Mongoose 利用实现HTTP服务

嘛….

留神:那里是运用mongoose完毕HTTP服务,非数据库使用。

近些年由于须求动用HTTP服务端,原先是选取的Qt框架达成的HTTP服务端,然后发现有个别欠缺导致本人只得吐弃那几个框架,也不是全然遗弃,只是HTTP服务端那里不再选择Qt,用Qt做高并发真的有些倒霉。

下一场毅然的选拔了mongoose那么些框架,首假如据他们说那东西
嵌入到代码中那三个有利于。下载之后发现果然就贰个 h文件和cpp文件。。

 

于是乎从头切磋那几个框架,依据mongoose
用户手册再添加一堆实例教程,基本上写了三个类
实行操作封装(并不是全然的包装了)

 

MoHttp.h文件
主要是实现mongoose框架的基本 变量获取。注意里面有重载,主要是为了方便使用。

#define _MOHTTP_H
#ifdef _MOHTTP_H


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

using namespace std;

const int CHAR_HTTP_VAR_MAX = 128;
const int CHAR_HTTP_COOKIE_MAX = 400;


class MoHttp
{
private:
    struct http_message *hm = NULL;

public:
    MoHttp(struct http_message *);
    ~MoHttp();
        int getGetVar(const char*, char*) const;    //获取变量
        void getGetVar(const char*, string &) const;    //获取变量
        int getPostVar(const char*, char*) const;    //获取变量
        void getPostVar(const char*, string &) const;    //获取变量
        int getCookie(const char*, char*) const;    //获取Cookie
        void getCookie(const char*, string &) const;    //获取Cookie
     int Model() const;    //判断当前模式 POST/GET    1为 GET 否则为0
};

#endif

 

MoHttp.cpp
实现各类方法。

#include "MoHttp.h"



MoHttp::MoHttp(struct http_message * hm = NULL)
{
    this->hm = hm;
}

int MoHttp::getGetVar(const char* name, char* var) const
{
    memset(var, '\0', sizeof(var));
    if (hm == NULL || name == NULL || hm->query_string.p == NULL)return -1; 
    return mg_get_http_var(&hm->query_string, name, var, sizeof(var));        //获取变量
}

void MoHttp::getGetVar(const char* name, string & str) const
{
    str = "";
    char var[CHAR_HTTP_VAR_MAX];
    var[0] = '\0';
    if (hm == NULL || name == NULL || hm->query_string.p == NULL)return;
    mg_get_http_var(&hm->query_string, name, var, sizeof(var));        //获取变量
    if (var[0] == '\0'){
        return;
    }
    str = var;    //如果数据正确
}

int MoHttp::getPostVar(const char* name, char* var) const
{
    memset(var,'\0',sizeof(var));
    if (hm == NULL || name == NULL || hm->body.p == NULL)return -1; 
    return mg_get_http_var(&hm->body, name, var, sizeof(var));        //获取变量
}

void MoHttp::getPostVar(const char* name, string & str) const
{
    str = "";
    char var[CHAR_HTTP_VAR_MAX];
    var[0] = '\0';
    if (hm == NULL || name == NULL || hm->query_string.p == NULL)return;
    mg_get_http_var(&hm->body, name, var, sizeof(var));        //获取变量
    if (var[0] == '\0'){
        return;
    }
    str = var;    //如果数据正确
}


int MoHttp::Model() const
{

    if (hm == NULL || hm->method.p == NULL)return -1;    //数据错误
    if (mg_vcmp(&hm->method, "POST") != 0)return 1;
    return 0;

}
int MoHttp::getCookie(const char * name, char * var) const
{
    memset(var, '\0', sizeof(var));
    //mg_printf(nc, "Set-Cookie: %s=%s; path=/\r\n", "wwe", "123456789");    发送Cookie
    if (hm == NULL) return -999;
    struct mg_str *cookie_header = mg_get_http_header(hm, "cookie");    //获取Cookie 整条
    if (cookie_header == NULL) return -999; //<0
    return mg_http_parse_header(cookie_header, name, var, sizeof(var));
}

void MoHttp::getCookie(const char* name, string & str) const
{
    str = "";
    char var[CHAR_HTTP_COOKIE_MAX];    //Cookie 最大更长
    var[0] = '\0';
    if (hm == NULL || name == NULL || hm->query_string.p == NULL)return;
    struct mg_str *cookie_header = mg_get_http_header(hm, "cookie");    //获取Cookie 整条
    if (cookie_header == NULL) return;
    mg_http_parse_header(cookie_header, name, var, sizeof(var));
    if (var[0] == '\0'){
        return;
    }
    str = var;    //如果数据正确
}

MoHttp::~MoHttp()
{

}

 

动用方法:

Mo.cpp(或Main.cpp)

// Copyright (c) 2016 by Suwings
// All rights reserved


#include <iostream>
#include "MoHttp.h"

