yhirose 5 years ago
parent
commit
58909f5917
2 changed files with 16 additions and 11 deletions
  1. 15 10
      httplib.h
  2. 1 1
      test/test.cc

+ 15 - 10
httplib.h

@@ -277,6 +277,7 @@ struct Request {
 
 
   // for client
   // for client
   size_t redirect_count = CPPHTTPLIB_REDIRECT_MAX_COUNT;
   size_t redirect_count = CPPHTTPLIB_REDIRECT_MAX_COUNT;
+  size_t authorization_count = 1;
   ResponseHandler response_handler;
   ResponseHandler response_handler;
   ContentReceiver content_receiver;
   ContentReceiver content_receiver;
   Progress progress;
   Progress progress;
@@ -857,9 +858,9 @@ inline void Post(std::vector<Request> &requests, const char *path,
   Post(requests, path, Headers(), body, content_type);
   Post(requests, path, Headers(), body, content_type);
 }
 }
 
 
-inline void Post(std::vector<Request> &requests,
-     const char *path, size_t content_length,
-    ContentProvider content_provider, const char *content_type) {
+inline void Post(std::vector<Request> &requests, const char *path,
+                 size_t content_length, ContentProvider content_provider,
+                 const char *content_type) {
   Request req;
   Request req;
   req.method = "POST";
   req.method = "POST";
   req.headers = Headers();
   req.headers = Headers();
@@ -2735,10 +2736,11 @@ inline std::pair<std::string, std::string> make_digest_authentication_header(
                  ":" + qop + ":" + H(A2));
                  ":" + qop + ":" + H(A2));
   }
   }
 
 
-  auto field = "Digest username=\"" + username + "\", realm=\"" + auth.at("realm") +
-               "\", nonce=\"" + auth.at("nonce") + "\", uri=\"" + req.path +
-               "\", algorithm=" + algo + ", qop=" + qop + ", nc=\"" + nc +
-               "\", cnonce=\"" + cnonce + "\", response=\"" + response + "\"";
+  auto field = "Digest username=\"" + username + "\", realm=\"" +
+               auth.at("realm") + "\", nonce=\"" + auth.at("nonce") +
+               "\", uri=\"" + req.path + "\", algorithm=" + algo +
+               ", qop=" + qop + ", nc=\"" + nc + "\", cnonce=\"" + cnonce +
+               "\", response=\"" + response + "\"";
 
 
   auto key = is_proxy ? "Proxy-Authorization" : "Authorization";
   auto key = is_proxy ? "Proxy-Authorization" : "Authorization";
   return std::make_pair(key, field);
   return std::make_pair(key, field);
@@ -3891,7 +3893,8 @@ inline bool Client::handle_request(Stream &strm, const Request &req,
   }
   }
 
 
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
-  if (res.status == 401 || res.status == 407) {
+  if ((res.status == 401 || res.status == 407) &&
+      req.authorization_count == 1) {
     auto is_proxy = res.status == 407;
     auto is_proxy = res.status == 407;
     const auto &username =
     const auto &username =
         is_proxy ? proxy_digest_auth_username_ : digest_auth_username_;
         is_proxy ? proxy_digest_auth_username_ : digest_auth_username_;
@@ -3902,10 +3905,12 @@ inline bool Client::handle_request(Stream &strm, const Request &req,
       std::map<std::string, std::string> auth;
       std::map<std::string, std::string> auth;
       if (parse_www_authenticate(res, auth, is_proxy)) {
       if (parse_www_authenticate(res, auth, is_proxy)) {
         Request new_req = req;
         Request new_req = req;
-        auto key = is_proxy ? "Proxy-Authorization" : "WWW-Authorization";
+        new_req.authorization_count += 1;
+        auto key = is_proxy ? "Proxy-Authorization" : "Authorization";
         new_req.headers.erase(key);
         new_req.headers.erase(key);
         new_req.headers.insert(make_digest_authentication_header(
         new_req.headers.insert(make_digest_authentication_header(
-            req, auth, 1, random_string(10), username, password, is_proxy));
+            req, auth, new_req.authorization_count, random_string(10), username,
+            password, is_proxy));
 
 
         Response new_res;
         Response new_res;
 
 

+ 1 - 1
test/test.cc

@@ -563,7 +563,7 @@ TEST(DigestAuthTest, FromHTTPWatch) {
     for (auto path : paths) {
     for (auto path : paths) {
       auto res = cli.Get(path.c_str());
       auto res = cli.Get(path.c_str());
       ASSERT_TRUE(res != nullptr);
       ASSERT_TRUE(res != nullptr);
-      EXPECT_EQ(400, res->status);
+      EXPECT_EQ(401, res->status);
     }
     }
 
 
     // NOTE: Until httpbin.org fixes issue #46, the following test is commented
     // NOTE: Until httpbin.org fixes issue #46, the following test is commented