I am开发者_StackOverflow社区 using this middleware to make my app restful, but it looks like my form parameters are not coming through:
from google.appengine.ext import webapp
class RestHTTPMiddleware(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
method = webapp.Request(environ).get('_method')
request = Request(environ)
environ['wsgi.input'] = StringIO.StringIO(request.body)
if method:
environ['REQUEST_METHOD'] = method.upper()
return self.app(environ, start_response)
when I submit a form and the debug it using:
def put(self):
logging.debug(self.request.get('description'))
the logger is empty. The put(self) method is being called, I have tested it using the logger and my debug message is shown.
2nd revision:
from google.appengine.ext import webapp
from webob import Request
import logging
import StringIO
class RestHTTPMiddleware(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
request = Request(environ)
environ['wsgi.input'] = StringIO.StringIO(request.body)
method = webapp.Request(environ).get('_method')
if method:
environ['REQUEST_METHOD'] = method.upper()
return self.app(environ, start_response)
Latest changes:
from google.appengine.ext import webapp
from webob import Request
import logging
import StringIO
class RestHTTPMiddleware(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
request = Request(environ)
body = StringIO.StringIO(request.body)
method = webapp.Request(environ).get('_method', None)
if method:
environ['REQUEST_METHOD'] = method.upper()
environ['wsgi.input'] = body
return self.app(environ, start_response)
Instantiating webapp.Request and calling .get on it causes it to read the request body and parse form parameters in it. When your actual webapp starts later, it instantiates another request object, and once again tries to read the request body - but it's already been read, so nothing is returned.
You could modify your middleware to store a copy of the request body and put it back in the WSGI environment. There are other options:
- If the _method arg will always be a query string parameter instead of a posted form parameter, you can use webapp.Request(environ).GET.get('method'), which won't read the request body.
- You could override WSGIApplication.call to change how it does dispatch.
- You could subclass WSGIApplication and supply a custom REQUEST_CLASS, being a function that builds a real request object, then modifies the environment that was passed in to suit you (hack!).
- You could define a custom webapp RequestHandler base class that implements initialize(), reaching in to the request object's WSGI dict and changing the method (hack!).
精彩评论