You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Rainer Jung <ra...@kippdata.de> on 2007/08/08 11:46:53 UTC

Re: ajp through ProxyPass is sending HTTP HEAD requests as HTTPGET to servlets.

Hi Chad,

yes, it looks like that's a bug in mod_proxy_ajp. You should log a bug 
in bugzilla for httpd. I checked the code for Apache httpd 2.2.4 and 
also shortly for 2.2.x head and trunk.

The situation is as follows (you might include this in the bug description):

Apache httpd decodes HTTP methods as method_number. HTTP HEAD and GET 
get the same method_number. To make HEAD distinguishable form GET, 
adiitionally header_only gets set for a HEAD request.

mod_proxy_ajp only decodes the method_number and doesn't check the 
header_only flag. So every HEAD request gets forwarded as a GET request.

In order to fix the forwarding, one has to improve 
ajp_marshal_into_msgb() in ajp_header.c and also ap_proxy_ajp_request(9 
in mod_proxy_ajp.c. A patch against 2.2.4 could be close to the 
following (I didn't test, I didn't even compile it):


Index: mod_proxy_ajp.c
===================================================================
--- mod_proxy_ajp.c     (revision 563796)
+++ mod_proxy_ajp.c     (working copy)
@@ -313,6 +313,16 @@
                  break;
              case CMD_AJP13_SEND_BODY_CHUNK:
                  /* AJP13_SEND_BODY_CHUNK: piece of data */
+                if (r->header_only) {
+                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                                 "proxy: header only");
+                    isok = 0;
+                    /* Pass EOS bucket down the filter chain. */
+                    e = apr_bucket_eos_create(r->connection->bucket_alloc);
+                    APR_BRIGADE_INSERT_TAIL(output_brigade, e);
+                    apr_brigade_cleanup(output_brigade);
+                    break;
+                }
                  status = ajp_parse_data(r, conn->data, &size, &buff);
                  if (status == APR_SUCCESS) {
                      if (size == 0) {
Index: ajp_header.c
===================================================================
--- ajp_header.c        (revision 563796)
+++ ajp_header.c        (working copy)
@@ -224,6 +224,9 @@
                 r->method);
          return AJP_EBAD_METHOD;
      }
+    if ((method == SC_M_GET) && r->header_only) {
+        method = SC_M_HEAD;
+    }

      is_ssl = (apr_byte_t) ap_proxy_conn_is_https(r->connection);


Regards,

Rainer

Chad Scholes wrote:
> I am using Apache 2.2.3 and Tomcat 5.0.  I use ProxyPass to ajp to
> send Servlet requests from Apache to Tomcat and for some reason all
> HEAD requests are being sent to my servlets as GET requests.  I
> probably don't have something setup correctly but I don't know what
> would affect the HEAD request.
> 
> My Apache configuration for ProxyPass is set like:
> 
> Alias /qfsearch "/var/lib/qfsearch/docs" <Location "/qfsearch"> Allow
> from all </Location> ProxyPass /qfsearch
> ajp://localhost:9009/qfsearch
> 
> 
> mod_proxy and mod_rewrite are setup as:
> 
> <IfModule mod_proxy.c> <Proxy *> Order deny,allow Deny from all 
> </Proxy> ProxyRequests Off </IfModule>
> 
> <IfModule mod_rewrite.c> RewriteEngine On RewriteLog
> /var/log/apache2/rewrite_log RewriteLogLevel 1 </IfModule>
> 
> 
> In the apache access log the request is getting to apache as a "HEAD"
> request: 137.65.79.137 - - [06/Aug/2007:14:33:45 -0600] "HEAD
> /qfsearch/ClusterServlet?server=qfsearch3.provo.novell.com&type=index&putname=duh&putsubname=qfind.idx&idxdatetime=1186176509000&idxlocation=%2Fvar%2Flib%2Fqfsearch%2FSites%2Fdefault%2Findexes%2Fduh%2F2007-08-03%3B+15.28.29&put=qfind.idx&filesize=11709498&datetime=1186176509000&do=canput
> HTTP/1.1" 503 - "-" "Java/1.5.0"
> 
> 
> However, I have a servlet that overrides the service function and in
> that call request.getMethod() and it is now returning "GET" not
> "HEAD".
> 
> If I call Tomcat directly then everything works fine
> (request.getMethod() returns "HEAD"). This particular section of code
> has been working for years with the JKMount command but now that we
> have changed to the ProxyPass it is not working.  If you have any
> ideas what could be wrong I would appreciate the help!
> 
> Thanks you!! Chad

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: ajp through ProxyPass is sending HTTP HEAD requests as HTTPGET to servlets.

Posted by Jim Jagielski <ji...@jaguNET.com>.
Added as PR: 43060

