@@ -949,6 +949,11 @@ class ClientImpl {
949949 Result Put (const std::string &path, const Params ¶ms);
950950 Result Put (const std::string &path, const Headers &headers,
951951 const Params ¶ms);
952+ Result Put (const std::string &path, const MultipartFormDataItems &items);
953+ Result Put (const std::string &path, const Headers &headers,
954+ const MultipartFormDataItems &items);
955+ Result Put (const std::string &path, const Headers &headers,
956+ const MultipartFormDataItems &items, const std::string &boundary);
952957
953958 Result Patch (const std::string &path);
954959 Result Patch (const std::string &path, const char *body, size_t content_length,
@@ -1304,6 +1309,11 @@ class Client {
13041309 Result Put (const std::string &path, const Params ¶ms);
13051310 Result Put (const std::string &path, const Headers &headers,
13061311 const Params ¶ms);
1312+ Result Put (const std::string &path, const MultipartFormDataItems &items);
1313+ Result Put (const std::string &path, const Headers &headers,
1314+ const MultipartFormDataItems &items);
1315+ Result Put (const std::string &path, const Headers &headers,
1316+ const MultipartFormDataItems &items, const std::string &boundary);
13071317 Result Patch (const std::string &path);
13081318 Result Patch (const std::string &path, const char *body, size_t content_length,
13091319 const std::string &content_type);
@@ -4064,6 +4074,46 @@ inline std::string make_multipart_data_boundary() {
40644074 return result;
40654075}
40664076
4077+ inline bool is_multipart_boundary_chars_valid (const std::string& boundary)
4078+ {
4079+ bool valid = true ;
4080+ for (size_t i = 0 ; i < boundary.size (); i++) {
4081+ char c = boundary[i];
4082+ if (!std::isalnum (c) && c != ' -' && c != ' _' ) {
4083+ valid = false ;
4084+ break ;
4085+ }
4086+ }
4087+ return valid;
4088+ }
4089+
4090+
4091+ inline std::string serialize_multipart_formdata (const MultipartFormDataItems& items, std::string& content_type, const std::string& boundary_str)
4092+ {
4093+ const std::string& boundary = boundary_str.empty () ? make_multipart_data_boundary () : boundary_str;
4094+
4095+ std::string body;
4096+
4097+ for (const auto &item : items) {
4098+ body += " --" + boundary + " \r\n " ;
4099+ body += " Content-Disposition: form-data; name=\" " + item.name + " \" " ;
4100+ if (!item.filename .empty ()) {
4101+ body += " ; filename=\" " + item.filename + " \" " ;
4102+ }
4103+ body += " \r\n " ;
4104+ if (!item.content_type .empty ()) {
4105+ body += " Content-Type: " + item.content_type + " \r\n " ;
4106+ }
4107+ body += " \r\n " ;
4108+ body += item.content + " \r\n " ;
4109+ }
4110+
4111+ body += " --" + boundary + " --\r\n " ;
4112+
4113+ content_type = " multipart/form-data; boundary=" + boundary;
4114+ return body;
4115+ }
4116+
40674117inline std::pair<size_t , size_t >
40684118get_range_offset_and_length (const Request &req, size_t content_length,
40694119 size_t index) {
@@ -6745,37 +6795,21 @@ inline Result ClientImpl::Post(const std::string &path,
67456795
67466796inline Result ClientImpl::Post (const std::string &path, const Headers &headers,
67476797 const MultipartFormDataItems &items) {
6748- return Post (path, headers, items, detail::make_multipart_data_boundary ());
6798+ std::string content_type;
6799+ const std::string& body = detail::serialize_multipart_formdata (items, content_type, std::string ());
6800+ return Post (path, headers, body, content_type.c_str ());
67496801}
6802+
67506803inline Result ClientImpl::Post (const std::string &path, const Headers &headers,
67516804 const MultipartFormDataItems &items,
6752- const std::string &boundary) {
6753- for (size_t i = 0 ; i < boundary.size (); i++) {
6754- char c = boundary[i];
6755- if (!std::isalnum (c) && c != ' -' && c != ' _' ) {
6805+ const std::string &boundary)
6806+ {
6807+ if (!detail::is_multipart_boundary_chars_valid (boundary)) {
67566808 return Result{nullptr , Error::UnsupportedMultipartBoundaryChars};
6757- }
6758- }
6759-
6760- std::string body;
6761-
6762- for (const auto &item : items) {
6763- body += " --" + boundary + " \r\n " ;
6764- body += " Content-Disposition: form-data; name=\" " + item.name + " \" " ;
6765- if (!item.filename .empty ()) {
6766- body += " ; filename=\" " + item.filename + " \" " ;
6767- }
6768- body += " \r\n " ;
6769- if (!item.content_type .empty ()) {
6770- body += " Content-Type: " + item.content_type + " \r\n " ;
6771- }
6772- body += " \r\n " ;
6773- body += item.content + " \r\n " ;
67746809 }
67756810
6776- body += " --" + boundary + " --\r\n " ;
6777-
6778- std::string content_type = " multipart/form-data; boundary=" + boundary;
6811+ std::string content_type;
6812+ const std::string& body = detail::serialize_multipart_formdata (items, content_type, boundary);
67796813 return Post (path, headers, body, content_type.c_str ());
67806814}
67816815
@@ -6848,6 +6882,31 @@ inline Result ClientImpl::Put(const std::string &path, const Headers &headers,
68486882 return Put (path, headers, query, " application/x-www-form-urlencoded" );
68496883}
68506884
6885+ inline Result ClientImpl::Put (const std::string &path, const MultipartFormDataItems &items)
6886+ {
6887+ return Put (path, Headers (), items);
6888+ }
6889+
6890+ inline Result ClientImpl::Put (const std::string &path, const Headers &headers,
6891+ const MultipartFormDataItems &items)
6892+ {
6893+ std::string content_type;
6894+ const std::string& body = detail::serialize_multipart_formdata (items, content_type, std::string ());
6895+ return Put (path, headers, body, content_type);
6896+ }
6897+
6898+ inline Result ClientImpl::Put (const std::string &path, const Headers &headers,
6899+ const MultipartFormDataItems &items,
6900+ const std::string &boundary)
6901+ {
6902+ if (!detail::is_multipart_boundary_chars_valid (boundary)) {
6903+ return Result{nullptr , Error::UnsupportedMultipartBoundaryChars};
6904+ }
6905+ std::string content_type;
6906+ const std::string& body = detail::serialize_multipart_formdata (items, content_type, boundary);
6907+ return Put (path, headers, body, content_type);
6908+ }
6909+
68516910inline Result ClientImpl::Patch (const std::string &path) {
68526911 return Patch (path, std::string (), std::string ());
68536912}
@@ -8099,6 +8158,20 @@ inline Result Client::Put(const std::string &path, const Headers &headers,
80998158 const Params ¶ms) {
81008159 return cli_->Put (path, headers, params);
81018160}
8161+ inline Result Client::Put (const std::string &path, const MultipartFormDataItems &items)
8162+ {
8163+ return cli_->Put (path, items);
8164+ }
8165+ inline Result Client::Put (const std::string &path, const Headers &headers,
8166+ const MultipartFormDataItems &items)
8167+ {
8168+ return cli_->Put (path, headers, items);
8169+ }
8170+ inline Result Client::Put (const std::string &path, const Headers &headers,
8171+ const MultipartFormDataItems &items, const std::string &boundary)
8172+ {
8173+ return cli_->Put (path, headers, items, boundary);
8174+ }
81028175inline Result Client::Patch (const std::string &path) {
81038176 return cli_->Patch (path);
81048177}
0 commit comments