Hello,

I have a client sending chunked requests and configured mod_wsgi to be
in daemon mode.

The request looks like this
POST adsf HTTP/1.1
Host: adsf:adsf
SOAPAction: ""
User-Agent: AAAAAAAAAAAAAAA/4.34
Accept: */*
Content-Type: text/xml
Transfer-Encoding: chunked

56d
<SOAP-ENV:Envelope
 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/";
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";
 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/";
 xmlns:cwmp="urn:dslforum-org:cwmp-1-0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
 xmlns:xsd="http://www.w3.org/2001/XMLSchema";>
<SOAP-ENV:Header>
<cwmp:ID SOAP-ENV:mustUnderstand="1">100</cwmp:ID>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<cwmp:Inform>
 <DeviceId>
  <Manufacturer>AAAAA</Manufacturer>
  <OUI>AAAAAA</OUI>
  <ProductClass>AAAAAAAAAAAA</ProductClass>
  <SerialNumber>AAAAAAAAAAAA</SerialNumber>
 </DeviceId>
 <Event SOAP-ENC:arrayType="cwmp:EventStruct[2]">
  <EventStruct>
   <EventCode>0 BOOTSTRAP</EventCode>
   <CommandKey></CommandKey>
  </EventStruct>
  <EventStruct>
   <EventCode>4 VALUE CHANGE</EventCode>
   <CommandKey></CommandKey>
  </EventStruct>
 </Event>
 <MaxEnvelopes>1</MaxEnvelopes>
 <CurrentTime>2012-04-26T14:02:37</CurrentTime>
 <RetryCount>1</RetryCount>
 <ParameterList SOAP-ENC:arrayType="cwmp:ParameterValueStruct[8]">
  <ParameterValueStruct>
   <Name>InternetGatewayDevice.DeviceSummary</Name>
   <Value xsi:type="xsd:string">InternetGatewayDevice:1.4[](Baseline:
1, EthernetLAN:1, WiFiLAN:1, EthernetWAN:1, ADSLWAN:1, IPPing:1,
DSLDiagnostics:1, Time:1), VoiceService:1.0[1](Endpoint:1, SIPEndpoin
573
t:1)</Value>
  </ParameterValueStruct>
  <ParameterValueStruct>
   <Name>InternetGatewayDevice.DeviceInfo.SpecVersion</Name>
   <Value xsi:type="xsd:string">1.0</Value>
  </ParameterValueStruct>
  <ParameterValueStruct>
   <Name>InternetGatewayDevice.DeviceInfo.HardwareVersion</Name>
   <Value xsi:type="xsd:string">AAAAAAAAAAAA</Value>
  </ParameterValueStruct>
  <ParameterValueStruct>
   <Name>InternetGatewayDevice.DeviceInfo.SoftwareVersion</Name>
   <Value xsi:type="xsd:string">AAAAAAAAAAAAAAAAAAAAAAA</Value>
  </ParameterValueStruct>
  <ParameterValueStruct>
   <Name>InternetGatewayDevice.DeviceInfo.ProvisioningCode</Name>
   <Value xsi:type="xsd:string"></Value>
  </ParameterValueStruct>
  <ParameterValueStruct>
   <Name>InternetGatewayDevice.ManagementServer.ConnectionRequestURL</
Name>
   <Value xsi:type="xsd:string">http://AAAAAAAAAAAAAAAAAA/CWMP/
ConnectionRequest</Value>
  </ParameterValueStruct>
  <ParameterValueStruct>
   <Name>InternetGatewayDevice.ManagementServer.ParameterKey</Name>
   <Value xsi:type="xsd:string"></Value>
  </ParameterValueStruct>
  <ParameterValueStruct>
   <Name>InternetGatewayDevice.WANDevice.3.WANConnectionDevice.
1.WANPPPConnection.1.ExternalIPAddress</Name>
   <Value xsi:type="xsd:string">AAAAAAAAAAAAA</Value>
  </ParameterValueStruct>
 </ParameterList>
</cwmp:Inform>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
0

>From a HTTP/1.1 perspective the request if fine, i checked if the
chunk-sizes are correctly submitted and if all \r\n are correctly
send.
Furthermore I set the WSGIChunkedRequest On.
However if I do a environ['wsgi.input'].read() the following error
message is generated.

[Fri Apr 27 09:09:42 2012] [error] [client 127.0.0.1] Traceback (most
recent call last):
[Fri Apr 27 09:09:42 2012] [error] [client 127.0.0.1]   File "/tmp/
wsgi", line 3, in application
[Fri Apr 27 09:09:42 2012] [error] [client 127.0.0.1]     print
environ['wsgi.input'].read()
[Fri Apr 27 09:09:42 2012] [error] [client 127.0.0.1] IOError: request
data read error

I search through mod_wsgi.c and apaches modules/http/http_filters.c
and for me it looks like that the HTTP body send to the daemon is
*free* from the chucking information. Which means no annoying (56d\r
\n, 574\r\n and \r\n0\r\n\r\n the end).
Inside the daemon the 'ap_http_filter' is added again to the input-
chain and then called by ap_get_client_block when the application
needs data. However in this scenario 'ap_http_filter' inside the
daemon process has *no* Content-Length header (obvious because it is
chunking) and *no* chunking information inside the body itself, like
the trailing '0'
'ap_http_filter' has no chance and returns APR_EOF to
ap_get_client_block. ap_get_client_block interprets APR_EOF as an
error and returns -1 which is converted by mod_wsgi.c to the exception
above.

Right now I see this solutions
1) Don't solve this at mod_wsgi level and write a separate
apache_module which does the 'dechunking of its own'. This module
reads the *whole* request at once (similar to mod_request in
apache2.4)  then it can calculate the body size and replaces the
'Transfer-Encoding' header with a Content-Length.

2) Do it like above but integrate the code it to mod_wsgi itself. This
code runs then before the request is send to the daemon.

3) Don't run ap_http_filter at all inside the daemon. I mean
'ap_http_filter' runs already in the process which accepts the
request. So why execute it a second time in the daemon itself? To be
more precise this line from 2007 makes me wondering
'ap_add_input_filter("HTTP_IN", NULL, r, r->connection);'
I disabled this line just for fun and then it works, because the only
filter called now is 'ap_core_input_filter' which return APR_SUCCESS
if no more data is coming.
On the other side I can image that there is a use case why this line
makes sense, I don't simply see it.

If there is a good reason not do option three I have no problem with
the other ones, because the requests our application expects will not
blow up memory.

Regards,
 Stephan


-- 
You received this message because you are subscribed to the Google Groups 
"modwsgi" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/modwsgi?hl=en.

Reply via email to