Thanks for the info and the analysis... I'll take a look
and tune as required.

On Aug 8, 2007, at 5:46 AM, Rainer Jung wrote:

> Hi Chad,
>
> yes, it looks like that's a bug in mod_proxy_ajp. You should log a  
> bug in bugzilla for httpd. I checked the code for Apache httpd  
> 2.2.4 and also shortly for 2.2.x head and trunk.
>
> The situation is as follows (you might include this in the bug  
> description):
>
> Apache httpd decodes HTTP methods as method_number. HTTP HEAD and  
> GET get the same method_number. To make HEAD distinguishable form  
> GET, adiitionally header_only gets set for a HEAD request.
>
> mod_proxy_ajp only decodes the method_number and doesn't check the  
> header_only flag. So every HEAD request gets forwarded as a GET  
> request.
>
> In order to fix the forwarding, one has to improve  
> ajp_marshal_into_msgb() in ajp_header.c and also  
> ap_proxy_ajp_request(9 in mod_proxy_ajp.c. A patch against 2.2.4  
> could be close to the following (I didn't test, I didn't even  
> compile it):
>
>
> Index: mod_proxy_ajp.c
> ===================================================================
> --- mod_proxy_ajp.c     (revision 563796)
> +++ mod_proxy_ajp.c     (working copy)
> @@ -313,6 +313,16 @@
>                  break;
>              case CMD_AJP13_SEND_BODY_CHUNK:
>                  /* AJP13_SEND_BODY_CHUNK: piece of data */
> +                if (r->header_only) {
> +                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r- 
> >server,
> +                                 "proxy: header only");
> +                    isok = 0;
> +                    /* Pass EOS bucket down the filter chain. */
> +                    e = apr_bucket_eos_create(r->connection- 
> >bucket_alloc);
> +                    APR_BRIGADE_INSERT_TAIL(output_brigade, e);
> +                    apr_brigade_cleanup(output_brigade);
> +                    break;
> +                }
>                  status = ajp_parse_data(r, conn->data, &size, &buff);
>                  if (status == APR_SUCCESS) {
>                      if (size == 0) {
> Index: ajp_header.c
> ===================================================================
> --- ajp_header.c        (revision 563796)
> +++ ajp_header.c        (working copy)
> @@ -224,6 +224,9 @@
>                 r->method);
>          return AJP_EBAD_METHOD;
>      }
> +    if ((method == SC_M_GET) && r->header_only) {
> +        method = SC_M_HEAD;
> +    }
>
>      is_ssl = (apr_byte_t) ap_proxy_conn_is_https(r->connection);
>
>
> Regards,
>
> Rainer
>
> Chad Scholes wrote:
>> I am using Apache 2.2.3 and Tomcat 5.0.  I use ProxyPass to ajp to
>> send Servlet requests from Apache to Tomcat and for some reason all
>> HEAD requests are being sent to my servlets as GET requests.  I
>> probably don't have something setup correctly but I don't know what
>> would affect the HEAD request.
>> My Apache configuration for ProxyPass is set like:
>> Alias /qfsearch "/var/lib/qfsearch/docs" <Location "/qfsearch"> Allow
>> from all </Location> ProxyPass /qfsearch
>> ajp://localhost:9009/qfsearch
>> mod_proxy and mod_rewrite are setup as:
>> <IfModule mod_proxy.c> <Proxy *> Order deny,allow Deny from all </ 
>> Proxy> ProxyRequests Off </IfModule>
>> <IfModule mod_rewrite.c> RewriteEngine On RewriteLog
>> /var/log/apache2/rewrite_log RewriteLogLevel 1 </IfModule>
>> In the apache access log the request is getting to apache as a "HEAD"
>> request: 137.65.79.137 - - [06/Aug/2007:14:33:45 -0600] "HEAD
>> /qfsearch/ClusterServlet? 
>> server=qfsearch3.provo.novell.com&type=index&putname=duh&putsubname=q 
>> find.idx&idxdatetime=1186176509000&idxlocation=%2Fvar%2Flib% 
>> 2Fqfsearch%2FSites%2Fdefault%2Findexes%2Fduh%2F2007-08-03%3B 
>> +15.28.29&put=qfind.idx&filesize=11709498&datetime=1186176509000&do=c 
>> anput
>> HTTP/1.1" 503 - "-" "Java/1.5.0"
>> However, I have a servlet that overrides the service function and in
>> that call request.getMethod() and it is now returning "GET" not
>> "HEAD".
>> If I call Tomcat directly then everything works fine
>> (request.getMethod() returns "HEAD"). This particular section of code
>> has been working for years with the JKMount command but now that we
>> have changed to the ProxyPass it is not working.  If you have any
>> ideas what could be wrong I would appreciate the help!
>> Thanks you!! Chad
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org