Extract HTTP headers via temporary file with -D switch. HTTP status code is extracted from curl output (-w switches). Redirects are handled recursively. TODO(AlexZ): avoid infinite redirects loop.
| 182 | // HTTP status code is extracted from curl output (-w switches). |
| 183 | // Redirects are handled recursively. TODO(AlexZ): avoid infinite redirects loop. |
| 184 | bool HttpClient::RunHttpRequest() |
| 185 | { |
| 186 | ScopedRemoveFile headers_deleter(GetTmpFileName()); |
| 187 | ScopedRemoveFile body_deleter; |
| 188 | ScopedRemoveFile received_file_deleter; |
| 189 | |
| 190 | std::string cmd = "curl -s -w \"%{http_code}\" -D \"" + headers_deleter.m_fileName + "\" "; |
| 191 | // From curl manual: |
| 192 | // This option [-X] only changes the actual word used in the HTTP request, it does not alter |
| 193 | // the way curl behaves. So for example if you want to make a proper |
| 194 | // HEAD request, using -X HEAD will not suffice. You need to use the -I, --head option. |
| 195 | if (m_httpMethod == "HEAD") |
| 196 | cmd += "-I "; |
| 197 | else |
| 198 | cmd += "-X " + m_httpMethod + " "; |
| 199 | |
| 200 | for (auto const & header : m_headers) |
| 201 | cmd += "-H \"" + header.first + ": " + header.second + "\" "; |
| 202 | |
| 203 | if (!m_cookies.empty()) |
| 204 | cmd += "-b \"" + m_cookies + "\" "; |
| 205 | |
| 206 | cmd += "-m \"" + strings::to_string(m_timeoutSec) + "\" "; |
| 207 | |
| 208 | if (!m_bodyData.empty()) |
| 209 | { |
| 210 | body_deleter.m_fileName = GetTmpFileName(); |
| 211 | // POST body through tmp file to avoid breaking command line. |
| 212 | if (!WriteToFile(body_deleter.m_fileName, m_bodyData)) |
| 213 | return false; |
| 214 | |
| 215 | // TODO(AlexZ): Correctly clean up this internal var to avoid client confusion. |
| 216 | m_inputFile = body_deleter.m_fileName; |
| 217 | } |
| 218 | // Content-Length is added automatically by curl. |
| 219 | if (!m_inputFile.empty()) |
| 220 | cmd += "--data-binary \"@" + m_inputFile + "\" "; |
| 221 | |
| 222 | // Use temporary file to receive data from server. |
| 223 | // If user has specified file name to save data, it is not temporary and is not deleted automatically. |
| 224 | std::string rfile = m_outputFile; |
| 225 | if (rfile.empty()) |
| 226 | { |
| 227 | rfile = GetTmpFileName(); |
| 228 | received_file_deleter.m_fileName = rfile; |
| 229 | } |
| 230 | |
| 231 | cmd += "-o " + rfile + strings::to_string(" ") + "\"" + m_urlRequested + "\""; |
| 232 | |
| 233 | LOG(LDEBUG, ("Executing", cmd)); |
| 234 | |
| 235 | try |
| 236 | { |
| 237 | m_errorCode = stoi(RunCurl(cmd)); |
| 238 | } |
| 239 | catch (RootException const & ex) |
| 240 | { |
| 241 | LOG(LERROR, (ex.Msg())); |
nothing calls this directly
no test coverage detected