Browse Source

Fixed URL encoding problem when sending a request to proxy

yhirose 6 years ago
parent
commit
f2476f21fc
1 changed files with 18 additions and 6 deletions
  1. 18 6
      httplib.h

+ 18 - 6
httplib.h

@@ -766,7 +766,7 @@ protected:
 private:
 private:
   socket_t create_client_socket() const;
   socket_t create_client_socket() const;
   bool read_response_line(Stream &strm, Response &res);
   bool read_response_line(Stream &strm, Response &res);
-  void write_request(Stream &strm, const Request &req, bool last_connection);
+  bool write_request(Stream &strm, const Request &req, bool last_connection);
   bool redirect(const Request &req, Response &res);
   bool redirect(const Request &req, Response &res);
 
 
   std::shared_ptr<Response> send_with_content_provider(
   std::shared_ptr<Response> send_with_content_provider(
@@ -3490,8 +3490,6 @@ inline bool Client::redirect(const Request &req, Response &res) {
   std::regex re(
   std::regex re(
       R"(^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*(?:\?[^#]*)?)(?:#.*)?)");
       R"(^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*(?:\?[^#]*)?)(?:#.*)?)");
 
 
-  auto scheme = is_ssl() ? "https" : "http";
-
   std::smatch m;
   std::smatch m;
   if (regex_match(location, m, re)) {
   if (regex_match(location, m, re)) {
     auto next_scheme = m[1].str();
     auto next_scheme = m[1].str();
@@ -3500,6 +3498,8 @@ inline bool Client::redirect(const Request &req, Response &res) {
     if (next_host.empty()) { next_host = host_; }
     if (next_host.empty()) { next_host = host_; }
     if (next_path.empty()) { next_path = "/"; }
     if (next_path.empty()) { next_path = "/"; }
 
 
+    auto scheme = is_ssl() ? "https" : "http";
+
     if (next_scheme == scheme && next_host == host_) {
     if (next_scheme == scheme && next_host == host_) {
       return detail::redirect(*this, req, res, next_path);
       return detail::redirect(*this, req, res, next_path);
     } else {
     } else {
@@ -3521,12 +3521,20 @@ inline bool Client::redirect(const Request &req, Response &res) {
   return false;
   return false;
 }
 }
 
 
-inline void Client::write_request(Stream &strm, const Request &req,
+inline bool Client::write_request(Stream &strm, const Request &req,
                                   bool last_connection) {
                                   bool last_connection) {
   BufferStream bstrm;
   BufferStream bstrm;
 
 
   // Request line
   // Request line
-  auto path = detail::encode_url(req.path);
+  static std::regex re(
+      R"(^([^:/?#]+://[^/?#]*)?([^?#]*(?:\?[^#]*)?(?:#.*)?))");
+
+  std::smatch m;
+  if (!regex_match(req.path, m, re)) {
+    return false;
+  }
+
+  auto path = m[1].str() + detail::encode_url(m[2].str());
 
 
   bstrm.write_format("%s %s HTTP/1.1\r\n", req.method.c_str(), path.c_str());
   bstrm.write_format("%s %s HTTP/1.1\r\n", req.method.c_str(), path.c_str());
 
 
@@ -3596,6 +3604,8 @@ inline void Client::write_request(Stream &strm, const Request &req,
   } else {
   } else {
     strm.write(req.body);
     strm.write(req.body);
   }
   }
+
+  return true;
 }
 }
 
 
 inline std::shared_ptr<Response> Client::send_with_content_provider(
 inline std::shared_ptr<Response> Client::send_with_content_provider(
@@ -3646,7 +3656,9 @@ inline bool Client::process_request(Stream &strm, const Request &req,
                                     Response &res, bool last_connection,
                                     Response &res, bool last_connection,
                                     bool &connection_close) {
                                     bool &connection_close) {
   // Send request
   // Send request
-  write_request(strm, req, last_connection);
+  if (!write_request(strm, req, last_connection)) {
+    return false;
+  }
 
 
   // Receive response and headers
   // Receive response and headers
   if (!read_response_line(strm, res) ||
   if (!read_response_line(strm, res) ||