On 02/04/2017 09:14 PM, [email protected] wrote:
> Author: druggeri
> Date: Sat Feb  4 20:14:18 2017
> New Revision: 1781701
> 
> URL: http://svn.apache.org/viewvc?rev=1781701&view=rev
> Log:
> Change tactic for PROXY processing in Optional case
> 
> Modified:
>     httpd/httpd/trunk/docs/manual/mod/mod_remoteip.xml
>     httpd/httpd/trunk/modules/metadata/mod_remoteip.c
> 

> Modified: httpd/httpd/trunk/modules/metadata/mod_remoteip.c
> URL: 
> http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/metadata/mod_remoteip.c?rev=1781701&r1=1781700&r2=1781701&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/metadata/mod_remoteip.c (original)
> +++ httpd/httpd/trunk/modules/metadata/mod_remoteip.c Sat Feb  4 20:14:18 2017

> @@ -1085,28 +1091,53 @@ static apr_status_t remoteip_input_filte
>              memcpy(ctx->header + ctx->rcvd, ptr, len);
>              ctx->rcvd += len;
>  
> -            /* Put this bucket into our temporary storage brigade because
> -               we may permit a request without a header. In that case, the
> -               data in the temporary storage brigade just gets copied
> -               to bb_out */
> -            APR_BUCKET_REMOVE(b);
> -            apr_bucket_setaside(b, f->c->pool);
> -            APR_BRIGADE_INSERT_TAIL(ctx->store_bb, b);
> +            apr_bucket_delete(b);
>              psts = HDR_NEED_MORE;
>  
>              if (ctx->version == 0) {
>                  /* reading initial chunk */
>                  if (ctx->rcvd >= MIN_HDR_LEN) {
>                      ctx->version = remoteip_determine_version(f->c, 
> ctx->header);
> -                    if (ctx->version < 0) {
> -                        psts = HDR_MISSING;
> -                    }
> -                    else if (ctx->version == 1) {
> -                        ctx->mode = AP_MODE_GETLINE;
> -                        ctx->need = sizeof(proxy_v1);
> +
> +                    /* We've read enough to know that a header is present. 
> In peek mode
> +                       we purge the bb and can decide to step aside or 
> switch to
> +                       non-speculative read to consume the data */
> +                    if (ctx->peeking) {
> +                        apr_brigade_destroy(ctx->bb);

apr_brigade_cleanup is better instead of destroy and create afterwards.

> +
> +                        if (ctx->version < 0) {
> +                            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c, 
> APLOGNO(03512)
> +                                          "RemoteIPProxyProtocol: PROXY 
> header is missing from "
> +                                          "request. Stepping aside.");
> +                            ctx->bb = NULL;
> +                            ctx->done = 1;
> +                            return ap_get_brigade(f->next, bb_out, mode, 
> block, readbytes);
> +                        }
> +                        else {
> +                            /* Rest ctx to initial values */
> +                            ctx->rcvd = 0;
> +                            ctx->need = MIN_HDR_LEN;
> +                            ctx->version = 0;
> +                            ctx->bb = apr_brigade_create(f->c->pool, 
> f->c->bucket_alloc);
> +                            ctx->done = 0;
> +                            ctx->mode = AP_MODE_READBYTES;
> +                            ctx->peeking = 0;
> +
> +                            ap_get_brigade(f->next, ctx->bb, ctx->mode, 
> block,
> +                                           ctx->need - ctx->rcvd);
> +                        }
>                      }
> -                    else if (ctx->version == 2) {
> -                        ctx->need = MIN_V2_HDR_LEN;
> +                    else {
> +                        if (ctx->version < 0) {
> +                            psts = HDR_MISSING;
> +                        }
> +                        else if (ctx->version == 1) {
> +                            ctx->mode = AP_MODE_GETLINE;
> +                            ctx->need = sizeof(proxy_v1);
> +                        }
> +                        else if (ctx->version == 2) {
> +                            ctx->need = MIN_V2_HDR_LEN;
> +                        }
>                      }
>                  }
>              }


Other comments:

If you are reading in SPECULATIVE mode and renter the filter (e.g. MIN_HDR_LEN 
bytes were not available and you were
reading non blocking) or if you just do a second ap_get_brigade in the outer 
loop, the returned brigade will contain
all the data you had already seen plus potential new data. So you don't need to 
tuck it away in ctx->header. You always
need to examine the whole returned brigade for the header and the brigade 
should become longer with a second
ap_get_brigade. If not and you are in non blocking mode no new data was 
available and you should leave.
Also take care to handle meta buckets correctly. You could probably hit an EOS 
bucket which tells you that no more
data will be delivered.

Regards

RĂ¼diger

Reply via email to