Parcourir la source

HttpMessage::String Data File Json

ithewei il y a 5 ans
Parent
commit
599f087098
6 fichiers modifiés avec 147 ajouts et 35 suppressions
  1. 14 6
      README.md
  2. 14 6
      examples/http_server_test.cpp
  3. 39 17
      examples/httpd/router.h
  4. 6 0
      getting_started.sh
  5. 60 0
      http/HttpMessage.h
  6. 14 6
      readme_cn.md

+ 14 - 6
README.md

@@ -45,13 +45,21 @@ see [examples/http_server_test.cpp](examples/http_server_test.cpp)
 #include "HttpServer.h"
 
 int main() {
-    HttpService service;
-    service.GET("/ping", [](HttpRequest* req, HttpResponse* resp) {
-        resp->body = "pong";
-        return 200;
+    HttpService router;
+    router.GET("/ping", [](HttpRequest* req, HttpResponse* resp) {
+        return resp->String("pong");
+    });
+
+    router.GET("/data", [](HttpRequest* req, HttpResponse* resp) {
+        static char data[] = "0123456789";
+        return resp->Data(data, 10);
+    });
+
+    router.GET("/paths", [&router](HttpRequest* req, HttpResponse* resp) {
+        return resp->Json(router.Paths());
     });
 
-    service.POST("/echo", [](HttpRequest* req, HttpResponse* resp) {
+    router.POST("/echo", [](HttpRequest* req, HttpResponse* resp) {
         resp->content_type = req->content_type;
         resp->body = req->body;
         return 200;
@@ -59,7 +67,7 @@ int main() {
 
     http_server_t server;
     server.port = 8080;
-    server.service = &service;
+    server.service = &router;
     http_server_run(&server);
     return 0;
 }

+ 14 - 6
examples/http_server_test.cpp

@@ -9,13 +9,21 @@
 int main() {
     HV_MEMCHECK;
 
-    HttpService service;
-    service.GET("/ping", [](HttpRequest* req, HttpResponse* resp) {
-        resp->body = "pong";
-        return 200;
+    HttpService router;
+    router.GET("/ping", [](HttpRequest* req, HttpResponse* resp) {
+        return resp->String("pong");
+    });
+
+    router.GET("/data", [](HttpRequest* req, HttpResponse* resp) {
+        static char data[] = "0123456789";
+        return resp->Data(data, 10);
+    });
+
+    router.GET("/paths", [&router](HttpRequest* req, HttpResponse* resp) {
+        return resp->Json(router.Paths());
     });
 
-    service.POST("/echo", [](HttpRequest* req, HttpResponse* resp) {
+    router.POST("/echo", [](HttpRequest* req, HttpResponse* resp) {
         resp->content_type = req->content_type;
         resp->body = req->body;
         return 200;
@@ -27,7 +35,7 @@ int main() {
     // server.worker_processes = 4;
     // uncomment to test multi-threads
     // server.worker_threads = 4;
-    server.service = &service;
+    server.service = &router;
 
 #if 1
     http_server_run(&server);

+ 39 - 17
examples/httpd/router.h

@@ -7,60 +7,82 @@
 
 class Router {
 public:
-    static void Register(HttpService& http) {
+    static void Register(HttpService& router) {
         // preprocessor => Handler => postprocessor
-        http.preprocessor = Handler::preprocessor;
-        http.postprocessor = Handler::postprocessor;
+        router.preprocessor = Handler::preprocessor;
+        router.postprocessor = Handler::postprocessor;
 
         // curl -v http://ip:port/ping
-        http.GET("/ping", [](HttpRequest* req, HttpResponse* resp) {
-            resp->body = "pong";
-            return 200;
+        router.GET("/ping", [](HttpRequest* req, HttpResponse* resp) {
+            return resp->String("pong");
+        });
+
+        // curl -v http://ip:port/data
+        router.GET("/data", [](HttpRequest* req, HttpResponse* resp) {
+            static char data[] = "0123456789";
+            return resp->Data(data, 10);
+        });
+
+        // curl -v http://ip:port/html/index.html
+        router.GET("/html/index.html", [&router](HttpRequest* req, HttpResponse* resp) {
+            return resp->File("html/index.html");
+        });
+
+        // curl -v http://ip:port/paths
+        router.GET("/paths", [&router](HttpRequest* req, HttpResponse* resp) {
+            return resp->Json(router.Paths());
         });
 
         // curl -v http://ip:port/echo -d "hello,world!"
-        http.POST("/echo", [](HttpRequest* req, HttpResponse* resp) {
+        router.POST("/echo", [](HttpRequest* req, HttpResponse* resp) {
             resp->content_type = req->content_type;
             resp->body = req->body;
             return 200;
         });
 
+        // wildcard *
+        // curl -v http://ip:port/wildcard/any
+        router.GET("/wildcard*", [](HttpRequest* req, HttpResponse* resp){
+            std::string str = req->path + " match /wildcard*";
+            return resp->String(str);
+        });
+
         // curl -v http://ip:port/sleep?t=3
-        http.GET("/sleep", Handler::sleep);
+        router.GET("/sleep", Handler::sleep);
 
         // curl -v http://ip:port/query?page_no=1\&page_size=10
-        http.GET("/query", Handler::query);
+        router.GET("/query", Handler::query);
 
         // Content-Type: application/x-www-form-urlencoded
         // curl -v http://ip:port/kv -H "content-type:application/x-www-form-urlencoded" -d 'user=admin&pswd=123456'
-        http.POST("/kv", Handler::kv);
+        router.POST("/kv", Handler::kv);
 
         // Content-Type: application/json
         // curl -v http://ip:port/json -H "Content-Type:application/json" -d '{"user":"admin","pswd":"123456"}'
-        http.POST("/json", Handler::json);
+        router.POST("/json", Handler::json);
 
         // Content-Type: multipart/form-data
         // bin/curl -v localhost:8080/form -F "user=admin pswd=123456"
-        http.POST("/form", Handler::form);
+        router.POST("/form", Handler::form);
 
         // curl -v http://ip:port/test -H "Content-Type:application/x-www-form-urlencoded" -d 'bool=1&int=123&float=3.14&string=hello'
         // curl -v http://ip:port/test -H "Content-Type:application/json" -d '{"bool":true,"int":123,"float":3.14,"string":"hello"}'
         // bin/curl -v http://ip:port/test -F 'bool=1 int=123 float=3.14 string=hello'
-        http.POST("/test", Handler::test);
+        router.POST("/test", Handler::test);
 
         // Content-Type: application/grpc
         // bin/curl -v --http2 http://ip:port/grpc -H "content-type:application/grpc" -d 'protobuf'
-        http.POST("/grpc", Handler::grpc);
+        router.POST("/grpc", Handler::grpc);
 
         // RESTful API: /group/:group_name/user/:user_id
         // curl -v -X DELETE http://ip:port/group/test/user/123
-        http.Delete("/group/:group_name/user/:user_id", Handler::restful);
+        router.Delete("/group/:group_name/user/:user_id", Handler::restful);
 
         // bin/curl -v localhost:8080/upload -F "file=@LICENSE"
-        http.POST("/upload", Handler::upload);
+        router.POST("/upload", Handler::upload);
 
         // curl -v http://ip:port/login -H "Content-Type:application/json" -d '{"username":"admin","password":"123456"}'
-        http.POST("/login", Handler::login);
+        router.POST("/login", Handler::login);
     }
 };
 

+ 6 - 0
getting_started.sh

@@ -36,8 +36,14 @@ cmd="bin/curl -v localhost:8080" && run_cmd
 cmd="bin/curl -v localhost:8080/downloads/" && run_cmd
 
 # http api service
+cmd="bin/curl -v localhost:8080/paths" && run_cmd
+
 cmd="bin/curl -v localhost:8080/ping" && run_cmd
 
+cmd="bin/curl -v localhost:8080/data" && run_cmd
+
+cmd="bin/curl -v localhost:8080/html/index.html" && run_cmd
+
 cmd="bin/curl -v localhost:8080/echo -d 'hello,world!'" && echo_cmd
 bin/curl -v localhost:8080/echo -d 'hello,world!'
 

+ 60 - 0
http/HttpMessage.h

@@ -6,7 +6,10 @@
 #include <map>
 
 #include "hexport.h"
+#include "hbase.h"
 #include "hstring.h"
+#include "hfile.h"
+
 #include "httpdef.h"
 #include "http_content.h"
 
@@ -65,6 +68,28 @@ public:
             break;
         }
     }
+
+    /*
+     * null:    Json(nullptr);
+     * boolean: Json(true);
+     * number:  Json(123);
+     * string:  Json("hello");
+     * object:  Json(std::map<string, ValueType>);
+     *          Json(hv::Json::object({
+                    {"k1", "v1"},
+                    {"k2", "v2"}
+                }));
+     * array:   Json(std::vector<ValueType>);
+                Json(hv::Json::object(
+                    {1, 2, 3}
+                ));
+     */
+    template<typename T>
+    int Json(const T& t) {
+        content_type = APPLICATION_JSON;
+        json = t;
+        return 200;
+    }
 #endif
 
     HttpMessage() {
@@ -136,6 +161,41 @@ public:
         }
         return content_type;
     }
+
+    int String(const char* str) {
+        content_type = TEXT_PLAIN;
+        body = str;
+        return 200;
+    }
+
+    int String(std::string& str) {
+        content_type = TEXT_PLAIN;
+        body = str;
+        return 200;
+    }
+
+    int Data(void* data, int len) {
+        content_type = APPLICATION_OCTET_STREAM;
+        content = data;
+        content_length = len;
+        return 200;
+    }
+
+    int File(const char* filepath) {
+        HFile file;
+        if (file.open(filepath, "r") != 0) {
+            return HTTP_STATUS_NOT_FOUND;
+        }
+        const char* suffix = hv_suffixname(filepath);
+        if (suffix) {
+            content_type = http_content_type_enum_by_suffix(suffix);
+        }
+        if (content_type == CONTENT_TYPE_NONE || content_type == CONTENT_TYPE_UNDEFINED) {
+            content_type = APPLICATION_OCTET_STREAM;
+        }
+        file.readall(body);
+        return 200;
+    }
 };
 
 #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"

+ 14 - 6
readme_cn.md

@@ -43,13 +43,21 @@
 #include "HttpServer.h"
 
 int main() {
-    HttpService service;
-    service.GET("/ping", [](HttpRequest* req, HttpResponse* resp) {
-        resp->body = "pong";
-        return 200;
+    HttpService router;
+    router.GET("/ping", [](HttpRequest* req, HttpResponse* resp) {
+        return resp->String("pong");
+    });
+
+    router.GET("/data", [](HttpRequest* req, HttpResponse* resp) {
+        static char data[] = "0123456789";
+        return resp->Data(data, 10);
+    });
+
+    router.GET("/paths", [&router](HttpRequest* req, HttpResponse* resp) {
+        return resp->Json(router.Paths());
     });
 
-    service.POST("/echo", [](HttpRequest* req, HttpResponse* resp) {
+    router.POST("/echo", [](HttpRequest* req, HttpResponse* resp) {
         resp->content_type = req->content_type;
         resp->body = req->body;
         return 200;
@@ -57,7 +65,7 @@ int main() {
 
     http_server_t server;
     server.port = 8080;
-    server.service = &service;
+    server.service = &router;
     http_server_run(&server);
     return 0;
 }