您的位置:首页 > 运维架构 > Nginx

nginx模块开发 post请求处理

2014-07-18 17:13 513 查看
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,仅供参考。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: