You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Chad Scholes <CS...@novell.com> on 2007/08/08 01:11:13 UTC

ajp through ProxyPass is sending HTTP HEAD requests as HTTP GET to servlets.

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


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

Posted by Rainer Jung <ra...@kippdata.de>.
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