| 98 | |
| 99 | |
| 100 | uint64_t HttpWriteCallback(uint8_t* data, uint64_t len, void* ctxt) |
| 101 | { |
| 102 | auto* request = reinterpret_cast<RequestContext*>(ctxt); |
| 103 | // copy can totally take pointers, pretty cool |
| 104 | copy(data, &data[len], back_inserter(request->response.body)); |
| 105 | |
| 106 | // Detect content length if it has not been found yet |
| 107 | if (request->downloadLength == 0) |
| 108 | { |
| 109 | const auto& headers = request->response.response.headers; |
| 110 | auto found = headers.find("Content-Length"); |
| 111 | if (found != headers.end()) |
| 112 | { |
| 113 | request->downloadLength = strtoll(found->second.c_str(), nullptr, 10); |
| 114 | request->response.body.reserve(request->downloadLength); |
| 115 | } |
| 116 | else |
| 117 | { |
| 118 | request->downloadLength = -1; |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | if (request->request.m_downloadProgress) |
| 123 | { |
| 124 | if (!request->request.m_downloadProgress(request->response.body.size(), request->downloadLength)) |
| 125 | { |
| 126 | // Signal error by returning non-len |
| 127 | request->cancelled = true; |
| 128 | return 0; |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | return len; |
| 133 | } |
| 134 | |
| 135 | |
| 136 | string UrlEncode(const string& str) |