405 for ajax calls on CherryPy

292 views
Skip to first unread message

JLIST

unread,
Dec 26, 2007, 6:08:52 AM12/26/07
to we...@googlegroups.com
Hello all,

I've been trying a little AJAX with SACK:
http://www.twilightuniverse.com/projects/sack/

I'm getting a lot of 405 errors with CherryPy server.
The requests fail most of the time, succeed occasionally.

This shows on web.py 0.22 console on Windows:
127.0.0.1:1883 - - [26/Dec/2007 02:00:09] "HTTP/1.1 POST /req" - 200 OK
127.0.0.1:1883 - - [26/Dec/2007 02:00:11] "HTTP/1.1 rndval=1198663209684POST /req" - 405 Method Not Allowed
127.0.0.1:1883 - - [26/Dec/2007 02:00:11] "HTTP/1.1 rndval=1198663211026POST /req" - 405 Method Not Allowed

I then switched to runbasic, and most requests succeed. The failed
ones don't give an error code though. Just no result. The request
handler class is called but the result is not picked up by the
browser. Any ideas why it fails sometimes?

--
Best regards,
Jack

Gary Bernhardt

unread,
Dec 28, 2007, 4:30:09 PM12/28/07
to we...@googlegroups.com
On Dec 26, 2007 6:08 AM, JLIST <jli...@gmail.com> wrote:
>
> Hello all,
>
> I've been trying a little AJAX with SACK:
> http://www.twilightuniverse.com/projects/sack/
>
> I'm getting a lot of 405 errors with CherryPy server.
> The requests fail most of the time, succeed occasionally.
>
> This shows on web.py 0.22 console on Windows:
> 127.0.0.1:1883 - - [26/Dec/2007 02:00:09] "HTTP/1.1 POST /req" - 200 OK
> 127.0.0.1:1883 - - [26/Dec/2007 02:00:11] "HTTP/1.1 rndval=1198663209684POST /req" - 405 Method Not Allowed
> 127.0.0.1:1883 - - [26/Dec/2007 02:00:11] "HTTP/1.1 rndval=1198663211026POST /req" - 405 Method Not Allowed

This log makes it look like the HTTP method being sent is
"rndval=<random integer>POST". Obviously, that isn't a valid HTTP
method. I can't imagine what kind of bug could result in this, but
maybe it's some kind of printed debug info that's making its way into
the HTTP request somehow?

--
Gary
http://blog.extracheese.org

Anand Chitipothu

unread,
Dec 28, 2007, 9:12:29 PM12/28/07
to we...@googlegroups.com

Aah, I know what is happening.
When you send a POST request and not read the input, it gets available
to the next request.

For example consider the following 2 requests.

POST /path1 HTTP/1.1
k1: v1
k2: v2

rndval=1234

GET /path2 HTTP/1.1
k1: v1
k2:v2

Since the data in POST request is not read, the second request's
method becomes rndval=1234GET.
Even I noticed this once. This happens only with cherrypy webserver
and not with lighttpd or apache.

If you make sure you read all the given input data, it will be OK. You
may add the following unloadhook.

web.unloadhooks['input'] = web.input

Graham Dumpleton

unread,
Dec 28, 2007, 11:27:53 PM12/28/07
to web.py
On Dec 29, 1:12 pm, "Anand Chitipothu" <anandol...@gmail.com> wrote:
The CherryPy WSGI server also does not protect against a WSGI
application accidentally reading more request content than was
actually sent for the request. This can be a problem if keep alive is
enabled and the content length header was wrong, the WSGI application
tries to read more than what the content length specified or the WSGI
application calls read() on wsgi.input with no arguments. End result
is that the WSGI application will block indefinitely waiting for more
input.

Proper web servers like Apache protect against such things and will
never let you read more data than was actually sent, properly
signalling EOF if you do even when keep alive is enabled. Apache will
also ensure that any remaining content from a request is discarded
before trying to process a subsequent request when keep alive is on.

For a production grade system, always probably better to use something
like Apache.

Graham

JLIST

unread,
Dec 29, 2007, 12:24:52 AM12/29/07
to Anand Chitipothu
Thanks Anand for finding out the problem! (For CherryPy,
though. SimpleHttpServer error is different - it doesn't
show an error in console window.)

How do I guarantee that I read all post data?

> web.unloadhooks['input'] = web.input

And what exactly does this do? Will this make sure all data is read
before the next request?

It should really be the web server's responsibility to understand
the HTTP protocol and parse the data though.

Thanks
Jack

Green

unread,
Dec 30, 2007, 5:12:24 AM12/30/07
to web.py
web.unloadhooks['input'] = web.input
is this added to webpy now? or does it need fixing

On Dec 28, 6:12 pm, "Anand Chitipothu" <anandol...@gmail.com> wrote:

Anand Chitipothu

unread,
Dec 30, 2007, 5:27:33 AM12/30/07
to we...@googlegroups.com
On Dec 30, 2007 3:42 PM, Green <sanmat...@yahoo.com> wrote:
>
> web.unloadhooks['input'] = web.input
> is this added to webpy now? or does it need fixing

It is there in 0.2x, but 0.3 will not have it.

JLIST

unread,
Dec 30, 2007, 1:05:51 PM12/30/07
to Anand Chitipothu
Hello Anand,

> If you make sure you read all the given input data, it will be OK. You
> may add the following unloadhook.

> web.unloadhooks['input'] = web.input

Without understanding how it works, I put that line before
web.run(urls, globals(), web.reloader)
and my ajax calls seem to work fine with both CherryPy and
SimpleHTTPServer.

Thanks,
Jack

Anand Chitipothu

unread,
Dec 30, 2007, 9:49:04 PM12/30/07
to we...@googlegroups.com
> > web.unloadhooks['input'] = web.input
>
> Without understanding how it works, I put that line before
> web.run(urls, globals(), web.reloader)
> and my ajax calls seem to work fine with both CherryPy and
> SimpleHTTPServer.

web.py runs all unloadhooks after handling every request. Since
web.input is added to unloadhooks, it will be called for every
request. This will make sure that all POST data is read and nothing is
left to interfere with the next request.

Reply all
Reply to author
Forward
0 new messages