Mongoose http server 例子

这篇具有很好参考价值的文章主要介绍了Mongoose http server 例子。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        今天抽了点时间看了一下 mongoose的源码, github 地址,发现跟以前公司内部使用的不太一样,这里正好利用其 http server 例子来看一下。以前的 http message 结构体是这样的:

/* HTTP message */
struct http_message {
  struct mg_str message; /* Whole message: request line + headers + body */
  struct mg_str body;    /* Message body. 0-length for requests with no body */

  /* HTTP Request line (or HTTP response line) */
  struct mg_str method; /* "GET" */
  struct mg_str uri;    /* "/my_file.html" */
  struct mg_str proto;  /* "HTTP/1.1" -- for both request and response */

  /* For responses, code and response status message are set */
  int resp_code;
  struct mg_str resp_status_msg;

  /*
   * Query-string part of the URI. For example, for HTTP request
   *    GET /foo/bar?param1=val1&param2=val2
   *    |    uri    |     query_string     |
   *
   * Note that question mark character doesn't belong neither to the uri,
   * nor to the query_string
   */
  struct mg_str query_string;

  /* Headers */
  struct mg_str header_names[MG_MAX_HTTP_HEADERS];
  struct mg_str header_values[MG_MAX_HTTP_HEADERS];
};

github 上的源码的http message 结构体是这样的:

struct mg_http_message {
  struct mg_str method, uri, query, proto;             // Request/response line
  struct mg_http_header headers[MG_MAX_HTTP_HEADERS];  // Headers
  struct mg_str body;                                  // Body
  struct mg_str head;                                  // Request + headers
  struct mg_str chunk;    // Chunk for chunked encoding,  or partial body
  struct mg_str message;  // Request + headers + body
};

很明显现在的头部消息使用了 mg_http_header 结构体,它的定义是这样的:

struct mg_http_header {
  struct mg_str name;   // Header name
  struct mg_str value;  // Header value
};

今天使用的是mongoose 自带的例子,位于源码目录的 examples/http-server 下的 main.c,因为我使用了c++的,所以我自己创建了目录 myExample/http_server,把它的 main.c 换成了 main.cpp,makefile 使用自己的,在编译的时候解决一下编译问题即可。

Mongoose http server 例子,# Mongoose,http,c++

自己写的Makefile

#中间文件存放目录,如.o 和 .d 文件
COMPILE_DIR = compile
BIN_DIR = bin

# 可编译arm版本
#CROSS = arm-himix200-linux-
CC = gcc 
CPP = $(CROSS)g++ -std=c++11
CFLAGS = -Werror -g
CFLAGS += -I../../
CPP_SRCS = $(wildcard *.cpp)
CPP_OBJS = $(patsubst %.cpp, $(COMPILE_DIR)/%.o, $(CPP_SRCS))
CPP_DEP = $(patsubst %.cpp, $(COMPILE_DIR)/%.cpp.d, $(CPP_SRCS))

OBJS = $(CPP_OBJS) $(C_OBJS)
DEP_ALL = $(CPP_DEP) $(C_DEP)

$(shell if [ ! -d $(COMPILE_DIR) ]; then mkdir $(COMPILE_DIR); fi)
$(shell if [ ! -d $(BIN_DIR) ]; then mkdir $(BIN_DIR); fi)


BIN =
ifeq ($(target), ) #如果是空的
BIN = httpServer
else
BIN := $(target)
endif


TARGET=$(BIN_DIR)/$(BIN)


all: $(TARGET)

-include $(DEP_ALL)

$(TARGET): $(OBJS) $(COMPILE_DIR)/mongoose.o
	$(CPP) $(CFLAGS) $^ -o $@ 

$(COMPILE_DIR)/%.o: %.cpp $(COMPILE_DIR)/%.cpp.d
	$(CPP) $(CFLAGS) -c $< -o $@

