Content-Length

171 views
Skip to first unread message

Cameron

unread,
Oct 24, 2012, 4:48:15 PM10/24/12
to we...@googlegroups.com
I'm curious to know what solution everyone has come up with for setting the Content-Length headers for larger web applications. I'd rather not set it for every single app / subapp response so I came up with this but it seems pretty hacky. Thoughts?

def headersProcessor(h):
    """
    Set the content length and and content type of each request.

    h : the handler for the requested url

    return the response from the handler
    """
    res = h()
    web.header('Content-type', 'text/html; charset=utf-8')
    web.header('Content-Length', len(res))
    return res
app.add_processor(headersProcessor)

Cameron

unread,
Oct 30, 2012, 8:57:31 PM10/30/12
to we...@googlegroups.com
Did I ask a dumb question or something? :( 

Kevin Houlihan

unread,
Oct 30, 2012, 2:19:06 PM10/30/12
to we...@googlegroups.com
I'm working on a REST API for which I implement common functionality using decorators that I can add to the request methods, and part of that common functionality is setting headers. It's a work in progress but this is the general idea:

def serializecontent(method):
    @wraps(method)
    def wrapper(self, *args, **keys):
        
        # Retrieve the data from the wrapped method
        content = method(self, *args, **keys)
        
        if not content is None:
            # Serialize the data as requested
            serializeddata = self.serialize(content)
            # Set the content headers
            # This may not be the best place to do this, particularly the content length.
            self.setcontentlengthheader(serializeddata)
            self.setcontenttypeheader()
            return serializeddata
        else:
            return None

    return wrapper

class UserCollection(Collection):
 
    @handleexceptions
    @requestmethod
    @setetag()
    @serializecontent
    @setlastmodified(determinelastmodified=_lastmodified)
    @conditionalresponse(determinelastmodified=_lastmodified)
    def GET(self):
        return Collection.GET(self) 
 
     # ...

Is that more or less hacky? :P It needs a lot of tidying up as it is at the moment, and I'm probably sidestepping a lot of great functionality that web.py provides, but the thing I was trying to avoid like yourself was recreating the same standard functionality in each request method.

Regards,
Kevin

--
You received this message because you are subscribed to the Google Groups "web.py" group.
To view this discussion on the web visit https://groups.google.com/d/msg/webpy/-/brb4RSGGqZMJ.
To post to this group, send email to we...@googlegroups.com.
To unsubscribe from this group, send email to webpy+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/webpy?hl=en.

Andrey Kuzmin

unread,
Oct 31, 2012, 5:42:35 AM10/31/12
to we...@googlegroups.com
I use decorators for authentication, in your case how do you handle when all application controllers methods need the same functionality? Having a lot of decorators over every method would look a bit bloated.

Kevin Houlihan

unread,
Oct 31, 2012, 6:36:07 AM10/31/12
to we...@googlegroups.com
I don't do anything special at this point if every method needs the same functionality, I just have that as a decorator as well (the exception handling, for example) and add it to every method. It looks like what Cameron has done would work well for that, so that's something that I might experiment with.

I'm not sure how many decorators over a method is too many. I had just learned about them when I started writing this, so I may have gone a bit overboard :P The alternative would seem to be to have a sequence of function calls within the method, each acting on the output of the previous call. I don't think that would be any more or less legible, just different.

What I like about it is that the request methods just need to concentrate on retrieving the requested objects from the database, while all the details of how those objects are delivered to the client, or even if they are delivered at all due to certain HTTP headers, is dealt with outside the method, in the decorators.

To view this discussion on the web visit https://groups.google.com/d/msg/webpy/-/jVou_kd7i5UJ.

Andrey Kuzmin

unread,
Oct 31, 2012, 6:50:34 AM10/31/12
to we...@googlegroups.com
I think that if you need to implement the same functionality for all requests, then webpy's application processors are better than specifying decorator for each controller method.

Cameron

unread,
Dec 4, 2012, 11:11:18 AM12/4/12
to we...@googlegroups.com

Just thought I'd post an update. I went with the function mentioned above with minor changes and it's been in production for a few weeks now. If a specific application was already returning with headers (JSON, generated file download, etc...) I just passed the response along.

 
 
 

def headersProcessor(h):
  
    res = h()
    if res:
        if not web.ctx.headers:
Reply all
Reply to author
Forward
0 new messages