[Grok-dev] HTTP PUT strange behavior

Adrian Tofan adi at modiadi.com
Thu May 28 05:09:45 EDT 2009


Hello,
I try to upload a file from an iPhone app to Grok application. The basic
idea is that I spent half of day searching for a solution and I believe that
is a bug on the server side(grok,zoppe or paster). After a lot
of frustration I have downloaded php and I tried the same code with a
php server-side application which works ! I also confirms a potential bug on
the grok side.

I am using  Grok 1.0a4 in a very simple code like this:

import grok
from zope.interface import Interface

class ZDUploadContainer(grok.Model):
pass
class IphoneUploadLayer(grok.IRESTLayer):
    grok.restskin('up')

class ZendriveREST(grok.REST):
  grok.context( ZDUploadContainer)
  grok.layer(IphoneUploadLayer)

  def PUT(self):
        import pdb;pdb.set_trace();
        self.response.setStatus(200)
        return "PUT request"
  def GET(self):
        return "GET request"

I am using a REST layer because is the only way I know to access HTTP PUT
data.

Testing from browser http://localhost:8080/++rest++up/zd/i/ works returning
a page with correct response "GET request".

Now from the phone app starts the interesting part...
Here is the HTTP conversation.
The phone sends as HEADER :

PUT /++rest++up/zd/i HTTP/1.1
Host: localhost:8080
User-Agent: zendrive/1.0 CFNetwork/445.3 Darwin/9.7.0
Content-Type: application/octet-stream
Content-Length: 4
Accept: */*
Accept-Language:en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive

The BODY of the message is TEST which has 4 bytes as length. What happens is
that the after sending all the data it doesn't get any response back(in the
HTTP sniffer I have a Waiting ... status).  If I kill the sending app before
timing out, on the grok side I get the debugger and I am inside the PUT
method !

If i try:
(Pdb) p self.body
'TEST'
Which is correct.  The problem is that I had to kill the iphone app to get
there.

Two interesting things :
if I don't send Content-Length at all, the HTTP header and the body is the
same (in the HTTP sniffer) except missing Content-Length. The debugger fires
up and I am inside the PUT method, but I have no body for the message :
(Pdb) p self.body
''
As son as I press c connection closes and everything is ok on the iphone
side.

Next step is with Content-Length:3 .. I have the same thing but after the
debugger starts:
(Pdb) p self.body
'TES'
The body is 3 caracters legth instead of 4 ... and after I continue the
iPhone app gives me a Error (opperation cannot be completed) and HTTP
sniffer tells me that the connection status is : Resset by peer.

As I explained with a simple php script all works on the phone side and
serve side!.
The conclusion is that if in a PUT request I put a Content-length :
1: bigger or equal of the body size - the wed server expects more data until
it times out, it never gives the control to PUT method
2: 0 - the body is sent to the server but inside PUT method self.body is
empty
3. less than the size of the body : bad on the client side(connection
reseted by peer) and on the server side inside PUT self.body is truncated.

First of all if anybody has any suggestions they are more than welcome.

I have read a related problem on the zope forums which they solved by
changing the web server from paster to zserver. I don't understand this part
and I don't know how to do it (if posible in grok).

Also do you think that is posible to get the content of a PUT request in a
difrent way ?

Thank you all for reading this long post ....


Adrian Tofan


More information about the Grok-dev mailing list