ソースを参照

http client redirect

ithewei 4 年 前
コミット
c51a9286d9
3 ファイル変更41 行追加4 行削除
  1. 4 2
      http/HttpMessage.h
  2. 30 2
      http/client/http_client.cpp
  3. 7 0
      http/httpdef.h

+ 4 - 2
http/HttpMessage.h

@@ -287,8 +287,9 @@ public:
     std::string         path;
     QueryParams         query_params;
     // client_addr
-    HNetAddr            client_addr; // for http server save client addr of request
-    int                 timeout; // for http client timeout
+    HNetAddr            client_addr;    // for http server save client addr of request
+    int                 timeout;        // for http client timeout
+    bool                redirect;       // for http_client redirect
 
     HttpRequest() : HttpMessage() {
         type = HTTP_REQUEST;
@@ -304,6 +305,7 @@ public:
         port = DEFAULT_HTTP_PORT;
         path = "/";
         timeout = 0;
+        redirect = true;
     }
 
     virtual void Reset() {

+ 30 - 2
http/client/http_client.cpp

@@ -7,6 +7,7 @@
 #endif
 
 #include "herr.h"
+#include "hlog.h"
 #include "hstring.h"
 #include "hsocket.h"
 #include "hssl.h"
@@ -115,6 +116,19 @@ const char* http_client_get_header(http_client_t* cli, const char* key) {
     return NULL;
 }
 
+static int http_client_redirect(HttpRequest* req, HttpResponse* resp) {
+    std::string location = resp->headers["Location"];
+    if (!location.empty()) {
+        hlogi("redirect %s => %s", req->url.c_str(), location.c_str());
+        req->url = location;
+        req->ParseUrl();
+        req->headers["Host"] = req->host;
+        resp->Reset();
+        return http_client_send(req, resp);
+    }
+    return 0;
+}
+
 int http_client_send(http_client_t* cli, HttpRequest* req, HttpResponse* resp) {
     if (!cli || !req || !resp) return ERR_NULL_POINTER;
 
@@ -134,7 +148,14 @@ int http_client_send(http_client_t* cli, HttpRequest* req, HttpResponse* resp) {
         }
     }
 
-    return __http_client_send(cli, req, resp);
+    int ret = __http_client_send(cli, req, resp);
+    if (ret != 0) return ret;
+
+    // redirect
+    if (req->redirect && HTTP_STATUS_IS_REDIRECT(resp->status_code)) {
+        return http_client_redirect(req, resp);
+    }
+    return 0;
 }
 
 int http_client_send(HttpRequest* req, HttpResponse* resp) {
@@ -145,7 +166,14 @@ int http_client_send(HttpRequest* req, HttpResponse* resp) {
     }
 
     http_client_t cli;
-    return __http_client_send(&cli, req, resp);
+    int ret = __http_client_send(&cli, req, resp);
+    if (ret != 0) return ret;
+
+    // redirect
+    if (req->redirect && HTTP_STATUS_IS_REDIRECT(resp->status_code)) {
+        return http_client_redirect(req, resp);
+    }
+    return ret;
 }
 
 #ifdef WITH_CURL

+ 7 - 0
http/httpdef.h

@@ -81,6 +81,13 @@ enum http_status {
     HTTP_CUSTOM_STATUS
 };
 
+#define HTTP_STATUS_IS_REDIRECT(status)             \
+    (status) == HTTP_STATUS_MOVED_PERMANENTLY   ||  \
+    (status) == HTTP_STATUS_FOUND               ||  \
+    (status) == HTTP_STATUS_SEE_OTHER           ||  \
+    (status) == HTTP_STATUS_TEMPORARY_REDIRECT  ||  \
+    (status) == HTTP_STATUS_PERMANENT_REDIRECT
+
 // http_mehtod
 // XX(num, name, string)
 #define HTTP_METHOD_MAP(XX)         \