ithewei 6 gadi atpakaļ
vecāks
revīzija
d145dd5ca2

+ 7 - 6
base/hdef.h

@@ -5,11 +5,6 @@
 
 typedef float               float32;
 typedef double              float64;
-
-typedef unsigned char       BYTE;
-typedef unsigned short      WORD;
-typedef int                 BOOL;
-
 typedef void*               handle;
 
 typedef union {
@@ -29,7 +24,7 @@ typedef void (*procedure_t)(void* userdata);
     typedef int pid_t;
     typedef int gid_t;
     typedef int uid_t;
-    #define strcasecmp stricmp
+    #define strcasecmp  stricmp
     #define strncasecmp strnicmp
 #else
     #include <strings.h>
@@ -202,6 +197,12 @@ typedef void (*procedure_t)(void* userdata);
 #endif
 
 #ifndef OS_WIN
+typedef unsigned char       BYTE;
+typedef unsigned short      WORD;
+
+typedef int                 BOOL;
+typedef void*               HANDLE;
+
 #ifndef MAKEWORD
 #define MAKEWORD(h, l)  ( (((WORD)h) << 8) | (l & 0xff) )
 #endif

+ 87 - 0
base/hurl.cpp

@@ -0,0 +1,87 @@
+#include "hurl.h"
+
+#include "hdef.h"
+
+/*
+static bool Curl_isunreserved(unsigned char in)
+{
+    switch(in) {
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+    case 'a': case 'b': case 'c': case 'd': case 'e':
+    case 'f': case 'g': case 'h': case 'i': case 'j':
+    case 'k': case 'l': case 'm': case 'n': case 'o':
+    case 'p': case 'q': case 'r': case 's': case 't':
+    case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
+    case 'A': case 'B': case 'C': case 'D': case 'E':
+    case 'F': case 'G': case 'H': case 'I': case 'J':
+    case 'K': case 'L': case 'M': case 'N': case 'O':
+    case 'P': case 'Q': case 'R': case 'S': case 'T':
+    case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
+    case '-': case '.': case '_': case '~':
+      return TRUE;
+    default:
+      break;
+    }
+    return FLASE;
+}
+*/
+
+static inline bool is_unambiguous(char c) {
+    return IS_ALPHANUM(c) ||
+           c == '-' ||
+           c == '_' ||
+           c == '.' ||
+           c == '~';
+}
+
+static char hex2i(char hex) {
+    if (hex >= '0' && hex <= '9') {
+        return hex - '0';
+    }
+    switch (hex) {
+        case 'A': case 'a': return 10;
+        case 'B': case 'b': return 11;
+        case 'C': case 'c': return 12;
+        case 'D': case 'd': return 13;
+        case 'E': case 'e': return 14;
+        case 'F': case 'f': return 15;
+        default: break;
+    }
+    return 0;
+}
+
+std::string url_escape(const char* istr) {
+    std::string ostr;
+    const char* p = istr;
+    char szHex[4] = {0};
+    while (*p != '\0') {
+        if (is_unambiguous(*p)) {
+            ostr += *p;
+        }
+        else {
+            sprintf(szHex, "%%%02X", *p);
+            ostr += szHex;
+        }
+        ++p;
+    }
+    return ostr;
+}
+
+std::string url_unescape(const char* istr) {
+    std::string ostr;
+    const char* p = istr;
+    while (*p != '\0') {
+        if (*p == '%' &&
+            IS_HEX(p[1]) &&
+            IS_HEX(p[2])) {
+            ostr += (hex2i(p[1]) << 4 | hex2i(p[2]));
+            p += 3;
+        }
+        else {
+            ostr += *p;
+            ++p;
+        }
+    }
+    return ostr;
+}

+ 9 - 0
base/hurl.h

@@ -0,0 +1,9 @@
+#ifndef HW_URL_H_
+#define HW_URL_H_
+
+#include <string>
+
+std::string url_escape(const char* istr);
+std::string url_unescape(const char* istr);
+
+#endif // HW_URL_H_

+ 4 - 4
http/Http1Session.cpp

@@ -38,7 +38,7 @@ int on_url(http_parser* parser, const char *at, size_t length) {
     printd("on_url:%.*s\n", (int)length, at);
     Http1Session* hss = (Http1Session*)parser->data;
     hss->state = HP_URL;
-    hss->url.insert(hss->url.size(), at, length);
+    hss->url.append(at, length);
     return 0;
 }
 
@@ -54,7 +54,7 @@ int on_header_field(http_parser* parser, const char *at, size_t length) {
     Http1Session* hss = (Http1Session*)parser->data;
     hss->handle_header();
     hss->state = HP_HEADER_FIELD;
-    hss->header_field.insert(hss->header_field.size(), at, length);
+    hss->header_field.append(at, length);
     return 0;
 }
 
@@ -62,7 +62,7 @@ int on_header_value(http_parser* parser, const char *at, size_t length) {
     printd("on_header_value:%.*s""\n", (int)length, at);
     Http1Session* hss = (Http1Session*)parser->data;
     hss->state = HP_HEADER_VALUE;
-    hss->header_value.insert(hss->header_value.size(), at, length);
+    hss->header_value.append(at, length);
     return 0;
 }
 
@@ -70,7 +70,7 @@ int on_body(http_parser* parser, const char *at, size_t length) {
     //printd("on_body:%.*s""\n", (int)length, at);
     Http1Session* hss = (Http1Session*)parser->data;
     hss->state = HP_BODY;
-    hss->parsed->body.insert(hss->parsed->body.size(), at, length);
+    hss->parsed->body.append(at, length);
     return 0;
 }
 

+ 2 - 2
http/Http1Session.h

@@ -21,8 +21,8 @@ public:
     static http_parser_settings*    cbs;
     http_parser                     parser;
     http_parser_state               state;
-    HttpPayload*                    submited;
-    HttpPayload*                    parsed;
+    HttpMessage*                    submited;
+    HttpMessage*                    parsed;
     // tmp
     std::string url;          // for on_url
     std::string header_field; // for on_header_field

+ 1 - 1
http/Http2Session.cpp

@@ -366,7 +366,7 @@ int on_data_chunk_recv_callback(nghttp2_session *session,
             len -= GRPC_MESSAGE_HDLEN;
         }
     }
