Browse Source

Allow client to specify boundary and use more entropy by default (#691) (#694)

lightvector 5 years ago
parent
commit
d37bc0fb4d
1 changed files with 31 additions and 3 deletions
  1. 31 3
      httplib.h

+ 31 - 3
httplib.h

@@ -704,7 +704,8 @@ enum Error {
   Canceled,
   Canceled,
   SSLConnection,
   SSLConnection,
   SSLLoadingCerts,
   SSLLoadingCerts,
-  SSLServerVerification
+  SSLServerVerification,
+  UnsupportedMultipartBoundaryChars
 };
 };
 
 
 class Result {
 class Result {
@@ -777,6 +778,9 @@ public:
   Result Post(const char *path, const MultipartFormDataItems &items);
   Result Post(const char *path, const MultipartFormDataItems &items);
   Result Post(const char *path, const Headers &headers,
   Result Post(const char *path, const Headers &headers,
               const MultipartFormDataItems &items);
               const MultipartFormDataItems &items);
+  Result Post(const char *path, const Headers &headers,
+              const MultipartFormDataItems &items,
+              const std::string& boundary);
 
 
   Result Put(const char *path);
   Result Put(const char *path);
   Result Put(const char *path, const std::string &body,
   Result Put(const char *path, const std::string &body,
@@ -1012,6 +1016,9 @@ public:
   Result Post(const char *path, const MultipartFormDataItems &items);
   Result Post(const char *path, const MultipartFormDataItems &items);
   Result Post(const char *path, const Headers &headers,
   Result Post(const char *path, const Headers &headers,
               const MultipartFormDataItems &items);
               const MultipartFormDataItems &items);
+  Result Post(const char *path, const Headers &headers,
+              const MultipartFormDataItems &items,
+              const std::string& boundary);
   Result Put(const char *path);
   Result Put(const char *path);
   Result Put(const char *path, const std::string &body,
   Result Put(const char *path, const std::string &body,
              const char *content_type);
              const char *content_type);
@@ -3090,8 +3097,13 @@ inline std::string make_multipart_data_boundary() {
   static const char data[] =
   static const char data[] =
       "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
       "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
 
+  // std::random_device might actually be deterministic on some
+  // platforms, but due to lack of support in the c++ standard library,
+  // doing better requires either some ugly hacks or breaking portability.
   std::random_device seed_gen;
   std::random_device seed_gen;
-  std::mt19937 engine(seed_gen());
+  // Request 128 bits of entropy for initialization
+  std::seed_seq seed_sequence{seed_gen(), seed_gen(), seed_gen(), seed_gen()};
+  std::mt19937 engine(seed_sequence);
 
 
   std::string result = "--cpp-httplib-multipart-data-";
   std::string result = "--cpp-httplib-multipart-data-";
 
 
@@ -5273,7 +5285,18 @@ inline Result ClientImpl::Post(const char *path,
 
 
 inline Result ClientImpl::Post(const char *path, const Headers &headers,
 inline Result ClientImpl::Post(const char *path, const Headers &headers,
                                const MultipartFormDataItems &items) {
                                const MultipartFormDataItems &items) {
-  auto boundary = detail::make_multipart_data_boundary();
+  return Post(path, headers, items, detail::make_multipart_data_boundary());
+}
+inline Result ClientImpl::Post(const char *path, const Headers &headers,
+                               const MultipartFormDataItems &items,
+                               const std::string& boundary) {
+  for (size_t i = 0; i < boundary.size(); i++) {
+    char c = boundary[i];
+    if (!std::isalnum(c) && c != '-' && c != '_') {
+      error_ = Error::UnsupportedMultipartBoundaryChars;
+      return Result{nullptr, error_};
+    }
+  }
 
 
   std::string body;
   std::string body;
 
 
@@ -6306,6 +6329,11 @@ inline Result Client::Post(const char *path, const Headers &headers,
                            const MultipartFormDataItems &items) {
                            const MultipartFormDataItems &items) {
   return cli_->Post(path, headers, items);
   return cli_->Post(path, headers, items);
 }
 }
+inline Result Client::Post(const char *path, const Headers &headers,
+                           const MultipartFormDataItems &items,
+                           const std::string& boundary) {
+  return cli_->Post(path, headers, items, boundary);
+}
 inline Result Client::Put(const char *path) { return cli_->Put(path); }
 inline Result Client::Put(const char *path) { return cli_->Put(path); }
 inline Result Client::Put(const char *path, const std::string &body,
 inline Result Client::Put(const char *path, const std::string &body,
                           const char *content_type) {
                           const char *content_type) {