Bug 46678

Summary: Fixed Content-Length using mod_ext_filter with mode=input
Product: Apache httpd-2 Reporter: Cris Webea <criswebea1>
Component: mod_ext_filterAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: NEW ---    
Severity: normal    
Priority: P2    
Version: 2.4.20   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   

Description Cris Webea 2009-02-09 04:49:30 UTC
I wrote an input filter using mod_ext_filter. In the filter "implementation" I get the post data (from stdin) and modify it (to stdout) with no issues. However, after changing the post data, the Content-Length of the request still has the original value. For instance:

Original post data: param1=12345 with Content-Length: 12 
Post data after filter: param1=abcdefghij with Content-Length: 12

Then because the Content-Length is not changed, when the request post data is
received after the filter, it will be truncated to the original Content-Length
size (i.e. would get param1=abcde in the previous example).

The filter implementation is a Java program (speed is not an issue), and this is
how the filter definition looks:

ExtFilterDefine filtername mode=input cmd="/path_to_java/java.exe -classpath
/path_to_java_app com.my.program.Filter"

As you can see, I am not using the PreservesContentLength flag. Also, this is
running on Windows XP, and using Apache 2.2.10 (I already verified and 2.2.11
does not mention anything like this in the release notes). I also tried setting the Content-Length using mod_headers but this cause another problem (would completely remove the post data). 

I am reporting this as a bug, as supposedly not using the PreservesContentLength flag should let the filter change the Content-Length.
Comment 1 Jon Jensen 2009-05-22 13:09:02 UTC
I've confirmed this behavior on Apache 2.2.3 (Debian Etch).

Also noteworthy is this only seems to happen if the request is handled locally. It works fine when using a reverse proxy. For example:

# foo gets replaced with foobarbaz, but content-length is unchanged, resulting
# in possible truncation
ExtFilterDefine foobar mode=output cmd="/bin/sed s/foo/foobarbaz/g"
<Location /my/path>
  SetOutputFilter foobar

# foo gets replaced with foobarbaz and content-length is adjusted accordingly
RewriteEngine On
RewriteRule ^/my/path http://otherserver/my/path [P]
ExtFilterDefine foobar mode=output cmd="/bin/sed s/foo/foobarbaz/g"
<Location /my/path>
  SetOutputFilter foobar