The PUT/POST translation is done in routes.middleware and I've tried
putting the HEAD/GET translation there too. Two diffs below - a short
one that fixes route matching for HEAD requests but reverts the method
to GET (using existing code) before passing the request on to the app,
and a longer one that reverts just before the response. An extra-
short one still wouldn't bother to revert at all but I feel a little
uneasy with that one.
The shorter version fixes routing but fails on actions that explicitly
check for the GET method, including those decorated with
@restrict('GET'). I don't use the decorators myself (having that
information in my routes is much more useful to me) and I'm not sure
what would be the least surprising behaviour to people that do!
If anyone would care to express an opinion either way (or has better
ideas) I'll push the consensus view up to my fork on bitbucket.
Regards,
Mike
Short version:
--- a/routes/middleware.py Mon Jan 11 19:57:55 2010 +0000
+++ b/routes/middleware.py Thu Feb 04 16:53:59 2010 +0100
@@ -76,7 +76,12 @@
if self.log_debug:
log.debug("_method found in POST data,
altering request "
"method to %s",
environ['REQUEST_METHOD'])
-
+ elif environ['REQUEST_METHOD'] == 'HEAD':
+ old_method = 'HEAD'
+ environ['REQUEST_METHOD'] = 'GET'
+ if self.log_debug:
+ log.debug("REQUEST_METHOD is HEAD, altering to
GET")
+
# Run the actual route matching
# -- Assignment of environ to config triggers route matching
config.environ = environ
Longer version:
@@ -49,6 +49,7 @@
config.mapper = self.mapper
old_method = None
+ head_method = None
if self.use_method_override:
req = None
@@ -76,7 +77,12 @@
if self.log_debug:
log.debug("_method found in POST data,
altering request "
"method to %s",
environ['REQUEST_METHOD'])
-
+ elif environ['REQUEST_METHOD'] == 'HEAD':
+ head_method = 'HEAD'
+ environ['REQUEST_METHOD'] = 'GET'
+ if self.log_debug:
+ log.debug("REQUEST_METHOD is HEAD, altering to
GET")
+
# Run the actual route matching
# -- Assignment of environ to config triggers route matching
config.environ = environ
@@ -128,6 +134,9 @@
environ['SCRIPT_NAME'] = environ['SCRIPT_NAME'][:-1]
response = self.app(environ, start_response)
+
+ if head_method:
+ environ['REQUEST_METHOD'] = head_method
# Wrapped in try as in rare cases the attribute will be gone
already
try:
On Feb 3, 12:27 pm, Mike Burrows <[email protected]> wrote:
> Yes, your article came up high in my research and it was very
> interesting (in the sense of slightly worrisome!). Your subscriber
> count went up by one this morning :-)
>
> Reassured somewhat that I'm thinking along the right lines I'm tempted
> to get something working and then submit a patch. I guess there's the
> PUT/POST translation to follow as a model.
>
> To be honest I'm not 100% sure how serious this is - my interest is in
> adding a resource discovery protool and I need only headers
> (specifically link headers) for 1-3 requests on client startup before
> a GET is fully justified. Slightly inefficient (not to mention
> distasteful) to use GET, but no disaster. Are there situations where
> it hurts more?
>
> Mike
>
> On Feb 3, 11:50 am, Graham Dumpleton <[email protected]>
> wrote:
>
> > You may find my blog post about GET/HEAD and WSGI interesting.
>
> > http://blog.dscpl.com.au/2009/10/wsgi-issues-with-http-head-requests....
>
> > Because of Python web frameworks doing all sort of odd things and not
> > always handling HEAD properly, I in part felt that WSGI adapters
> > should always just convert HEAD to GET as is safest thing to do to
> > ensure correct behaviour.
>
> > Graham
>
> > On Feb 3, 9:35 pm, Mike Burrows <[email protected]> wrote:
>
> > > When routes have conditions that constrain the request method to GET,
> > > any HEAD requests result in 405 Method Not Allowed. Bug or feature?
>
> > > With HEAD added as an allowed method, the server (paster) does the
> > > right thing and returns a zero-length body.
>
> > > Working around this in one's routing isn't always an easy option -
> > > mapper.resource() or mapper.collection() don't add HEAD automatically,
> > > and they probably shouldn't either. Can't help thinking that somewhere
> > > in the middleware stack (before Routes I guess) a HEAD should be
> > > turned temporarily into GET so that HEAD is allowed everywhere GET
> > > is. As such this feels to me a Pylons issue. Before I raise a
> > > ticket, any thoughts?
>
> > > Small asides:
> > > (1) I haven't tested what happens if you use @restrict instead (I
> > > don't use it)
> > > (2) a head() method in paste.fixture would be nice, but in the
> > > meantime app._gen_request('HEAD', ...) does the job. Tried real http
> > > requests using curl too.
>
> > > Regards,
> > > Mike
--
You received this message because you are subscribed to the Google Groups
"pylons-discuss" 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/pylons-discuss?hl=en.