Browse Source

Add HttpResponse::Redirect HttpResponseWriter::SSEvent

ithewei 3 years ago
parent
commit
8776473481
4 changed files with 35 additions and 11 deletions
  1. 17 11
      examples/httpd/handler.cpp
  2. 1 0
      examples/httpd/router.cpp
  3. 6 0
      http/HttpMessage.h
  4. 11 0
      http/server/HttpResponseWriter.h

+ 17 - 11
examples/httpd/handler.cpp

@@ -13,6 +13,14 @@ int Handler::preprocessor(HttpRequest* req, HttpResponse* resp) {
     // printf("%s:%d\n", req->client_addr.ip.c_str(), req->client_addr.port);
     // printf("%s:%d\n", req->client_addr.ip.c_str(), req->client_addr.port);
     // printf("%s\n", req->Dump(true, true).c_str());
     // printf("%s\n", req->Dump(true, true).c_str());
 
 
+#if REDIRECT_HTTP_TO_HTTPS
+    // 301
+    if (req->scheme == "http") {
+        std::string location = hv::asprintf("https://%s:%d%s", req->host.c_str(), 8443, req->path.c_str());
+        return resp->Redirect(location);
+    }
+#endif
+
     // cors
     // cors
     resp->headers["Access-Control-Allow-Origin"] = "*";
     resp->headers["Access-Control-Allow-Origin"] = "*";
     if (req->method == HTTP_OPTIONS) {
     if (req->method == HTTP_OPTIONS) {
@@ -350,18 +358,16 @@ int Handler::sendLargeFile(const HttpContextPtr& ctx) {
 }
 }
 
 
 int Handler::sse(const HttpContextPtr& ctx) {
 int Handler::sse(const HttpContextPtr& ctx) {
-    ctx->writer->EndHeaders("Content-Type", "text/event-stream");
-    // send(message) every 1s
+    // SSEvent(message) every 1s
     hv::setInterval(1000, [ctx](hv::TimerID timerID) {
     hv::setInterval(1000, [ctx](hv::TimerID timerID) {
-        char szTime[DATETIME_FMT_BUFLEN] = {0};
-        datetime_t now = datetime_now();
-        datetime_fmt(&now, szTime);
-        // @test html/EventSource.html EventSource.onmessage
-        std::string msg("event: message\n");
-        msg += "data: ";
-        msg += szTime;
-        msg += "\n\n";
-        ctx->writer->write(msg);
+        if (ctx->writer->isConnected()) {
+            char szTime[DATETIME_FMT_BUFLEN] = {0};
+            datetime_t now = datetime_now();
+            datetime_fmt(&now, szTime);
+            ctx->writer->SSEvent(szTime);
+        } else {
+            hv::killTimer(timerID);
+        }
     });
     });
     return HTTP_STATUS_UNFINISHED;
     return HTTP_STATUS_UNFINISHED;
 }
 }

+ 1 - 0
examples/httpd/router.cpp

@@ -137,5 +137,6 @@ void Router::Register(hv::HttpService& router) {
     router.POST("/upload/{filename}", Handler::recvLargeFile);
     router.POST("/upload/{filename}", Handler::recvLargeFile);
 
 
     // SSE: Server Send Events
     // SSE: Server Send Events
+    // @test html/EventSource.html EventSource.onmessage
     router.GET("/sse", Handler::sse);
     router.GET("/sse", Handler::sse);
 }
 }

+ 6 - 0
http/HttpMessage.h

@@ -562,6 +562,12 @@ public:
         from = to = total = 0;
         from = to = total = 0;
         return false;
         return false;
     }
     }
+
+    int Redirect(const std::string& location, http_status status = HTTP_STATUS_MOVED_PERMANENTLY) {
+        status_code = status;
+        headers["Location"] = location;
+        return status_code;
+    }
 };
 };
 
 
 typedef std::shared_ptr<HttpRequest>    HttpRequestPtr;
 typedef std::shared_ptr<HttpRequest>    HttpRequestPtr;

+ 11 - 0
http/server/HttpResponseWriter.h

@@ -130,6 +130,17 @@ public:
         return write(msg);
         return write(msg);
     }
     }
 
 
+    int SSEvent(const std::string& data, const char* event = "message") {
+        if (state == SEND_BEGIN) {
+            EndHeaders("Content-Type", "text/event-stream");
+        }
+        std::string msg;
+        msg =  "event: "; msg += event; msg += "\n";
+        msg += "data: ";  msg += data;  msg += "\n\n";
+        state = SEND_BODY;
+        return write(msg);
+    }
+
     int End(const char* buf = NULL, int len = -1) {
     int End(const char* buf = NULL, int len = -1) {
         if (end == SEND_END) return 0;
         if (end == SEND_END) return 0;
         end = SEND_END;
         end = SEND_END;