nginx模块开发 post请求处理

来源:互联网 发布:mtkoala男友知乎 编辑:程序博客网 时间:2024/06/13 21:16

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<string> temp;
    int para_count = asplit(post_data,"&",temp);   //asplit这个函数是一个分割函数
    for (vector<string>::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<string> & 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,仅供参考。

0 0