zoukankan      html  css  js  c++  java
  • mongoose 开源http库(2) --HTTP服务示例

    要创建HTTP服务器,请按照以下格式:

    1. 通过调用mg_bind()mg_bind_opt()创建侦听连接
    2. 调用mg_set_protocol_http_websocket()创建listening连接。它附带一个内置的HTTP事件处理程序,它解析传入的数据并触发HTTP特定的事件。例如,当HTTP请求完全缓冲时,内置的HTTP处理程序会解析请求,并调用用户定义的事件处理程序,并将MG_EV_HTTP_REQUEST事件和解析的HTTP请求作为事件数据。
    3. 创建事件处理函数。请注意,事件处理程序接收所有事件 - 低级TCP事件MG_EV_RECV和高级HTTP事件,如MG_EV_HTTP_REQUEST通常情况下,事件处理函数只能处理MG_EV_HTTP_REQUEST事件。

    以下是最简单HTTP服务器的示例。为了清楚起见,省略了错误检查:

    #include "mongoose.h"
    
    static const char *s_http_port = "8000";
    
    static void ev_handler(struct mg_connection *c, int ev, void *p) {
      if (ev == MG_EV_HTTP_REQUEST) {
        struct http_message *hm = (struct http_message *) p;
    
        // We have received an HTTP request. Parsed request is contained in `hm`.
        // Send HTTP reply to the client which shows full original request.
        mg_send_head(c, 200, hm.message.len, "Content-Type: text/plain");
        mg_printf(c, "%.*s", hm.message.len, hm.message.p);
      }
    }
    
    int main(void) {
      struct mg_mgr mgr;
      struct mg_connection *c;
    
      mg_mgr_init(&mgr, NULL);
      c = mg_bind(&mgr, s_http_port, ev_handler);
      mg_set_protocol_http_websocket(c);
    
      for (;;) {
        mg_mgr_poll(&mgr, 1000);
      }
      mg_mgr_free(&mgr);
    
      return 0;
    }

    要创建HTTP客户端,请遵循以下模式:

    1. 通过调用创建出站连接 mg_connect_http()
    2. 创建一个处理MG_EV_HTTP_REPLY事件的事件处理函数

    以下是最简单HTTP客户端的示例。为了清楚起见,省略错误检查:

    #include "mongoose.h"
    
    static const char *url = "http://www.google.com";
    static int exit_flag = 0;
    
    static void ev_handler(struct mg_connection *c, int ev, void *p) {
      if (ev == MG_EV_HTTP_REPLY) {
        c->flags |= MG_F_CLOSE_IMMEDIATELY;
        fwrite(hm->message.p, 1, hm->message.len, stdout);
        putchar('
    ');
        exit_flag = 1;
      } else if (ev == MG_EV_CLOSE) {
        exit_flag = 1;
      };
    }
    
    int main(void) {
      struct mg_mgr mgr;
    
      mg_mgr_init(&mgr, NULL);
      mg_connect_http(mgr, ev_handler, url, NULL, NULL);
    
    
      while (exit_flag == 0) {
        mg_mgr_poll(&mgr, 1000);
      }
      mg_mgr_free(&mgr);
    
      return 0;
    }

    HTTP事件

    如概述所述,mg_set_protocol_http_websocket()函数解析输入数据,将其视为HTTP或WebSocket,并触发高级HTTP或WebSocket事件。以下是HTTP特有的事件列表。

    • MG_EV_HTTP_REQUEST:HTTP请求到达。解析的请求struct http_message通过处理程序的void *ev_data指针传递 
    • MG_EV_HTTP_REPLY:HTTP回复已到。解析的回复struct http_message通过处理程序的void *ev_data 指针传递
    • MG_EV_HTTP_MULTIPART_REQUEST:多部分POST请求已到。此事件在body解析之前发送。此后,用户应该期望一系列MG_EV_HTTP_PART_BEGIN / DATA / END请求。这也是头文件和其他请求字段可访问的最后一次。
    • MG_EV_HTTP_CHUNK:一个HTTP分块编码块到了。解析的HTTP回复struct http_message通过处理程序的void *ev_data指针传递http_message::body将包含不完整的,重新组合的HTTP身体。它将随着到达的每一个新的块增长,并且可能消耗大量的内存。事件处理程序可以处理以分块形式到来的body,并通知Mongoose通过设定在mg_connection::flags中的MG_F_DELETE_CHUNK来删除body当接收到最后一个零块时,Mongoose会发送MG_EV_HTTP_REPLY具有完全重新组合的身体的事件(如果处理程序没有指示删除块)或空的身体(如果处理程序发出信号删除块)。
    • MG_EV_HTTP_PART_BEGIN:多部分消息的新部分启动,额外的参数将以mg_http_multipart_part发送
    • MG_EV_HTTP_PART_DATA:来自多部分消息的新部分数据没有附加头可用,只有数据和数据大小
    • MG_EV_HTTP_PART_END:接收到最后一个边界,可能用于找到包的结尾注意:Mongoose应使用MG_ENABLE_HTTP_STREAMING_MULTIPART进行编译,以启用多部分事件。

    提供文件

    API函数mg_serve_http()可以轻松地从文件系统提供文件。一般来说,该功能是提供静态文件CGI和SSI的HTTP服务器的实现。它的行为是由整合到结构中的选项列表驱动的struct mg_serve_http_opts 。有关完整的功能列表,请参阅struct mg_serve_http_opts定义mg_serve_http()

    例如,为了创建一个从当前目录提供静态文件的Web服务器,实现如下的事件处理函数:

    static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
      if (ev == MG_EV_HTTP_REQUEST) {
        struct mg_serve_http_opts opts;
    
        memset(&opts, 0, sizeof(opts);  // Reset all options to defaults
        opts.document_root = ".";       // Serve files from the current directory
    
        mg_serve_http(c, (struct http_message *) ev_data, s_http_server_opts);
      }
    }

    其他选项请参考:
    https://docs.cesanta.com/mongoose/master/#/overview/event-handler.md/

  • 相关阅读:
    2021.01.28 Rating赛 解题/补题报告
    2021.01.23 Rating赛 补题&解题报告
    ACM 实验室2020.11.08天梯赛练习*5
    6. Python 基础 dict 字典 查找方法 set() 集合 公共方法
    5. python 基础 list [] 列表 tuple () 元组
    4. python 操作字符串 字符串的一些方法
    3. python基础 转化字符类型 循环
    2. python 数据类型 格式化
    1. Python是编译性语言解释性语言 pyCharm 配置
    科二 教育教学知识与能力4
  • 原文地址:https://www.cnblogs.com/gardenofhu/p/6961515.html
Copyright © 2011-2022 走看看