| 79 | } |
| 80 | |
| 81 | multipart_content https_client::build_multipart(const std::string &json, const std::vector<std::string>& filenames, const std::vector<std::string>& contents, const std::vector<std::string>& mimetypes) { |
| 82 | |
| 83 | if (filenames.empty() && contents.empty()) { |
| 84 | /* If there are no files to upload, there is no need to build a multipart body */ |
| 85 | if (!json.empty()) { |
| 86 | return { json, "application/json" }; |
| 87 | } |
| 88 | return {json, ""}; |
| 89 | } |
| 90 | |
| 91 | /* Note: loss of upper 32 bits on this value is INTENTIONAL */ |
| 92 | uint32_t dummy1 = (uint32_t)time(nullptr) + (uint32_t)time(nullptr); |
| 93 | time_t dummy2 = time(nullptr) * time(nullptr); |
| 94 | const std::string two_cr("\r\n\r\n"); |
| 95 | const std::string boundary("-------------" + to_hex(dummy1) + to_hex(dummy2)); |
| 96 | const std::string part_start("--" + boundary + "\r\nContent-Disposition: form-data; "); |
| 97 | const std::string mime_type_start("\r\nContent-Type: "); |
| 98 | const std::string default_mime_type("application/octet-stream"); |
| 99 | |
| 100 | std::string content("--" + boundary); |
| 101 | |
| 102 | /* Special case, single file */ |
| 103 | content += "\r\nContent-Type: application/json\r\nContent-Disposition: form-data; name=\"payload_json\"" + two_cr; |
| 104 | content += json + "\r\n"; |
| 105 | if (filenames.size() == 1 && contents.size() == 1) { |
| 106 | content += part_start + "name=\"file\"; filename=\"" + filenames[0] + "\""; |
| 107 | content += mime_type_start + (mimetypes.empty() || mimetypes[0].empty() ? default_mime_type : mimetypes[0]) + two_cr; |
| 108 | content += contents[0]; |
| 109 | } else { |
| 110 | /* Multiple files */ |
| 111 | for (size_t i = 0; i < filenames.size(); ++i) { |
| 112 | content += part_start + "name=\"files[" + std::to_string(i) + "]\"; filename=\"" + filenames[i] + "\""; |
| 113 | content += "\r\nContent-Type: " + (mimetypes.size() <= i || mimetypes[i].empty() ? default_mime_type : mimetypes[i]) + two_cr; |
| 114 | content += contents[i]; |
| 115 | content += "\r\n"; |
| 116 | } |
| 117 | } |
| 118 | content += "\r\n--" + boundary + "--"; |
| 119 | return { content, "multipart/form-data; boundary=" + boundary }; |
| 120 | } |
| 121 | |
| 122 | const std::string https_client::get_header(std::string header_name) const { |
| 123 | std::transform(header_name.begin(), header_name.end(), header_name.begin(), [](unsigned char c){ |