int main(int, char** ) { Deferred<int> d; Promise<int> p; Resolver<int> r; p = d.promise(); r = d.resolver(); p.done([] (int a) { std::cout << "A = " << a << std::endl; }); r.resolve(42); return 0; }
StrPair loadContent(const StrPair& url) { const int MAX_BUF_SIZE = 1024*1000; const int READ_BUF_SIZE = 1024*16; auto&& host = url.first; auto&& path = url.second; JLOG("loading url: " << host << ", " << path); Resolver r; Resolver::EndPoints ends = r.resolve(host, 80); VERIFY(ends != Resolver::EndPoints(), "Cannot resolve hostname: " + host); Socket s; s.connect(*ends); Str req = "GET " + path + " HTTP/1.1" EOL "Host: " + host + EOL EOL; s.write(req); Str resp; Str buf; size_t header = std::string::npos; while (header == std::string::npos) { VERIFY(resp.size() < MAX_BUF_SIZE, "Header is too large"); buf.resize(READ_BUF_SIZE); s.partialRead(buf); VERIFY(!buf.empty(), "Empty buffer on partial read"); resp += buf; header = resp.find(EOL EOL); } Str head = resp.substr(0, header); header += 4; // add 2 EOLs static const regex eStatus("^http/1\\.[01] ([\\d]{3})", regex::icase); smatch whatStatus; bool result = regex_search(head, whatStatus, eStatus); VERIFY(result, "Invalid http status header"); Str status = whatStatus[1]; static const std::unordered_set<Str> allowedStatuses = {"200", "301", "302", "303"}; VERIFY(allowedStatuses.count(status), "Unexpected status: " + status); static const regex e("content-length: *(\\d+)", regex::icase); smatch what; result = regex_search(head, what, e); if (result) { int len = std::atoi(Str(what[1]).c_str()); VERIFY(len > 0 && len < MAX_BUF_SIZE, "Content length: invalid value"); buf.resize(len - (resp.size() - header)); s.read(buf); resp += buf; } else { static const regex et("transfer-encoding: *chunked", regex::icase); // read chunks result = regex_search(head, et); VERIFY(result, "Either content-length or transfer-encoding must be present in header"); while (resp.find(EOL EOL, resp.size() - 4) == std::string::npos) { VERIFY(resp.size() < MAX_BUF_SIZE, "Response is too large"); buf.resize(READ_BUF_SIZE); s.partialRead(buf); VERIFY(!buf.empty(), "Empty buffer on partial read"); resp += buf; } } Str body = resp.substr(header); return {host, body}; }