Browse Source

test http_async_handler

hewei.it 4 năm trước cách đây
mục cha
commit
eaaa031665
6 tập tin đã thay đổi với 71 bổ sung14 xóa
  1. 2 1
      Makefile
  2. 1 0
      Makefile.vars
  3. 1 0
      cmake/vars.cmake
  4. 10 6
      examples/CMakeLists.txt
  5. 22 5
      examples/httpd/handler.h
  6. 35 2
      examples/httpd/router.h

+ 2 - 1
Makefile

@@ -99,7 +99,8 @@ nmap: prepare
 	$(MAKEF) TARGET=$@ SRCDIRS=". base event cpputil examples/nmap" SRCS="examples/nmap/nmap_test.cpp" DEFINES="PRINT_DEBUG"
 
 httpd: prepare
-	$(MAKEF) TARGET=$@ SRCDIRS=". base event util cpputil evpp http http/server examples/httpd"
+	$(RM) examples/httpd/*.o
+	$(MAKEF) TARGET=$@ SRCDIRS=". base event util cpputil evpp http http/client http/server examples/httpd"
 
 curl: prepare
 	$(MAKEF) TARGET=$@ SRCDIRS=". base event util cpputil evpp http http/client" SRCS="examples/curl.cpp"

+ 1 - 0
Makefile.vars

@@ -81,6 +81,7 @@ HTTP_CLIENT_HEADERS =   http/client/http_client.h\
 
 HTTP_SERVER_HEADERS =   http/server/HttpService.h\
 						http/server/HttpServer.h\
+						http/server/HttpResponseWriter.h\
 						http/server/WebSocketServer.h\
 
 CONSUL_HEADERS = consul/consul.h

+ 1 - 0
cmake/vars.cmake

@@ -90,6 +90,7 @@ set(HTTP_CLIENT_HEADERS
 set(HTTP_SERVER_HEADERS
     http/server/HttpService.h
     http/server/HttpServer.h
+    http/server/HttpResponseWriter.h
     http/server/WebSocketServer.h
 )
 

+ 10 - 6
examples/CMakeLists.txt

@@ -51,11 +51,6 @@ if(WITH_HTTP)
 if(WITH_HTTP_SERVER)
     include_directories(../http/server)
 
-    # httpd
-    aux_source_directory(httpd HTTPD_SRCS)
-    add_executable(httpd ${HTTPD_SRCS})
-    target_link_libraries(httpd hv)
-
     # http_server_test
     add_executable(http_server_test http_server_test.cpp)
     target_link_libraries(http_server_test hv)
@@ -64,7 +59,7 @@ if(WITH_HTTP_SERVER)
     add_executable(websocket_server_test websocket_server_test.cpp)
     target_link_libraries(websocket_server_test hv)
 
-    list(APPEND EXAMPLES httpd http_server_test websocket_server_test)
+    list(APPEND EXAMPLES http_server_test websocket_server_test)
 endif()
 
 if(WITH_HTTP_CLIENT)
@@ -105,6 +100,15 @@ if(WITH_CONSUL)
 
     list(APPEND EXAMPLES consul_cli)
 endif()
+
+if(WITH_HTTP_SERVER)
+    # httpd
+    aux_source_directory(httpd HTTPD_SRCS)
+    add_executable(httpd ${HTTPD_SRCS})
+    target_link_libraries(httpd hv)
+    list(APPEND EXAMPLES httpd)
+endif()
+
 endif()
 endif()
 

+ 22 - 5
examples/httpd/handler.h

@@ -2,11 +2,13 @@
 #define HV_HTTPD_HANDLER_H
 
 #include "HttpMessage.h"
+#include "HttpResponseWriter.h"
 #include "htime.h"
+#include "EventLoop.h" // import setTimeout, setInterval
 
 class Handler {
 public:
-    // preprocessor => handler => postprocessor
+    // preprocessor => api_handlers => postprocessor
     static int preprocessor(HttpRequest* req, HttpResponse* resp) {
         // printf("%s:%d\n", req->client_addr.ip.c_str(), req->client_addr.port);
         // printf("%s\n", req->Dump(true, true).c_str());
@@ -39,7 +41,7 @@ public:
     }
 
     static int sleep(HttpRequest* req, HttpResponse* resp) {
-        unsigned long long start_ms = gettimeofday_ms();
+        resp->Set("start_ms", gettimeofday_ms());
         std::string strTime = req->GetParam("t");
         if (!strTime.empty()) {
             int ms = atoi(strTime.c_str());
@@ -47,13 +49,28 @@ public:
                 hv_delay(ms);
             }
         }
-        unsigned long long end_ms = gettimeofday_ms();
-        resp->Set("start_ms", start_ms);
-        resp->Set("end_ms", end_ms);
+        resp->Set("end_ms", gettimeofday_ms());
         response_status(resp, 0, "OK");
         return 200;
     }
 
+    static void setTimeout(const HttpRequestPtr& req, const HttpResponseWriterPtr& writer) {
+        writer->resp->Set("start_ms", gettimeofday_ms());
+        std::string strTime = req->GetParam("t");
+        if (!strTime.empty()) {
+            int ms = atoi(strTime.c_str());
+            if (ms > 0) {
+                hv::setTimeout(ms, [writer](hv::TimerID timerID){
+                    writer->Begin();
+                    HttpResponse* resp = writer->resp.get();
+                    resp->Set("end_ms", gettimeofday_ms());
+                    response_status(resp, 0, "OK");
+                    writer->End();
+                });
+            }
+        }
+    }
+
     static int query(HttpRequest* req, HttpResponse* resp) {
         // scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]
         // ?query => HttpRequest::query_params

+ 35 - 2
examples/httpd/router.h

@@ -1,7 +1,10 @@
 #ifndef HV_HTTPD_ROUTER_H
 #define HV_HTTPD_ROUTER_H
 
+#include <future> // import std::async
+
 #include "HttpService.h"
+#include "http_client.h"
 
 #include "handler.h"
 
@@ -42,14 +45,44 @@ public:
 
         // wildcard *
         // curl -v http://ip:port/wildcard/any
-        router.GET("/wildcard*", [](HttpRequest* req, HttpResponse* resp){
+        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
+        // curl -v http://ip:port/async
+        router.GET("/async", [](const HttpRequestPtr& req, const HttpResponseWriterPtr& writer) {
+            writer->resp->headers["X-Request-tid"] = hv::to_string(hv_gettid());
+            std::async([req, writer](){
+                writer->Begin();
+                std::string resp_tid = hv::to_string(hv_gettid());
+                writer->resp->headers["X-Response-tid"] = hv::to_string(hv_gettid());
+                writer->WriteHeader("Content-Type", "text/plain");
+                writer->WriteBody("This is an async response.\n");
+                writer->End();
+            });
+        });
+
+        // curl -v http://ip:port/www/*
+        // curl -v http://ip:port/www/example.com
+        // curl -v http://ip:port/www/example/com
+        router.GET("/www/*", [](const HttpRequestPtr& req, const HttpResponseWriterPtr& writer) {
+            HttpRequestPtr req2(new HttpRequest);
+            req2->url = replace(req->path.substr(1), "/", ".");
+            // printf("url=%s\n", req2->url.c_str());
+            http_client_send_async(req2, [writer](const HttpResponsePtr& resp2){
+                writer->Begin();
+                writer->resp = resp2;
+                writer->End();
+            });
+        });
+
+        // curl -v http://ip:port/sleep?t=1000
         router.GET("/sleep", Handler::sleep);
 
+        // curl -v http://ip:port/setTimeout?t=1000
+        router.GET("/setTimeout", Handler::setTimeout);
+
         // curl -v http://ip:port/query?page_no=1\&page_size=10
         router.GET("/query", Handler::query);