$(COMPILE_DIR)/%.cpp.d: %.cpp
	$(CPP) $(CFLAGS) -MM -E -c $< -o $@
	@sed 's/.*\.o/$(subst /,\/,$(dir $@))&/g' $@ > $@.tmp
	@mv $@.tmp $@

$(COMPILE_DIR)/mongoose.o: ../../mongoose.c
	$(CC) $(CFLAGS) -c $< -o $@

$(COMPILE_DIR)/%.c.d: %.c
	$(CC) $(CFLAGS) -MM -E -c $< -o $@
	@sed 's/.*\.o/$(subst /,\/,$(dir $@))&/g' $@ > $@.tmp
	@mv $@.tmp $@

.PHONY: clean
clean:
	rm -rf $(COMPILE_DIR) $(BIN_DIR)

同时把main.cpp里的书写格式也改了,还是习惯一行行的看代码:

// Copyright (c) 2020 Cesanta Software Limited
// All rights reserved

#include <signal.h>
#include "mongoose.h"

static int s_debug_level = MG_LL_INFO;
static const char *s_root_dir = ".";
static const char *s_listening_address = "http://0.0.0.0:8190";
static const char *s_enable_hexdump = "no";
static const char *s_ssi_pattern = "#.html";

// Handle interrupts, like Ctrl-C
static int s_signo;
static void signal_handler(int signo) 
{
    s_signo = signo;
}

// Event handler for the listening connection.
// Simply serve static files from `s_root_dir`
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) 
{
    if (ev == MG_EV_HTTP_MSG) 
    {
        struct mg_http_message *hm = (mg_http_message *)ev_data, tmp = {0};
        struct mg_str unknown = mg_str_n("?", 1), *cl;
        struct mg_http_serve_opts opts = {0};
        
        //不能用ptr直接打印,需要根据len
        MG_INFO(("method(%d): %s, uri(%d): %s, query(%d): %s, proto(%d): %s", hm->method.len, hm->method.ptr, hm->uri.len, hm->uri.ptr, hm->query.len, hm->query.ptr, 
                hm->proto.len, hm->proto.ptr));
        MG_INFO(("method ptr: %p, uri ptr: %p, query ptr: %p, proto ptr: %p\n", hm->method.ptr, hm->uri.ptr, hm->query.ptr, hm->proto.ptr));
        
        //设置目录起点
        opts.root_dir = s_root_dir;
        opts.ssi_pattern = s_ssi_pattern;
        mg_http_serve_dir(c, hm, &opts);
        mg_http_parse((char *) c->send.buf, c->send.len, &tmp);
        cl = mg_http_get_header(&tmp, "Content-Length");
        if (cl == NULL) 
        {
            cl = &unknown;
        }

        MG_INFO(("%.*s %.*s %.*s %.*s", (int) hm->method.len, hm->method.ptr,
                    (int) hm->uri.len, hm->uri.ptr, (int) tmp.uri.len, tmp.uri.ptr,
                    (int) cl->len, cl->ptr));
    }
    (void) fn_data;
}

static void usage(const char *prog) 
{
    fprintf(stderr,
            "Mongoose v.%s\n"
            "Usage: %s OPTIONS\n"
            "  -H yes|no - enable traffic hexdump, default: '%s'\n"
            "  -S PAT    - SSI filename pattern, default: '%s'\n"
            "  -d DIR    - directory to serve, default: '%s'\n"
            "  -l ADDR   - listening address, default: '%s'\n"
            "  -v LEVEL  - debug level, from 0 to 4, default: %d\n",
            MG_VERSION, prog, s_enable_hexdump, s_ssi_pattern, s_root_dir,
            s_listening_address, s_debug_level);
    exit(EXIT_FAILURE);
}

