Prechádzať zdrojové kódy

SSE: Content-Type: text/event-stream

ithewei 4 rokov pred
rodič
commit
de856c8f30

+ 13 - 0
examples/httpd/handler.cpp

@@ -284,3 +284,16 @@ int Handler::upload(const HttpContextPtr& ctx) {
     }
     return response_status(ctx, status_code);
 }
+
+int Handler::sse(const HttpContextPtr& ctx) {
+    ctx->writer->EndHeaders("Content-Type", "text/event-stream");
+    // send(time) every 1s
+    hv::setInterval(1000, [ctx](hv::TimerID timerID) {
+        char szTime[DATETIME_FMT_BUFLEN] = {0};
+        datetime_t now = datetime_now();
+        datetime_fmt(&now, szTime);
+        ctx->writer->write("event: timeout\n");
+        ctx->writer->write(hv::asprintf("data: %s\n\n", szTime));
+    });
+    return HTTP_STATUS_UNFINISHED;
+}

+ 2 - 0
examples/httpd/handler.h

@@ -26,6 +26,8 @@ public:
 
     static int login(const HttpContextPtr& ctx);
     static int upload(const HttpContextPtr& ctx);
+    // SSE: Server Send Events
+    static int sse(const HttpContextPtr& ctx);
 
 private:
     static int response_status(HttpResponse* resp, int code = 200, const char* message = NULL) {

+ 7 - 4
examples/httpd/router.cpp

@@ -110,12 +110,12 @@ void Router::Register(hv::HttpService& router) {
     router.POST("/json", Handler::json);
 
     // Content-Type: multipart/form-data
-    // bin/curl -v http://ip:port/form -F "user=admin pswd=123456"
+    // bin/curl -v http://ip:port/form -F 'user=admin' -F 'pswd=123456'
     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'
+    // bin/curl -v http://ip:port/test -F 'bool=1' -F 'int=123' -F 'float=3.14' -F 'string=hello'
     router.POST("/test", Handler::test);
 
     // Content-Type: application/grpc
@@ -130,7 +130,10 @@ void Router::Register(hv::HttpService& router) {
     // curl -v http://ip:port/login -H "Content-Type:application/json" -d '{"username":"admin","password":"123456"}'
     router.POST("/login", Handler::login);
 
-    // curl -v http://ip:port/upload -d "hello,world!"
-    // curl -v http://ip:port/upload -F "file=@LICENSE"
+    // curl -v http://ip:port/upload -d '@LICENSE'
+    // curl -v http://ip:port/upload -F 'file=@LICENSE'
     router.POST("/upload", Handler::upload);
+
+    // SSE: Server Send Events
+    router.GET("/SSE", Handler::sse);
 }

+ 1 - 1
http/HttpMessage.cpp

@@ -322,7 +322,7 @@ void HttpMessage::FillContentLength() {
         DumpBody();
         content_length = body.size();
     }
-    if (iter == headers.end() && !IsChunked()) {
+    if (iter == headers.end() && !IsChunked() && content_type != TEXT_EVENT_STREAM) {
         if (content_length != 0 || type == HTTP_RESPONSE) {
             headers["Content-Length"] = hv::to_string(content_length);
         }

+ 1 - 1
http/HttpMessage.h

@@ -432,7 +432,7 @@ public:
     }
 
     // scheme
-    bool isHttps() {
+    bool IsHttps() {
         return strncmp(scheme.c_str(), "https", 5) == 0 ||
                strncmp(url.c_str(), "https://", 8) == 0;
     }

+ 1 - 1
http/client/AsyncHttpClient.cpp

@@ -47,7 +47,7 @@ int AsyncHttpClient::doTask(const HttpClientTaskPtr& task) {
         hio_set_peeraddr(connio, &peeraddr.sa, sockaddr_len(&peeraddr));
         addChannel(connio);
         // https
-        if (req->isHttps()) {
+        if (req->IsHttps()) {
             hio_enable_ssl(connio);
         }
     }

+ 2 - 2
http/client/http_client.cpp

@@ -166,7 +166,7 @@ static int http_client_make_request(http_client_t* cli, HttpRequest* req) {
         req->port = cli->port;
     }
 
-    bool https = req->isHttps();
+    bool https = req->IsHttps();
     bool use_proxy = https ? (!cli->https_proxy_host.empty()) : (!cli->http_proxy_host.empty());
     if (use_proxy) {
         if (req->host == "127.0.0.1" || req->host == "localhost") {
@@ -452,7 +452,7 @@ int __http_client_send(http_client_t* cli, HttpRequest* req, HttpResponse* resp)
     int err = 0;
     int timeout = req->timeout;
     int connfd = cli->fd;
-    bool https = req->isHttps();
+    bool https = req->IsHttps();
     bool keepalive = true;
 
     time_t start_time = time(NULL);

+ 1 - 0
http/httpdef.h

@@ -149,6 +149,7 @@ enum http_method {
     XX(TEXT_PLAIN,              text/plain,               txt)          \
     XX(TEXT_HTML,               text/html,                html)         \
     XX(TEXT_CSS,                text/css,                 css)          \
+    XX(TEXT_EVENT_STREAM,       text/event-stream,        sse)          \
     XX(IMAGE_JPEG,              image/jpeg,               jpg)          \
     XX(IMAGE_PNG,               image/png,                png)          \
     XX(IMAGE_GIF,               image/gif,                gif)          \

+ 1 - 0
http/server/HttpResponseWriter.h

@@ -27,6 +27,7 @@ public:
     // Begin -> End
     // Begin -> WriteResponse -> End
     // Begin -> WriteStatus -> WriteHeader -> WriteBody -> End
+    // Begin -> EndHeaders("Content-Type", "text/event-stream") -> write -> write -> ... -> close
     // Begin -> EndHeaders("Content-Length", content_length) -> WriteBody -> WriteBody -> ... -> End
     // Begin -> EndHeaders("Transfer-Encoding", "chunked") -> WriteChunked -> WriteChunked -> ... -> End