ithewei 6 năm trước cách đây
mục cha
commit
08a6495bd7
5 tập tin đã thay đổi với 57 bổ sung26 xóa
  1. 8 0
      base/hstring.h
  2. 28 4
      http/HttpRequest.h
  3. 1 12
      http/client/http_client.cpp
  4. 19 8
      http/http_content.cpp
  5. 1 2
      http/server/FileCache.h

+ 8 - 0
base/hstring.h

@@ -16,6 +16,14 @@
 using std::string;
 typedef std::vector<string> StringList;
 
+// std::map<std::string, std::string, StringCaseLess>
+class StringCaseLess : public std::binary_function<std::string, std::string, bool> {
+public:
+    bool operator()(const std::string& lhs, const std::string& rhs) {
+        return stricmp(lhs.c_str(), rhs.c_str()) < 0;
+    }
+};
+
 #define SPACE_CHARS     " \t\r\n"
 #define PAIR_CHARS      "{}[]()<>\"\"\'\'``"
 

+ 28 - 4
http/HttpRequest.h

@@ -86,8 +86,9 @@ inline const char* http_content_type_str_by_suffix(const char* suf) {
 }
 
 #include "http_content.h"
-typedef std::map<std::string, std::string>  http_headers;
-typedef std::string                         http_body;
+#include "hstring.h"
+typedef std::map<std::string, std::string, StringCaseLess>  http_headers;
+typedef std::string     http_body;
 class HttpInfo {
 public:
     unsigned short      http_major;
@@ -110,7 +111,7 @@ public:
         auto iter = headers.find("Content-Type");
         if (iter != headers.end()) {
             content_type = http_content_type_enum(iter->second.c_str());
-            return;
+            goto append;
         }
 
         if (content_type == CONTENT_TYPE_NONE) {
@@ -131,6 +132,18 @@ public:
         if (content_type != CONTENT_TYPE_NONE) {
             headers["Content-Type"] = http_content_type_str(content_type);
         }
+append:
+        if (content_type == MULTIPART_FORM_DATA) {
+            auto iter = headers.find("Content-Type");
+            if (iter != headers.end()) {
+                const char* boundary = strstr(iter->second.c_str(), "boundary=");
+                if (boundary == NULL) {
+                    boundary = DEFAULT_MULTIPART_BOUNDARY;
+                    iter->second += "; boundary=";
+                    iter->second += boundary;
+                }
+            }
+        }
     }
 
     void fill_content_lenght() {
@@ -161,7 +174,18 @@ public:
             body = dump_json(json);
             break;
         case MULTIPART_FORM_DATA:
-            body = dump_multipart(mp);
+        {
+            auto iter = headers.find("Content-Type");
+            if (iter == headers.end()) {
+                return;
+            }
+            const char* boundary = strstr(iter->second.c_str(), "boundary=");
+            if (boundary == NULL) {
+                return;
+            }
+            boundary += strlen("boundary=");
+            body = dump_multipart(mp, boundary);
+        }
             break;
         case X_WWW_FORM_URLENCODED:
             body = dump_query_params(kv);

+ 1 - 12
http/client/http_client.cpp

@@ -1,17 +1,6 @@
 #include "http_client.h"
 
-#include <string.h>
-#include <string>
-using std::string;
-
-#define SPACE_CHARS     " \t\r\n"
-static string trim(const string& str) {
-    string::size_type pos1 = str.find_first_not_of(SPACE_CHARS);
-    if (pos1 == string::npos)   return "";
-
-    string::size_type pos2 = str.find_last_not_of(SPACE_CHARS);
-    return str.substr(pos1, pos2-pos1+1);
-}
+#include "hstring.h"
 
 /***************************************************************
 HttpClient based libcurl

+ 19 - 8
http/http_content.cpp

@@ -5,6 +5,8 @@
 
 #include "hstring.h"
 
+#include "HttpRequest.h"
+
 #ifndef LOWER
 #define LOWER(c)    ((c) | 0x20)
 #endif
@@ -182,6 +184,15 @@ std::string dump_multipart(MultiPart& mp, const char* boundary) {
             }
             snprintf(c_str, sizeof(c_str), "; filename=\"%s\"", basename(form.filename).c_str());
             str += c_str;
+            const char* suffix = strrchr(form.filename.c_str(), '.');
+            if (suffix) {
+                const char* stype = http_content_type_str_by_suffix(++suffix);
+                if (stype && *stype != '\0') {
+                    str += "\r\n";
+                    str += "Content-Type: ";
+                    str += stype;
+                }
+            }
         }
         str += "\r\n\r\n";
         str += form.content;
@@ -246,7 +257,7 @@ struct multipart_parser_userdata {
     }
 };
 static int on_header_field(multipart_parser* parser, const char *at, size_t length) {
-    printf("on_header_field:%.*s\n", (int)length, at);
+    //printf("on_header_field:%.*s\n", (int)length, at);
     multipart_parser_userdata* userdata = (multipart_parser_userdata*)multipart_parser_get_data(parser);
     userdata->handle_header();
     userdata->state = MP_HEADER_FIELD;
@@ -254,47 +265,47 @@ static int on_header_field(multipart_parser* parser, const char *at, size_t leng
     return 0;
 }
 static int on_header_value(multipart_parser* parser, const char *at, size_t length) {
-    printf("on_header_value:%.*s\n", (int)length, at);
+    //printf("on_header_value:%.*s\n", (int)length, at);
     multipart_parser_userdata* userdata = (multipart_parser_userdata*)multipart_parser_get_data(parser);
     userdata->state = MP_HEADER_VALUE;
     userdata->header_value.insert(userdata->header_value.size(), at, length);
     return 0;
 }
 static int on_part_data(multipart_parser* parser, const char *at, size_t length) {
-    printf("on_part_data:%.*s\n", (int)length, at);
+    //printf("on_part_data:%.*s\n", (int)length, at);
     multipart_parser_userdata* userdata = (multipart_parser_userdata*)multipart_parser_get_data(parser);
     userdata->state = MP_PART_DATA;
     userdata->part_data.insert(userdata->part_data.size(), at, length);
     return 0;
 }
 static int on_part_data_begin(multipart_parser* parser) {
-    printf("on_part_data_begin\n");
+    //printf("on_part_data_begin\n");
     multipart_parser_userdata* userdata = (multipart_parser_userdata*)multipart_parser_get_data(parser);
     userdata->state = MP_PART_DATA_BEGIN;
     return 0;
 }
 static int on_headers_complete(multipart_parser* parser) {
-    printf("on_headers_complete\n");
+    //printf("on_headers_complete\n");
     multipart_parser_userdata* userdata = (multipart_parser_userdata*)multipart_parser_get_data(parser);
     userdata->handle_header();
     userdata->state = MP_HEADERS_COMPLETE;
     return 0;
 }
 static int on_part_data_end(multipart_parser* parser) {
-    printf("on_part_data_end\n");
+    //printf("on_part_data_end\n");
     multipart_parser_userdata* userdata = (multipart_parser_userdata*)multipart_parser_get_data(parser);
     userdata->state = MP_PART_DATA_END;
     userdata->handle_data();
     return 0;
 }
 static int on_body_end(multipart_parser* parser) {
-    printf("on_body_end\n");
+    //printf("on_body_end\n");
     multipart_parser_userdata* userdata = (multipart_parser_userdata*)multipart_parser_get_data(parser);
     userdata->state = MP_BODY_END;
     return 0;
 }
 int parse_multipart(std::string& str, MultiPart& mp, const char* boundary) {
-    printf("boundary=%s\n", boundary);
+    //printf("boundary=%s\n", boundary);
     std::string __boundary("--");
     __boundary += boundary;
     multipart_parser_settings settings;

+ 1 - 2
http/server/FileCache.h

@@ -102,8 +102,7 @@ public:
             fc->etag[32] = '\0';
             const char* suffix = strrchr(filepath, '.');
             if (suffix) {
-                ++suffix;
-                fc->content_type = http_content_type_str_by_suffix(suffix);
+                fc->content_type = http_content_type_str_by_suffix(++suffix);
             }
         }
         return fc;