ithewei 3 anni fa
parent
commit
dc3e4a7f50

+ 29 - 16
http/HttpMessage.h

@@ -46,7 +46,9 @@
 #include "httpdef.h"
 #include "http_content.h"
 
-struct HNetAddr {
+namespace hv {
+
+struct NetAddr {
     std::string     ip;
     int             port;
 
@@ -55,6 +57,8 @@ struct HNetAddr {
     }
 };
 
+}
+
 // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
 // Cookie: sessionid=1; domain=.example.com; path=/; max-age=86400; secure; httponly
 struct HV_EXPORT HttpCookie {
@@ -111,7 +115,7 @@ public:
     http_content_type   content_type;
 #ifndef WITHOUT_HTTP_CONTENT
     hv::Json            json;       // APPLICATION_JSON
-    MultiPart           form;       // MULTIPART_FORM_DATA
+    hv::MultiPart       form;       // MULTIPART_FORM_DATA
     hv::KeyValue        kv;         // X_WWW_FORM_URLENCODED
 
     // T=[bool, int, int64_t, float, double]
@@ -130,7 +134,7 @@ public:
             json[key] = value;
             break;
         case MULTIPART_FORM_DATA:
-            form[key] = FormData(value);
+            form[key] = hv::FormData(value);
             break;
         case X_WWW_FORM_URLENCODED:
             kv[key] = hv::to_string(value);
@@ -175,17 +179,17 @@ public:
     // Content-Type: multipart/form-data
     template<typename T>
     void SetFormData(const char* name, const T& t) {
-        form[name] = FormData(t);
+        form[name] = hv::FormData(t);
     }
     void SetFormFile(const char* name, const char* filepath) {
-        form[name] = FormData(NULL, filepath);
+        form[name] = hv::FormData(NULL, filepath);
     }
     int FormFile(const char* name, const char* filepath) {
         content_type = MULTIPART_FORM_DATA;
-        form[name] = FormData(NULL, filepath);
+        form[name] = hv::FormData(NULL, filepath);
         return 200;
     }
-    const MultiPart& GetForm() {
+    const hv::MultiPart& GetForm() {
         if (form.empty() && ContentType() == MULTIPART_FORM_DATA) {
             ParseBody();
         }
@@ -206,7 +210,7 @@ public:
             ParseBody();
             if (form.empty()) return HTTP_STATUS_BAD_REQUEST;
         }
-        const FormData& formdata = form[name];
+        const hv::FormData& formdata = form[name];
         if (formdata.content.empty()) {
             return HTTP_STATUS_BAD_REQUEST;
         }
@@ -376,7 +380,11 @@ public:
     }
 };
 
-#define DEFAULT_USER_AGENT "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
+#define DEFAULT_HTTP_USER_AGENT "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
+#define DEFAULT_HTTP_TIMEOUT            60 // s
+#define DEFAULT_HTTP_FAIL_RETRY_COUNT   1
+#define DEFAULT_HTTP_FAIL_RETRY_DELAY   1000 // ms
+
 class HV_EXPORT HttpRequest : public HttpMessage {
 public:
     http_method         method;
@@ -387,12 +395,15 @@ public:
     std::string         host;
     int                 port;
     std::string         path;
-    QueryParams         query_params;
+    hv::QueryParams     query_params;
     // client_addr
-    HNetAddr            client_addr;    // for http server save client addr of request
-    int                 timeout;        // for http client timeout
-    unsigned            redirect: 1;    // for http_client redirect
-    unsigned            proxy   : 1;    // for http_client proxy
+    hv::NetAddr         client_addr; // for http server save client addr of request
+    // for HttpClient
+    int                 timeout;
+    int                 retry_count; // just for AsyncHttpClient fail retry
+    int                 retry_delay; // just for AsyncHttpClient fail retry
+    unsigned            redirect: 1;
+    unsigned            proxy   : 1;
 
     HttpRequest() : HttpMessage() {
         type = HTTP_REQUEST;
@@ -400,14 +411,16 @@ public:
     }
 
     void Init() {
-        headers["User-Agent"] = DEFAULT_USER_AGENT;
+        headers["User-Agent"] = DEFAULT_HTTP_USER_AGENT;
         headers["Accept"] = "*/*";
         method = HTTP_GET;
         scheme = "http";
         host = "127.0.0.1";
         port = DEFAULT_HTTP_PORT;
         path = "/";
-        timeout = 0;
+        timeout = DEFAULT_HTTP_TIMEOUT;
+        retry_count = DEFAULT_HTTP_FAIL_RETRY_COUNT;
+        retry_delay = DEFAULT_HTTP_FAIL_RETRY_DELAY;
         redirect = 1;
         proxy = 0;
     }

+ 3 - 3
http/client/AsyncHttpClient.cpp

@@ -91,10 +91,10 @@ int AsyncHttpClient::doTask(const HttpClientTaskPtr& task) {
             iter->second.remove(channel->fd());
         }
         const HttpClientTaskPtr& task = ctx->task;
-        if (task && task->retry_cnt-- > 0) {
-            if (task->retry_delay) {
+        if (task && task->req && task->req->retry_count-- > 0) {
+            if (task->req->retry_delay > 0) {
                 // try again after delay
-                setTimeout(ctx->task->retry_delay, [this, task](TimerID timerID){
+                setTimeout(task->req->retry_delay, [this, task](TimerID timerID){
                     hlogi("retry %s %s", http_method_str(task->req->method), task->req->url.c_str());
                     sendInLoop(task);
                 });

+ 4 - 9
http/client/AsyncHttpClient.h

@@ -9,9 +9,6 @@
 #include "HttpMessage.h"
 #include "HttpParser.h"
 
-#define DEFAULT_FAIL_RETRY_COUNT  3
-#define DEFAULT_FAIL_RETRY_DELAY  1000  // ms
-
 // async => keepalive => connect_pool
 
 namespace hv {
@@ -55,10 +52,7 @@ private:
 struct HttpClientTask {
     HttpRequestPtr          req;
     HttpResponseCallback    cb;
-
-    uint64_t    start_time;
-    int         retry_cnt;
-    int         retry_delay;
+    uint64_t                start_time;
 };
 typedef std::shared_ptr<HttpClientTask> HttpClientTaskPtr;
 
@@ -118,8 +112,9 @@ public:
         task->req = req;
         task->cb = std::move(resp_cb);
         task->start_time = hloop_now_hrtime(loop_thread.hloop());
-        task->retry_delay = DEFAULT_FAIL_RETRY_DELAY;
-        task->retry_cnt = MIN(DEFAULT_FAIL_RETRY_COUNT, req->timeout * 1000 / task->retry_delay - 1);
+        if (req->retry_count > 0 && req->retry_delay > 0) {
+            req->retry_count = MIN(req->retry_count, req->timeout * 1000 / req->retry_delay - 1);
+        }
         return send(task);
     }
 

+ 1 - 1
http/client/axios.h

@@ -71,7 +71,7 @@ HV_INLINE Request newRequestFromJson(const json& jreq) {
     }
     // params
     if (jreq.contains("params")) {
-        req->query_params = jreq["params"].get<QueryParams>();
+        req->query_params = jreq["params"].get<hv::QueryParams>();
     }
     // headers
     if (jreq.contains("headers")) {

+ 1 - 1
http/client/http_client.h

@@ -27,7 +27,6 @@ int main(int argc, char* argv[]) {
 }
 */
 
-#define DEFAULT_HTTP_TIMEOUT    60 // s
 typedef struct http_client_s http_client_t;
 
 HV_EXPORT http_client_t* http_client_new(const char* host = NULL, int port = DEFAULT_HTTP_PORT, int https = 0);
@@ -35,6 +34,7 @@ HV_EXPORT int http_client_close(http_client_t* cli);
 HV_EXPORT int http_client_del(http_client_t* cli);
 HV_EXPORT const char* http_client_strerror(int errcode);
 
+// timeout: s
 HV_EXPORT int http_client_set_timeout(http_client_t* cli, int timeout);
 
 // SSL/TLS

+ 2 - 2
http/client/requests.h

@@ -103,8 +103,8 @@ HV_INLINE Response patch(const char* url, const http_body& body = NoBody, const
 }
 
 // delete is c++ keyword, we have to replace delete with Delete.
-HV_INLINE Response Delete(const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders) {
-    return request(HTTP_DELETE, url, body, headers);
+HV_INLINE Response Delete(const char* url, const http_headers& headers = DefaultHeaders) {
+    return request(HTTP_DELETE, url, NoBody, headers);
 }
 
 HV_INLINE int async(Request req, ResponseCallback resp_cb) {

+ 3 - 1
http/http_content.cpp

@@ -4,7 +4,7 @@
 
 #include <string.h>
 
-using namespace hv;
+BEGIN_NAMESPACE_HV
 
 std::string dump_query_params(const QueryParams& query_params) {
     std::string query_string;
@@ -248,3 +248,5 @@ int parse_json(const char* str, hv::Json& json, std::string& errmsg) {
     return (json.is_discarded() || json.is_null()) ? -1 : 0;
 }
 #endif
+
+END_NAMESPACE_HV

+ 11 - 7
http/http_content.h

@@ -4,13 +4,19 @@
 #include "hexport.h"
 #include "hstring.h"
 
+// NOTE: WITHOUT_HTTP_CONTENT
+// ndk-r10e no std::to_string and can't compile modern json.hpp
+#ifndef WITHOUT_HTTP_CONTENT
+#include "json.hpp" // https://github.com/nlohmann/json
+#endif
+
+BEGIN_NAMESPACE_HV
+
 // QueryParams
-typedef hv::KeyValue    QueryParams;
+using QueryParams = hv::KeyValue;
 HV_EXPORT std::string dump_query_params(const QueryParams& query_params);
 HV_EXPORT int         parse_query_params(const char* query_string, QueryParams& query_params);
 
-// NOTE: WITHOUT_HTTP_CONTENT
-// ndk-r10e no std::to_string and can't compile modern json.hpp
 #ifndef WITHOUT_HTTP_CONTENT
 
 /**************multipart/form-data*************************************
@@ -60,15 +66,13 @@ HV_EXPORT std::string dump_multipart(MultiPart& mp, const char* boundary = DEFAU
 HV_EXPORT int         parse_multipart(const std::string& str, MultiPart& mp, const char* boundary);
 
 // Json
-// https://github.com/nlohmann/json
-#include "json.hpp"
-namespace hv { // NOTE: Avoid conflict with jsoncpp
 using Json = nlohmann::json;
 // using Json = nlohmann::ordered_json;
-}
 
 HV_EXPORT std::string dump_json(const hv::Json& json, int indent = -1);
 HV_EXPORT int         parse_json(const char* str, hv::Json& json, std::string& errmsg);
 #endif
 
+END_NAMESPACE_HV
+
 #endif // HV_HTTP_CONTENT_H_

+ 2 - 2
http/server/HttpContext.h

@@ -44,7 +44,7 @@ struct HV_EXPORT HttpContext {
         return request->GetHeader(key, defvalue);
     }
 
-    const QueryParams& params() {
+    const hv::QueryParams& params() {
         return request->query_params;
     }
 
@@ -79,7 +79,7 @@ struct HV_EXPORT HttpContext {
     }
 
     // Content-Type: multipart/form-data
-    const MultiPart& form() {
+    const hv::MultiPart& form() {
         return request->GetForm();
     }
     std::string form(const char* name, const std::string& defvalue = hv::empty_string) {