static ngx_int_t mytest_process_status_line(ngx_http_request_t *r) {
	size_t len;
	ngx_int_t rc;
	ngx_http_upstream_t *u;

	ngx_http_mytest_ctx_t* ctx = ngx_http_get_module_ctx(r,
			ngx_http_mytest_module);
	if (ctx == NULL)
		return NGX_ERROR;
	u = r->upstream;
	rc = ngx_http_parse_status_line(r, &u->buffer, &ctx->status);//解析HTTP响应行
	if (rc == NGX_AGAIN)
		return rc;
	if (rc == NGX_ERROR) {
		ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
				"[jseanj] upstream sent no valid HTTP/1.0 header");
		r->http_version = NGX_HTTP_VERSION_9;
		u->state->status = NGX_HTTP_OK;
		return NGX_OK;
	}
	if (u->state)
		u->state->status = ctx->status.code;
	u->headers_in.status_n = ctx->status.code;
	len = ctx->status.end - ctx->status.start;
	u->headers_in.status_line.len = len;
	u->headers_in.status_line.data = ngx_pnalloc(r->pool, len);
	if (u->headers_in.status_line.data == NULL)
		return NGX_ERROR;
	ngx_memcpy(u->headers_in.status_line.data, ctx->status.start, len);
	u->process_header = mytest_upstream_process_header;
	return mytest_upstream_process_header(r);
}
static ngx_int_t
ngx_http_scgi_process_status_line(ngx_http_request_t *r)
{
    size_t                len;
    ngx_int_t             rc;
    ngx_http_status_t    *status;
    ngx_http_upstream_t  *u;

    status = ngx_http_get_module_ctx(r, ngx_http_scgi_module);

    if (status == NULL) {
        return NGX_ERROR;
    }

    u = r->upstream;

    rc = ngx_http_parse_status_line(r, &u->buffer, status);

    if (rc == NGX_AGAIN) {
        return rc;
    }

    if (rc == NGX_ERROR) {

        r->http_version = NGX_HTTP_VERSION_9;

        u->process_header = ngx_http_scgi_process_header;

        return ngx_http_scgi_process_header(r);
    }

    if (u->state) {
        u->state->status = status->code;
    }

    u->headers_in.status_n = status->code;

    len = status->end - status->start;
    u->headers_in.status_line.len = len;

    u->headers_in.status_line.data = ngx_pnalloc(r->pool, len);
    if (u->headers_in.status_line.data == NULL) {
        return NGX_ERROR;
    }

    ngx_memcpy(u->headers_in.status_line.data, status->start, len);

    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "http scgi status %ui \"%V\"",
                   u->headers_in.status_n, &u->headers_in.status_line);

    u->process_header = ngx_http_scgi_process_header;

    return ngx_http_scgi_process_header(r);
}
Exemplo n.º 3
0
// reference: ngx_http_proxy_process_status_line
ngx_int_t ngx_http_fetch_decode(ngx_http_request_t *r)
{
    ngx_http_fetch_ctx_t * ctx = ngx_http_fetch_get_module_ctx(r);
    if (!ctx)
    {
        return NGX_ERROR;
    }

    ngx_http_upstream_t * u = r->upstream;

    ngx_int_t rc = ngx_http_parse_status_line(r, &u->buffer, &ctx->status);

    if (rc == NGX_AGAIN)
    {
        return rc;
    }

    if (rc == NGX_ERROR)
    {
        r->http_version = NGX_HTTP_VERSION_9;
        u->state->status = NGX_HTTP_OK;
        u->headers_in.connection_close = 1;

        return NGX_OK;
    }

    if (u->state && u->state->status == 0)
    {
        u->state->status = ctx->status.code;
    }

    u->headers_in.status_n = ctx->status.code;

    size_t len = ctx->status.end - ctx->status.start;
    u->headers_in.status_line.len = len;

    u->headers_in.status_line.data = ngx_pnalloc(r->pool, len);
    if (!u->headers_in.status_line.data)
    {
        return NGX_ERROR;
    }

    ngx_memcpy(u->headers_in.status_line.data, ctx->status.start, len);

    if (ctx->status.http_version < NGX_HTTP_VERSION_11)
    {
        u->headers_in.connection_close = 1;
    }

    u->process_header = __decode_header;

    return __decode_header(r);
}
Exemplo n.º 4
0
ngx_int_t
ngx_http_srcache_process_status_line(ngx_http_request_t *r, ngx_buf_t *b)
{
    ngx_int_t                    rc;
    ngx_http_srcache_ctx_t      *ctx;
    ngx_http_request_t          *pr;
    ngx_http_srcache_loc_conf_t *conf;

    ctx = ngx_http_get_module_ctx(r, ngx_http_srcache_filter_module);

    rc = ngx_http_parse_status_line(r, b, &ctx->status);

    if (rc == NGX_AGAIN) {
        return NGX_AGAIN;
    }

    if (rc == NGX_ERROR) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "srcache_fetch: cache sent invalid status line");
        return NGX_ERROR;
    }

    /* rc == NGX_OK */

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "srcache_fetch status line done");

    pr = r->parent;
    pr->headers_out.status = ctx->status.code;

    ctx->process_header = ngx_http_srcache_process_header;

    conf = ngx_http_get_module_loc_conf(pr, ngx_http_srcache_filter_module);

    dd("header buffer size: %d", (int) conf->header_buf_size);

    ctx->header_buf = ngx_create_temp_buf(r->pool, conf->header_buf_size);
    if (ctx->header_buf == NULL) {
        return NGX_ERROR;
    }

    if (b->pos == b->last) {
        return NGX_AGAIN;
    }

    return ngx_http_srcache_process_header(r, b);
}
static ngx_int_t
ngx_http_poller_process_status_line(ngx_http_request_t *r)
{
  ngx_int_t             rc;
  ngx_http_upstream_t  *u;
  ngx_http_poller_t    *poller;

  poller = ngx_http_get_module_ctx(r, ngx_http_poller_module);
  if (poller == NULL) {
    return NGX_ERROR;
  }

  u = r->upstream;

  rc = ngx_http_parse_status_line(r, &u->buffer, &poller->status);
  if (rc == NGX_AGAIN) {
    return rc;
  }

  if (rc == NGX_ERROR) {
    if (u->state) {
      u->state->status = NGX_HTTP_OK;
    }
    u->headers_in.connection_close = 1;

    return NGX_OK;
  }

  if (u->state) {
    u->state->status = poller->status.code;
  }
  u->headers_in.connection_close = 1;

  if (poller->handler.status != NULL) {
    poller->handler.status(r, &poller->status);
  }

  ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
		 "[poller] %V: status = %uD",
		 &poller->name, (uint32_t)poller->status.code);

  r->upstream->process_header = ngx_http_poller_process_header;

  return ngx_http_poller_process_header(r);
}
static ngx_int_t
mytest_process_status_line(ngx_http_request_t *r)
{
	size_t len;
	ngx_int_t rc;
	ngx_http_upstream_t *u;
	//上下文中才会保存多次解析http响应行的状态,下面首先取出请求的上下文
	ngx_http_mytest_ctx_t*	ctx = ngx_http_get_module_ctx(r,ngx_http_mytest_module);
	if(ctx == NULL){
		return NGX_ERROR;
	}
	u = r->upstream;
	/* http框架提供的ngx_http_parse_status_line方法可以解析http响应行,它的输入就是收到的
	 * 字符流和上下文中的ngx_http_status_t结构
	*/
	rc = ngx_http_parse_status_line(r,&u->buffer,&ctx->status);
	if(rc == NGX_AGAIN){
		return rc;
	}
	if(rc == NGX_ERROR){
		ngx_log_error(NGX_LOG_ERR,r->connection->log,0,"upstream sent no valid HTTP/1.0 header");
		r->http_version = NGX_HTTP_VERSION_9;
		u->state->status = NGX_HTTP_OK;

		return NGX_OK;
	}
	//将解析到完整的http响应行时,会做一些简单的赋值操作,将解析出的信息设置到r->upstream->headers_in结构体中
	if(u->state){
		u->state->status = ctx->status.code;
	}
	u->headers_in.status_n = ctx->status.code;

	len = ctx->status.end - ctx->status.start;
	u->headers_in.status_line.len = len;

	u->headers_in.status_line.data = ngx_pnalloc(r->pool,len);
	if(u->headers_in.status_line.data == NULL){
		return NGX_ERROR;
	}
	ngx_memcpy(u->headers_in.status_line.data,ctx->status.start,len);
	u->process_header = mytest_upstream_process_header;
	return mytest_upstream_process_header(r);
}
//解析HTTP响应行
static ngx_int_t
mytest_process_status_line(ngx_http_request_t *r)
{
	size_t		len;
	ngx_int_t	rc;
	ngx_http_upstream_t	*u;

	//上下文中才会保存多次解析HTTP响应行的状态,下面首先取出请求的上下文
	ngx_http_mytest_ctx_t * ctx = ngx_http_get_module_ctx(r, ngx_http_mytest_module);
	if(ctx == NULL){
		return NGX_ERROR;
	}

	u = r->upstream;

	//HTTP框架提供的ngx_http_parse_status_line方法可以解析HTTP响应行,它的输入就是收到
	//的字符流和上下文中的ngx_http_status_t结构
	rc = ngx_http_parse_status_line(r, &u->buffer, &ctx->status);
	
	//返回NGX_AGAIN时,表示还没有解析出完整的HTTP响应行,需要接收更多的字符流在进行解析
	if(rc == NGX_AGAIN){
		return rc;
	}

	//返回NGX_ERROR时,表示没有接收到合法的HTTP响应行
	if(rc == NGX_ERROR){
		ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
				"upstream sent no valid HTTP/1.0 header");

		r->http_version = NGX_HTTP_VERSION_9;
		u->state->status = NGX_HTTP_OK;
		return NGX_OK;
	}

	//以下表示在解析到完整的HTTP响应行时,会做一些简单的赋值操作,将解析出的信息设置到
	//r->upstream->headers_in结构体中。当upstream解析完所有的包头时,会把headers_in中的
	//成员设置到将要向下游发送的r->headers_out结构体中,也就是说,现在用户向headers_in中
	//设置的信息,最终都会发往下游客户端。为什么不直接设置r->headers_out而要多次一举呢?
	//因为upstream希望能够按照ngx_http_upstream_conf_t配置结构体中的hide_headers等成员对
	//发往下游的响应头部做统一处理
	if(u->state){
		u->state->status = ctx->status.code;
	}

	u->headers_in.status_n = ctx->status.code;
	
	len = ctx->status.end - ctx->status.start;
	u->headers_in.status_line.len = len;
	
	u->headers_in.status_line.data = ngx_pnalloc(r->pool, len);
	if(u->headers_in.status_line.data == NULL){
		return NGX_ERROR;
	}

	ngx_memcpy(u->headers_in.status_line.data, ctx->status.start, len);

	//下一步将开始解析HTTP头部。设置process_header回调方法为mytest_upstream_process_header,
	//之后在再收到的新字符流将由mytest_upstream_process_header操作
	u->process_header = mytest_upstream_process_header;

	return mytest_upstream_process_header(r);

}
Exemplo n.º 8
0
static ngx_int_t
mytest_process_status_line(ngx_http_request_t *r)
{
    size_t                 len;
    ngx_int_t              rc;
    ngx_http_upstream_t   *u;

    //上下文中才会保存多次解析http响应行的状态,首先取出请求的上下文
    ngx_http_mytest_ctx_t* ctx = ngx_http_get_module_ctx(r, ngx_http_mytest_module);
    if (ctx == NULL)
    {
        return NGX_ERROR;
    }

    u = r->upstream;

    //http框架提供的ngx_http_parse_status_line方法可以解析http
//响应行,它的输入就是收到的字符流和上下文中的ngx_http_status_t结构
    rc = ngx_http_parse_status_line(r, &u->buffer, &ctx->status);
    //返回NGX_AGAIN表示还没有解析出完整的http响应行,需要接收更多的
//字符流再来解析
    if (rc == NGX_AGAIN)
    {
        return rc;
    }
    //返回NGX_ERROR则没有接收到合法的http响应行
    if (rc == NGX_ERROR)
    {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "upstream sent no valid HTTP/1.0 header");

        r->http_version = NGX_HTTP_VERSION_9;
        u->state->status = NGX_HTTP_OK;

        return NGX_OK;
    }

    //以下表示解析到完整的http响应行,这时会做一些简单的赋值操作,将解析出
