You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NGINX模块子请求回调中rc=NGX_AGAIN时的预期处理方式

NGINX子请求回调中NGX_AGAIN且request->out=NULL的处理逻辑

我正在编写一个依赖子请求调用的NGINX模块,在回调函数中遇到了rc=NGX_AGAIN且request->out=NULL的情况,此时无法获取子请求的响应内容,想知道这种情况下回调函数的预期行为是什么?

子请求设置代码

/// Setup callback
ngx_http_request_t *sub_request;
ngx_http_post_subrequest_t *callback = ngx_pcalloc(request->pool, sizeof(ngx_http_post_subrequest_t));
callback->handler = callback_proc;
callback->data = data;
ngx_int_t result = ngx_http_subrequest(request, uri, NULL, &sub_request, callback, NGX_HTTP_SUBREQUEST_IN_MEMORY);

回调处理函数代码

static ngx_int_t
callback_proc(ngx_http_request_t *request, void *data, ngx_int_t rc) {
    // unbox and sanity check    
    data->value->len = r->out->buf->last - r->out->buf->pos; // <<-- SIGSEV because r->out is NULL
    data->value->data = r->out->buf->pos;
    return rc;
}

核心结论

当回调函数收到NGX_AGAIN返回码时,意味着子请求尚未完成处理,此时request->out为NULL是正常现象,回调函数需要直接返回NGX_AGAIN,绝对不能尝试访问request->out相关的响应数据。

详细解释

  1. NGX_AGAIN的含义:在NGINX子请求机制中,NGX_AGAIN表示子请求的IO操作仍在进行,响应内容还未生成完毕。此时触发回调只是通知你子请求处于处理中状态,而非已经完成。
  2. request->out为NULL的原因:只有当子请求完全处理完成(比如返回NGX_OK或其他表示完成的状态码)时,NGINX才会把响应内容填充到request->out链表中。子请求未完成时,这个字段自然为空。
  3. 回调的正确行为:
    • 直接返回NGX_AGAIN,不做任何读取响应的操作,避免空指针访问导致崩溃(如你代码中出现的SIGSEGV)。
    • 无需额外的清理或资源释放操作,NGINX会在子请求后续的处理流程中再次触发该回调,直到子请求完成。

代码修复建议

修改回调函数,先判断返回码,仅当子请求完成后再处理响应数据:

static ngx_int_t
callback_proc(ngx_http_request_t *r, void *data, ngx_int_t rc) {
    // 子请求未完成,直接返回
    if (rc == NGX_AGAIN) {
        return rc;
    }

    // 子请求完成后,安全读取响应
    if (r->out != NULL && r->out->buf != NULL) {
        data->value->len = r->out->buf->last - r->out->buf->pos;
        data->value->data = r->out->buf->pos;
    }

    return rc;
}

内容的提问来源于stack exchange,提问作者dvhh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 02:51:15