int main(int argc, char *argv[]) 
{
    char path[MG_PATH_MAX] = ".";
    struct mg_mgr mgr;
    struct mg_connection *c;
    int i;

    // Parse command-line flags
    for (i = 1; i < argc; i++) 
    {
        if (strcmp(argv[i], "-d") == 0) 
        {
            s_root_dir = argv[++i];
        } 
        else if (strcmp(argv[i], "-H") == 0) 
        {
            s_enable_hexdump = argv[++i];
        } 
        else if (strcmp(argv[i], "-S") == 0) 
        {
            s_ssi_pattern = argv[++i];
        } 
        else if (strcmp(argv[i], "-l") == 0) 
        {
            s_listening_address = argv[++i];
        } 
        else if (strcmp(argv[i], "-v") == 0) 
        {
            s_debug_level = atoi(argv[++i]);
        } 
        else 
        {
            usage(argv[0]);
        }
    }

    // Root directory must not contain double dots. Make it absolute
    // Do the conversion only if the root dir spec does not contain overrides
    if (strchr(s_root_dir, ',') == NULL) 
    {
        realpath(s_root_dir, path);
        s_root_dir = path;
    }

    // Initialise stuff
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
    mg_log_set(s_debug_level);
    mg_mgr_init(&mgr);

    if ((c = mg_http_listen(&mgr, s_listening_address, cb, &mgr)) == NULL) 
    {
        MG_ERROR(("Cannot listen on %s. Use http://ADDR:PORT or :PORT", s_listening_address));
        exit(EXIT_FAILURE);
    }

    if (mg_casecmp(s_enable_hexdump, "yes") == 0) 
    {
        c->is_hexdumping = 1;
    }

    // Start infinite event loop
    MG_INFO(("Mongoose version : v%s", MG_VERSION));
    MG_INFO(("Listening on     : %s", s_listening_address));
    MG_INFO(("Web root         : [%s]", s_root_dir));
    
    while (s_signo == 0) 
    {
        mg_mgr_poll(&mgr, 1000);
    }

    mg_mgr_free(&mgr);
    MG_INFO(("Exiting on signal %d", s_signo));

    return 0;
}

在实际使用的时候需要注意 struct mg_str 结构体,如 mg_http_message 中的 method, uri, query, proto 等,代码里我只是好奇地想打印一下这些数据,然而结果并不是我想要的,如:

Mongoose http server 例子,# Mongoose,http,c++

        MG_INFO(("method(%d): %s, uri(%d): %s, query(%d): %s, proto(%d): %s", hm->method.len, hm->method.ptr, hm->uri.len, hm->uri.ptr, hm->query.len, hm->query.ptr, 
                hm->proto.len, hm->proto.ptr));
        MG_INFO(("method ptr: %p, uri ptr: %p, query ptr: %p, proto ptr: %p\n", hm->method.ptr, hm->uri.ptr, hm->query.ptr, hm->proto.ptr));

打印 mg_str 的时候使用了其 ptr 指针,而打印出这些指针可以看到它们指向的是连续的一个地址:

[2023/08/10 14:52:21 510890 Info] main.cpp:32:cb   method ptr: 0x1f30580, uri ptr: 0x1f30584, query ptr: 0x0, proto ptr: 0x1f30586

Mongoose http server 例子,# Mongoose,http,c++

0x1f30580 + 3(method 的长度) + 1(一个空格) = 0x1f30584,0x1f30584 + 1(uri的长度)+1(一个空格) = 0x1f30586。

使用了 std::string 

        std::string method(hm->method.ptr, hm->method.len);
        std::string uri(hm->uri.ptr, hm->uri.len);
        std::string proto(hm->proto.ptr, hm->proto.len);
        MG_INFO(("method: %s, uri: %s, proto: %s\n", method.c_str(), uri.c_str(), proto.c_str()));

 

Mongoose http server 例子,# Mongoose,http,c++文章来源地址https://www.toymoban.com/news/detail-699946.html