-    hss->parsed->body.insert(hss->parsed->body.size(), (const char*)data, len);
+    hss->parsed->body.append((const char*)data, len);
     return 0;
 }
 

+ 2 - 2
http/Http2Session.h

@@ -29,8 +29,8 @@ public:
     static nghttp2_session_callbacks* cbs;
     nghttp2_session*                session;
     http2_session_state             state;
-    HttpPayload*                    submited;
-    HttpPayload*                    parsed;
+    HttpMessage*                    submited;
+    HttpMessage*                    parsed;
     int error;
     int stream_id;
     int stream_closed;

+ 7 - 7
http/HttpPayload.cpp → http/HttpMessage.cpp

@@ -1,10 +1,10 @@
-#include "HttpPayload.h"
+#include "HttpMessage.h"
 
 #include <string.h>
 
 #include "http_parser.h" // for http_parser_url
 
-void HttpPayload::FillContentType() {
+void HttpMessage::FillContentType() {
     auto iter = headers.find("Content-Type");
     if (iter != headers.end()) {
         content_type = http_content_type_enum(iter->second.c_str());
@@ -49,7 +49,7 @@ append:
     return;
 }
 
-void HttpPayload::FillContentLength() {
+void HttpMessage::FillContentLength() {
     auto iter = headers.find("Content-Length");
     if (iter == headers.end()) {
         if (content_length == 0) {
@@ -62,7 +62,7 @@ void HttpPayload::FillContentLength() {
     }
 }
 
-void HttpPayload::DumpHeaders(std::string& str) {
+void HttpMessage::DumpHeaders(std::string& str) {
     FillContentType();
     FillContentLength();
     for (auto& header: headers) {
@@ -77,7 +77,7 @@ void HttpPayload::DumpHeaders(std::string& str) {
     }
 }
 
-void HttpPayload::DumpBody() {
+void HttpMessage::DumpBody() {
     if (body.size() != 0) {
         return;
     }
@@ -111,7 +111,7 @@ void HttpPayload::DumpBody() {
 #endif
 }
 
-int HttpPayload::ParseBody() {
+int HttpMessage::ParseBody() {
     if (body.size() == 0) {
         return -1;
     }
@@ -143,7 +143,7 @@ int HttpPayload::ParseBody() {
     return 0;
 }
 
-std::string HttpPayload::Dump(bool is_dump_headers, bool is_dump_body) {
+std::string HttpMessage::Dump(bool is_dump_headers, bool is_dump_body) {
     std::string str;
     if (is_dump_headers) {
         DumpHeaders(str);

+ 13 - 13
http/HttpPayload.h → http/HttpMessage.h

@@ -1,5 +1,5 @@
-#ifndef HTTP_PAYLOAD_H_
-#define HTTP_PAYLOAD_H_
+#ifndef HTTP_MESSAGE_H_
+#define HTTP_MESSAGE_H_
 
 #include <string>
 #include <map>
@@ -11,7 +11,7 @@
 typedef std::map<std::string, std::string, StringCaseLess>  http_headers;
 typedef std::string                                         http_body;
 
-class HttpPayload {
+class HttpMessage {
 public:
     int                 type;
     unsigned short      http_major;
@@ -26,16 +26,16 @@ public:
     http_content_type   content_type;
 #ifndef WITHOUT_HTTP_CONTENT
     Json                json;       // APPLICATION_JSON
-    MultiPart           mp;         // FORM_DATA
+    MultiPart           mp;         // MULTIPART_FORM_DATA
     KeyValue            kv;         // X_WWW_FORM_URLENCODED
 #endif
 
-    HttpPayload() {
+    HttpMessage() {
         type = HTTP_BOTH;
         Init();
     }
 
-    virtual ~HttpPayload() {}
+    virtual ~HttpMessage() {}
 
     void Init() {
         http_major = 1;
@@ -94,7 +94,7 @@ 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"
-class HttpRequest : public HttpPayload {
+class HttpRequest : public HttpMessage {
 public:
     http_method         method;
     // scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]
@@ -106,7 +106,7 @@ public:
     std::string         path;
     QueryParams         query_params;
 
-    HttpRequest() : HttpPayload() {
+    HttpRequest() : HttpMessage() {
         type = HTTP_REQUEST;
         Init();
     }
@@ -122,7 +122,7 @@ public:
     }
 
     virtual void Reset() {
-        HttpPayload::Reset();
+        HttpMessage::Reset();
         Init();
         url.clear();
         query_params.clear();
@@ -136,11 +136,11 @@ public:
     void ParseUrl();
 };
 
-class HttpResponse : public HttpPayload {
+class HttpResponse : public HttpMessage {
 public:
     http_status         status_code;
 
-    HttpResponse() : HttpPayload() {
+    HttpResponse() : HttpMessage() {
         type = HTTP_RESPONSE;
         Init();
     }
@@ -150,11 +150,11 @@ public:
     }
 
     virtual void Reset() {
-        HttpPayload::Reset();
+        HttpMessage::Reset();
         Init();
     }
 
     virtual std::string Dump(bool is_dump_headers = true, bool is_dump_body = false);
 };
 
-#endif // HTTP_PAYLOAD_H_
+#endif // HTTP_MESSAGE_H_

+ 1 - 1
http/HttpSession.h

@@ -1,7 +1,7 @@
 #ifndef HTTP_SESSION_H_
 #define HTTP_SESSION_H_
 
-#include "HttpPayload.h"
+#include "HttpMessage.h"
 
 class HttpSession {
 public:

+ 14 - 10
http/client/http_client.cpp

@@ -1,9 +1,9 @@
 #include "http_client.h"
 
-#include "hstring.h"
-
 #define MAX_CONNECT_TIMEOUT 3000 // ms
 
+#include "hstring.h" // import asprintf,trim
+
 #ifdef WITH_CURL
 #include "curl/curl.h"
 #else
@@ -150,9 +150,9 @@ static size_t s_header_cb(char* buf, size_t size, size_t cnt, void* userdata) {
 
     HttpResponse* res = (HttpResponse*)userdata;
 
-    string str(buf);
-    string::size_type pos = str.find_first_of(':');
-    if (pos == string::npos) {
+    std::string str(buf);
+    std::string::size_type pos = str.find_first_of(':');
+    if (pos == std::string::npos) {
         if (strncmp(buf, "HTTP/", 5) == 0) {
             // status line
             //hlogd("%s", buf);
@@ -173,8 +173,8 @@ static size_t s_header_cb(char* buf, size_t size, size_t cnt, void* userdata) {
     }
     else {
         // headers
-        string key = trim(str.substr(0, pos));
-        string value = trim(str.substr(pos+1));
+        std::string key = trim(str.substr(0, pos));
+        std::string value = trim(str.substr(pos+1));
         res->headers[key] = value;
     }
     return size*cnt;
@@ -224,7 +224,7 @@ int __http_client_send(http_client_t* cli, HttpRequest* req, HttpResponse* res)
     req->FillContentType();
     struct curl_slist *headers = NULL;
     for (auto& pair : req->headers) {
-        string header = pair.first;
+        std::string header = pair.first;
         header += ": ";
         header += pair.second;
         headers = curl_slist_append(headers, header.c_str());
@@ -232,10 +232,11 @@ int __http_client_send(http_client_t* cli, HttpRequest* req, HttpResponse* res)
     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
 
     // body
-    struct curl_httppost* httppost = NULL;
-    struct curl_httppost* lastpost = NULL;
+    //struct curl_httppost* httppost = NULL;
+    //struct curl_httppost* lastpost = NULL;
     if (req->body.size() == 0) {
         req->DumpBody();
+        /*
         if (req->body.size() == 0 &&
             req->content_type == MULTIPART_FORM_DATA) {
             for (auto& pair : req->mp) {
@@ -256,6 +257,7 @@ int __http_client_send(http_client_t* cli, HttpRequest* req, HttpResponse* res)
                 curl_easy_setopt(curl, CURLOPT_HTTPPOST, httppost);
             }
         }
+        */
     }
     if (req->body.size() != 0) {
         curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req->body.c_str());
@@ -292,9 +294,11 @@ int __http_client_send(http_client_t* cli, HttpRequest* req, HttpResponse* res)
     if (headers) {
         curl_slist_free_all(headers);
     }
+    /*
     if (httppost) {
         curl_formfree(httppost);
     }
+    */
 
     return ret;
 }

+ 1 - 1
http/client/http_client.h

@@ -1,7 +1,7 @@
 #ifndef HTTP_CLIENT_H_
 #define HTTP_CLIENT_H_
 
-#include "HttpPayload.h"
+#include "HttpMessage.h"
 
 /*
 #include <stdio.h>

+ 30 - 112
http/http_content.cpp

@@ -1,97 +1,6 @@
 #include "http_content.h"
 
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "hdef.h"
-#include "hstring.h"
-
-#include "httpdef.h" // for http_content_type_str_by_suffix
-
-static char hex2i(char hex) {
-    if (hex >= '0' && hex <= '9') {
-        return hex - '0';
-    }
-    switch (hex) {
-        case 'A': case 'a': return 10;
-        case 'B': case 'b': return 11;
-        case 'C': case 'c': return 12;
-        case 'D': case 'd': return 13;
-        case 'E': case 'e': return 14;
-        case 'F': case 'f': return 15;
-        default: break;
-    }
-    return 0;
-}
-
-/*
-bool Curl_isunreserved(unsigned char in)
-{
-    switch(in) {
-    case '0': case '1': case '2': case '3': case '4':
-    case '5': case '6': case '7': case '8': case '9':
-    case 'a': case 'b': case 'c': case 'd': case 'e':
-    case 'f': case 'g': case 'h': case 'i': case 'j':
-    case 'k': case 'l': case 'm': case 'n': case 'o':
-    case 'p': case 'q': case 'r': case 's': case 't':
-    case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
-    case 'A': case 'B': case 'C': case 'D': case 'E':
-    case 'F': case 'G': case 'H': case 'I': case 'J':
-    case 'K': case 'L': case 'M': case 'N': case 'O':
-    case 'P': case 'Q': case 'R': case 'S': case 'T':
-    case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
-    case '-': case '.': case '_': case '~':
-      return TRUE;
-    default:
-      break;
-    }
-    return FLASE;
-}
-*/
-
-static inline bool is_unambiguous(char c) {
-    return IS_ALPHANUM(c) ||
-           c == '-' ||
-           c == '_' ||
-           c == '.' ||
-           c == '~';
-}
-
-// scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]
-static std::string escape(const std::string& param) {
-    std::string str;
-    const char* p = param.c_str();
-    char escape[4] = {0};
-    while (*p != '\0') {
-        if (is_unambiguous(*p)) {
-            str += *p;
-        }
-        else {
-            sprintf(escape, "%%%02X", *p);
-            str += escape;
-        }
-        ++p;
-    }
-    return str;
-}
-
-static std::string unescape(const char* escape_param) {
-    std::string str;
-    const char* p = escape_param;
-    while (*p != '\0') {
-        if (*p == '%' &&
-            IS_HEX(p[1]) &&
-            IS_HEX(p[2])) {
-            str += (hex2i(p[1]) << 4 | hex2i(p[2]));
-            p += 3;
-        }
-        else {
-            str += *p;
-            ++p;
-        }
-    }
-    return str;
-}
+#include "hurl.h"
 
 std::string dump_query_params(QueryParams& query_params) {
     std::string query_string;
@@ -99,9 +8,9 @@ std::string dump_query_params(QueryParams& query_params) {
         if (query_string.size() != 0) {
             query_string += '&';
         }
-        query_string += escape(pair.first);
+        query_string += url_escape(pair.first.c_str());
         query_string += '=';
-        query_string += escape(pair.second);
+        query_string += url_escape(pair.second.c_str());
     }
     return query_string;
 }
@@ -109,8 +18,6 @@ std::string dump_query_params(QueryParams& query_params) {
 int parse_query_params(const char* query_string, QueryParams& query_params) {
     const char* p = strchr(query_string, '?');
     p = p ? p+1 : query_string;
-    std::string unescape_string = unescape(p);
-    p = unescape_string.c_str();
 
     enum {
         s_key,
@@ -124,7 +31,9 @@ int parse_query_params(const char* query_string, QueryParams& query_params) {
     while (*p != '\0') {
         if (*p == '&') {
             if (key_len && value_len) {
-                query_params[std::string(key,key_len)] = std::string(value,value_len);
+                std::string strkey = std::string(key, key_len);
+                std::string strvalue = std::string(value, value_len);
+                query_params[url_unescape(strkey.c_str())] = url_unescape(strvalue.c_str());
                 key_len = value_len = 0;
             }
             state = s_key;
@@ -140,28 +49,21 @@ int parse_query_params(const char* query_string, QueryParams& query_params) {
         ++p;
     }
     if (key_len && value_len) {
-        query_params[std::string(key,key_len)] = std::string(value,value_len);
+        std::string strkey = std::string(key, key_len);
+        std::string strvalue = std::string(value, value_len);
+        query_params[url_unescape(strkey.c_str())] = url_unescape(strvalue.c_str());
         key_len = value_len = 0;
     }
     return query_params.size() == 0 ? -1 : 0;
 }
 
 #ifndef WITHOUT_HTTP_CONTENT
-std::string dump_json(Json& json) {
-    return json.dump();
-}
 
-std::string g_parse_json_errmsg;
-int parse_json(const char* str, Json& json, std::string& errmsg) {
-    try {
-        json = Json::parse(str);
-    }
-    catch(nlohmann::detail::exception e) {
-        errmsg = e.what();
-        return -1;
-    }
-    return (json.is_discarded() || json.is_null()) ? -1 : 0;
-}
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "hstring.h" // for split
+#include "httpdef.h" // for http_content_type_str_by_suffix
 
 std::string dump_multipart(MultiPart& mp, const char* boundary) {
     char c_str[256] = {0};
@@ -329,4 +231,20 @@ int parse_multipart(std::string& str, MultiPart& mp, const char* boundary) {
     multipart_parser_free(parser);
     return nparse == str.size() ? 0 : -1;
 }
+
+std::string dump_json(Json& json) {
+    return json.dump();
+}
+
+std::string g_parse_json_errmsg;
+int parse_json(const char* str, Json& json, std::string& errmsg) {
+    try {
+        json = Json::parse(str);
+    }
+    catch(nlohmann::detail::exception e) {
+        errmsg = e.what();
+        return -1;
+    }
+    return (json.is_discarded() || json.is_null()) ? -1 : 0;
+}
 #endif

+ 6 - 6
http/http_content.h

@@ -55,12 +55,6 @@ int         parse_query_params(const char* query_string, QueryParams& query_para
 // NOTE: WITHOUT_HTTP_CONTENT
 // ndk-r10e no std::to_string and can't compile modern json.hpp
 #ifndef WITHOUT_HTTP_CONTENT
-// Json
-#include "json.hpp"
-using Json = nlohmann::json;
-extern std::string g_parse_json_errmsg;
-std::string dump_json(Json& json);
-int         parse_json(const char* str, Json& json, std::string& errmsg = g_parse_json_errmsg);
 
 /**************multipart/form-data*************************************
 --boundary
@@ -108,6 +102,12 @@ typedef MAP<std::string, FormData>          MultiPart;
 std::string dump_multipart(MultiPart& mp, const char* boundary = DEFAULT_MULTIPART_BOUNDARY);
 int         parse_multipart(std::string& str, MultiPart& mp, const char* boundary);
 
+// Json
+#include "json.hpp"
+using Json = nlohmann::json;
+extern std::string g_parse_json_errmsg;
+std::string dump_json(Json& json);
+int         parse_json(const char* str, Json& json, std::string& errmsg = g_parse_json_errmsg);
 #endif
 
 #endif // HTTP_CONTENT_H_

+ 1 - 1
http/server/HttpService.h

@@ -7,7 +7,7 @@
 #include <list>
 #include <memory>
 
-#include "HttpPayload.h"
+#include "HttpMessage.h"
 
 #define DEFAULT_BASE_URL        "/v1/api"
 #define DEFAULT_DOCUMENT_ROOT   "/var/www/html"