ngxin处理post请求的handler

本文介绍了一种在Nginx中处理POST请求的方法,包括如何通过自定义模块实现特定的POST请求处理逻辑,以及如何读取POST请求的数据并进行响应。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 在主handler中,判断如果是POST请求,转向一个post_handler,因为在不同事件中需要回调用这个post_handler,所以不要在主handler中处理。

2.因为其它事件回调这个post_hander时只能传入request,所以不要传入out,应该把out放在一个自己定义的context中

所以主handler中逻辑应该是

       if (r->method == NGX_HTTP_POST) {
            ctx = ngx_http_get_module_ctx(r, ngx_module_test);
            if (ctx == NULL) {
                ctx = ngx_pcalloc(r->pool, sizeof (ngx_test_request_ctx_t));
                if (ctx == NULL) {
                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate request context.");
                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
                }
                ctx->post_read_okay = 0;
                ctx->request_out = &out;
                ngx_http_set_ctx(r, ctx, ngx_module_test);
            }
            return ngx_test_post_handler(r);

        }


3.out从外部传入是为了和get等方法统一处理,也可以在这个post_handler要输出的时候再申请一个内存池作

static ngx_int_t ngx_test_post_handler(ngx_http_request_t *r) {

    ngx_int_t rc;
    ngx_test_request_ctx_t *ctx;
    ngx_str_t input;
    ngx_chain_t * out;
    u_char * content;
    content = (u_char *) "This is a post demo handler for nginx.";

    ctx = ngx_http_get_module_ctx(r, ngx_module_test);
    if (ctx == NULL) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate response buffer.");
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    if (!ctx->post_read_okay) {
        rc = ngx_http_read_client_request_body(r, ngx_test_post_read_request_body_handler);
       //ngx_test_post_read_request_body_handler只能有一个参数r,它又需要回调post_handler,

       //所以它也只能传一个参数给post_handler,所以上面的out被放到ctx中。


        if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
            return rc;
        }
        return NGX_DONE;
    }

    // get input request body
    input = ngx_test_post_get_requst_body(r); //这个方法可以放在动态库中处理
    if (input.len == 0) {
        return NGX_DECLINED;
    }
    
    printf("post content:%s\n",(char* )input.data);

    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 = ngx_strlen(content);

    out = ctx->request_out;
    out->buf->pos = content;
    out->buf->last = content + (ngx_strlen(content));
    out->buf->memory = 1;
    out->buf->last_buf = 1;

    ngx_http_send_header(r);
    return ngx_http_output_filter(r, out);
}

static void ngx_test_post_read_request_body_handler(ngx_http_request_t *r) {
    ngx_test_request_ctx_t *ctx;
    ctx = ngx_http_get_module_ctx(r, ngx_module_test);

    if (ctx == NULL) {
        return ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
    }
    ctx->post_read_okay = 1;
    ngx_http_finalize_request(r, ngx_test_post_handler(r));
}



static ngx_str_t ngx_test_post_get_requst_body(ngx_http_request_t *r) {
    u_char *p;
    u_char *data;
    size_t len;
    ngx_buf_t *buf, *next;
    ngx_chain_t *cl;
    ngx_str_t body = ngx_null_string;
    if (r->request_body == NULL
            || r->request_body->bufs == NULL) {
        return body;
    }
    if (r->request_body->temp_file) {
        printf("Please read the content from file: %s\n", (char*) r->request_body->temp_file->file.name.data);
        body = r->request_body->temp_file->file.name;
        return body;
    } else {

        cl = r->request_body->bufs;

        buf = cl->buf;

        if (cl->next == NULL) {
            len = (buf->last - buf->pos);
            p = ngx_pnalloc(r->pool, len + 1);
            if (p == NULL) {
                return body;
            }
            data = p;
            ngx_memcpy(p, buf->pos, len);
            data[len] = 0;

        } else {
            next = cl->next->buf;
            len = (buf->last - buf->pos) + (next->last - next->pos);
            p = ngx_pnalloc(r->pool, len + 1);
            data = p;
            if (p == NULL) {
                return body;
            }
            p = ngx_cpymem(p, buf->pos, buf->last - buf->pos);
            ngx_memcpy(p, next->pos, next->last - next->pos);
            data[len] = 0;
        }
    }

    body.len = len;
    body.data = data;
    return body;
}

处理Web服务器时,静态文件如HTML、CSS、JavaScript等,默认情况下通常只能处理GET请求,而不是POST请求。如果需要让Nginx支持静态文件处理POST请求,可以按照以下步骤修改Nginx的配置文件:首先,定位到Nginx的配置文件`nginx.conf`,在`http`、`server`或`location`块中添加相应的配置代码。这里提供一个基本的配置示例: 参考资源链接:[解决Nginx静态文件POST请求返回405错误](https://wenku.csdn.net/doc/6412b787be7fbd1778d4a9f8?spm=1055.2569.3001.10343) ```nginx server { listen 80; server_***; root /var/www/html; index index.html; if ($request_method = POST) { set $allow_post 1; } location / { try_files $uri $uri/ @post_handler; } location @post_handler { if ($allow_post = 1) { rewrite ^(.*)$ $1 break; return 200; } return 405; # 对于非POST请求,仍然返回405错误 } } ``` 在这个配置中,我们使用`if`指令检查请求方法是否为POST。如果是POST请求,我们将设置一个变量`$allow_post`为1,然后使用`location @post_handler`块来处理POST请求。在这里,如果`$allow_post`为1,我们通过重写规则和返回状态码200来模拟成功处理POST请求。对于非POST请求,我们返回405状态码,表明该方法不被允许。请注意,这种做法虽然可以解决问题,但可能会引入安全风险。因此,在实际应用中应根据具体需求谨慎使用,并确保系统的安全策略得到维护。为了深入理解Nginx的配置和处理HTTP请求的机制,建议阅读《解决Nginx静态文件POST请求返回405错误》,这本书详细解释了Nginx处理静态文件POST请求和405错误的配置方法及其背后的原因,帮助读者全面掌握相关知识。 参考资源链接:[解决Nginx静态文件POST请求返回405错误](https://wenku.csdn.net/doc/6412b787be7fbd1778d4a9f8?spm=1055.2569.3001.10343)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值