到了这里,关于Mongoose http server 例子的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • mongoose 解析接口参数

    mongoose 查询 这些参数可以放在链接里面 码云: node-mongodb

    2024年02月13日
    浏览(30)
  • 【http-server】http-server的安装、前端使用http-server启动本地dist文件服务:

    一、http-server 简介: http-server 是一个简单的零配置的命令行 http服务器,它足够强大便于生产和使用,用于本地测试和开发。 有时候我们打开一个文档使用file协议打开的时候,不能发送ajax请求,只能使用http协议才能请求资源,具体的区别大家可以去参考[这篇文档] (www.cnblo

    2024年02月16日
    浏览(45)
  • 路由配置与mongoose模型构建

    本文,我们以用户最简单的用户模块为例,介绍 Express 的路由,以及 mongoose 的模型配置知识。 一个简单的用户模块至少应包括:登录页、注册页、用户中心页(用户信息),三者之间的关系如下图所示: 在 Express 框架下,创建路由非常的简单,我们只需要简单的使用 expre

    2024年01月18日
    浏览(28)
  • mongoose安装和使用(超详细)

    介绍 Mongoose 是一个让我们可以通过Node来操作MongoDB数据库的一个模块 Mongoose 是一个对象文档模型(ODM)库,它是对Node原生的MongoDB模块进行了进一步的优化封装 大多数情况下,他被用来把结构化的模式应用到一个MongoDB集合,并提供了验证和类型装换等好处 基于MongoDB驱动,通

    2024年01月17日
    浏览(27)
  • node教程(四)Mongodb+mongoose

    1.1Mongodb是什么? Mongodb是一个基于分布式文件存储的数据库 1.2数据库是什么? 数据库是按照数据结构来组织、存储和管理数据的应用程序。 1.3数据库的作用 主要作用就是管理数据,对数据进行增删改查 1.4数据库管理数据的特点 相比于纯文件,数据库管理数据具有如下特点

    2024年02月05日
    浏览(47)
  • python -m http.server 迅速搭建本地任意目录http.server服务器

    目录 问题描述 解决办法 在工作中,我们经常遇到文件传输这样的事情,小文件传输,一般使用QQ或者微信就能满足,但当传输文件几百MB或者几十G时,这种传输效率就有点捉襟见肘;同时,我们也可以用U盘或者移动硬盘进行拷贝,但偶尔移动硬盘满了或者没有携带时候,就

    2023年04月13日
    浏览(59)
  • python:http.server --- HTTP 服务器

    HTTPServer 是 socketserver.TCPServer 的一个子类。它会创建和侦听 HTTP 套接字,并将请求分发给处理程序。创建和运行 HTTP 服务器的代码类似如下所示: 该类基于 TCPServer 类,并在实例变量 server_name 和 server_port 中保存 HTTP 服务器地址。处理程序可通过实例变量 server 访问 HTTP 服务器

    2024年02月08日
    浏览(41)
  • Python开启Http Server

    用 Python 部署了一个具有 FTP 功能的服务器,电脑在局域网内通过 FTP 下载想要传输的文件。 注:这种方法不仅在自己家的路由器上可行,亲测在下面两种场景也可行: 需要用手机验证码连接的公共 WIFI 上; 用手机开热点,然后用手机访问部署在笔记本上的 FTP 服务器。 直接

    2024年02月07日
    浏览(34)
  • 在nodejs中使用Mongoose和MongoDB实现curd操作

    在 Node.js 中,数据库被用来存储和检索 Web 应用程序的数据。它们是构建动态和可伸缩应用程序的重要组成部分。 Node.js 提供了各种模块和包,可以与数据库一起工作,如 MySQL 、 PostgreSQL 、 MongoDB 等。它们允许开发人员使用各种操作来存储、查询和操作数据,例如创建、读取、

    2024年02月06日
    浏览(37)
  • [Python http.server] 搭建http服务器用于下载/上传文件

    动机: 笔者需测试bs架构下的文件上传与下载性能,故想通过Python搭建http服务器并实现客户端与服务器之间的文件上传和下载需求 难点: 这应该是很基础的东西,不过笔者之前未接触过http编程,谨在此记录下学习的过程,可能不是最优解 方法: 在服务器端部署html页面,并

    2024年02月11日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包