IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]nginx模块开发 post请求处理

    zhoubl668发表于 2014-07-18 17:13:50
    love 0

    nginx可以支持c++直接进行模块插件的开发,对post请求的处理大致如下:

    static ngx_int_t ngx_echo_handler(ngx_http_request_t *r) {

    if (r->method &(NGX_HTTP_POST)) {
    ngx_int_t rc = ngx_http_read_client_request_body(r, ngx_recom_handler);
    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
    return rc;
    }
    return NGX_DONE;
    }

    return NGX_DONE;

    }



    void ngx_recom_handler (ngx_http_request_t *r) {

    key_vv = ngx_http_get_indexed_variable(r,ngx_http_key_index);

    string title;
    string content;
    bool para_r = get_post_para(r, title, content);

    //算法逻辑处理过程

    char dest[65536];//结果字符串

    //............................

    //输出结果整理 end

    ngx_int_t rc;
    ngx_buf_t *b;
    ngx_chain_t out;
    ngx_echo_loc_conf_t *cglcf;
    cglcf = (ngx_echo_loc_conf_t*)ngx_http_get_module_loc_conf(r, ngx_module_echo);
    // 限制请求的方法
    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD| NGX_HTTP_POST))) {
    ngx_http_finalize_request(r,NGX_HTTP_INTERNAL_SERVER_ERROR);
    return ;
    }
    if (r->headers_in.if_modified_since) {
    ngx_http_finalize_request(r,NGX_HTTP_INTERNAL_SERVER_ERROR);
    return ;
    }


    r->headers_out.content_type.len = sizeof("text/html") - 1;
    r->headers_out.content_type.data = (u_char *) "text/html";


    r->headers_out.status = NGX_HTTP_OK; // 发送状态码
    r->headers_out.content_length_n = strlen(dest); // 发送内容长度
    if (r->method == NGX_HTTP_HEAD) {
    rc = ngx_http_send_header(r);


    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
    ngx_http_finalize_request(r,NGX_HTTP_INTERNAL_SERVER_ERROR);
    return ;
    }
    }
    b = (ngx_buf_t*)ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
    if (b == NULL) {
    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate response buffer.");
    ngx_http_finalize_request(r,NGX_HTTP_INTERNAL_SERVER_ERROR);
    return;
    }
    ////////////////////////////////////////////
    // 定义输出
    ////////////////////////////////////////////
    out.buf = b;
    out.next = NULL;
    ////////////////////////////////////////////
    // 给输出复制
    ////////////////////////////////////////////
    b->pos = (u_char*)dest;
    b->last = (u_char*)dest + strlen(dest);


    b->memory = 1;
    b->last_buf = 1;
    rc = ngx_http_send_header(r);


    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
    ngx_http_finalize_request(r,NGX_HTTP_INTERNAL_SERVER_ERROR);
    return ;
    }
    ngx_http_finalize_request(r,ngx_http_output_filter(r, &out;));
    return ;


    }



    static bool get_post_para(ngx_http_request_t *r, string &title;, string &content;)
    {
    //TODO
    if (r->request_body == NULL)
    {
    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "reqeust_body:null");
    return false;
    }
    ngx_chain_t* bufs = r->request_body->bufs;
    ngx_buf_t* buf = NULL;
    uint8_t* data_buf = NULL;
    size_t content_length = 0;
    size_t body_length = 0;

    if ( r->headers_in.content_length == NULL )
    {
    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "r->headers_in.content_length == NULL");
    return false;
    }

    // malloc space for data_buf
    content_length = atoi( (char*)(r->headers_in.content_length->value.data) );
    data_buf = ( uint8_t* )ngx_palloc( r->pool , content_length + 1 );
    size_t buf_length = 0;
    while ( bufs )
    {
    buf = bufs->buf;
    bufs = bufs->next;
    buf_length = buf->last - buf->pos ;
    if( body_length + buf_length > content_length )
    {
    memcpy( data_buf + body_length, buf->pos, content_length - body_length);
    body_length = content_length ;
    break;
    }
    memcpy( data_buf + body_length, buf->pos, buf->last - buf->pos );
    body_length += buf->last - buf->pos;
    }
    if ( body_length )
    {
    data_buf[body_length] = 0;
    }
    string post_data;
    post_data = (char *) data_buf;
    vector temp;
    int para_count = asplit(post_data,"&",temp); //asplit这个函数是一个分割函数
    for (vector
    ::iterator it = temp.begin(); it != temp.end();++it)
    {
    size_t pos = it->find("=");
    if (pos == string::npos || pos == 0 || (pos == it->length()-1))
    continue;
    string key = it->substr(0,pos);
    string value = it->substr(pos+1);
    if (key == "title"){
    title = value;
    }else if(key =="content"){
    content = value;
    }
    }
    return true;

    }




    int asplit(const string& content,const string& del,vector & result)
    {
    result.clear();
    size_t sep_pos = content.find(del);
    int pre = 0;


    if ((int)content.length() == 0) {
    return 0;
    }


    if (sep_pos == string::npos)
    {
    result.push_back(content);
    return 1;
    }
    while (sep_pos != string::npos)
    {
    string kws = content.substr(pre,sep_pos-pre);
    result.push_back(kws);
    pre = sep_pos + del.length();
    sep_pos = content.find(del,pre);
    }
    string kws = content.substr(pre);
    result.push_back(kws);
    return result.size();
    }


    ok,仅供参考。



沪ICP备19023445号-2号
友情链接