using namespace std;

static char *s_http_port = "23333";
static struct mg_serve_http_opts s_http_server_opts;

MoHttp * mo = NULL;


static void ev_handler(struct mg_connection *nc, int ev, void *p) {
    if (ev == MG_EV_HTTP_REQUEST) {                                        //如果是HTTP 请求
        struct http_message *hm = (struct http_message *) p;        //传为
        mo = new MoHttp(hm);                                                    //记得释放内存,实例化 MoHttp
        if (mo->Model()==1){
            //GET
        string w;                            //测试代码    
        mo->getGetVar("user",w);                   //测试代码
        if (w != "")cout << "变量:" << w.c_str() << endl;     //测试代码

        }else{                              //测试代码
            //POST
        }                                 //测试代码
        delete mo;            //释放变量
        mg_serve_http(nc, hm, s_http_server_opts);                        //数据发送
    }
}

int main(void) {
    struct mg_mgr mgr;
    struct mg_connection *nc;
    //struct mg_request_info *ww;
    mg_mgr_init(&mgr, NULL);
    printf("[状态] 服务器已经开启在端口:  %s\n", s_http_port);

    nc = mg_bind(&mgr, s_http_port, ev_handler);
    if (nc == NULL) {
        printf("Failed to create listener\n");
        return 1;
    }

    // Set up HTTP server parameters
    mg_set_protocol_http_websocket(nc);
    s_http_server_opts.document_root = "./www/";  // Serve current directory
    s_http_server_opts.enable_directory_listing = "no";    //Set if show dir
    for (;;) {
        mg_mgr_poll(&mgr, 1000);
    }
    mg_mgr_free(&mgr);

    return 0;
}

 

看了多少个钟头今后,差不三只可以写出如此点东西了。然后本身就一向在想。

不过你有没有发现,要是浏览器就算发送 Ajax 数据复苏,假定逻辑在 C++
代码里面,笔者应该什么设置重临的数据啊?

的确,这几个类也尚未插手 重回的数额,那些题材本人也一直在干扰。

莫不是mongoose 框架都尚未函数是能够设置数据在 body
的?百思不得其解的自己于是去找了一晃 mongoose
文书档案里面的例子,发现了2个Cookie验证的例证,原本小编以为无论怎么也会有设置数据的地方了,可是自己奇怪的发现,是那般的:

 

Cookie_auth.c 例子文件

static void set_session_cookie(struct mg_connection *nc,    
                               const struct session *s) {
  mg_printf(nc, "Set-Cookie: %s=%" INT64_X_FMT "; path=/\r\n",
            SESSION_COOKIE_NAME, s->id);
}

/*
 * If requested via GET, serves the login page.
 * If requested via POST (form submission), checks password and logs user in.
 */
static void login_handler(struct mg_connection *nc, int ev, void *p) {    //主要看这个函数
  struct http_message *hm = (struct http_message *) p;
  if (mg_vcmp(&hm->method, "POST") != 0) {
    /* Serve login.html */
    mg_serve_http(nc, (struct http_message *) p, s_http_server_opts);
  } else {
    /* Perform password check. */
    char user[50], pass[50];
    int ul = mg_get_http_var(&hm->body, "user", user, sizeof(user));  
    int pl = mg_get_http_var(&hm->body, "pass", pass, sizeof(pass));
    if (ul > 0 && pl > 0) {   //如果有数据
      if (check_pass(user, pass)) {  //验证账号和密码 函数无须理会
        struct session *s = create_session(user, hm);   //mg_printf 是直接输出数据,并不是输出到body
        mg_printf(nc, "HTTP/1.0 302 Found\r\n");
        set_session_cookie(nc, s);                  //他是进行了一次跳转,并且直接返回的HTTP头
        mg_printf(nc, "Location: /\r\n"); 
        mg_printf(nc, "\r\nHello, %s!\r\n", s->user);
        //这句是控制台输出
        fprintf(stderr, "%s logged in, sid %" INT64_X_FMT "\n", s->user, s->id);  
      } else {
        mg_printf(nc, "HTTP/1.0 403 Unauthorized\r\n\r\nWrong password.\r\n");
      }
    } else {
      mg_printf(nc, "HTTP/1.0 400 Bad Request\r\n\r\nuser, pass required.\r\n");
    }
    nc->flags |= MG_F_SEND_AND_CLOSE;
  }
  (void) ev;
}

 

看完了后头作者就跟纳闷了,为啥要一贯出口HTTP头?框架难道真的没有提供类似的不二法门吗?

然后尝试了各项函数:

也无果,那一个函数会 输出到 HTTP 响应头以前。

图片 1

 

从而,是否以此框架真的没有 什么设置再次来到的body 的函数呢?

 

一句话来说方今只学到那里,恐怕有哪些地方确实尚未询问。近期先记录下来,等理解明白后再续写。

相关文章