//的信息设置到r->upstream->headers_in结构体中,upstream解析完所
//有的包头时,就会把headers_in中的成员设置到将要向下游发送的
//r->headers_out结构体中,也就是说,现在我们向headers_in中设置的
//信息,最终都会发往下游客户端。为什么不是直接设置r->headers_out而要
//这样多此一举呢?这是因为upstream希望能够按照
//ngx_http_upstream_conf_t配置结构体中的hide_headers等成员对
//发往下游的响应头部做统一处理
    if (u->state)
    {
        u->state->status = ctx->status.code;
    }

    u->headers_in.status_n = ctx->status.code;

    len = ctx->status.end - ctx->status.start;
    u->headers_in.status_line.len = len;

    u->headers_in.status_line.data = ngx_pnalloc(r->pool, len);
    if (u->headers_in.status_line.data == NULL)
    {
        return NGX_ERROR;
    }

    ngx_memcpy(u->headers_in.status_line.data, ctx->status.start, len);

    //下一步将开始解析http头部,设置process_header回调方法为
//mytest_upstream_process_header,
//之后再收到的新字符流将由mytest_upstream_process_header解析
    u->process_header = mytest_upstream_process_header;

    //如果本次收到的字符流除了http响应行外,还有多余的字符,
//将由mytest_upstream_process_header方法解析
    return mytest_upstream_process_header(r);
}