开发者

Python Handlers.py

I'm writing my own WSGI Simple Server. I want to be able to send a few requests to it and have some responses returned.

I have a request that comes in from fiddler, gets processed and returned to fiddler. I'm currently ONLY trying to return a success code... Fiddler gets back a 200 success/OK response, which is great. But then when I look at python it's thrown an assertion failure! Help! How do I avoid the assertion!?

My call stack ends up going

--> socketserver.py - handle_request_noblock
--> socketserver.py - process_request
--> socketserver.py - finish_request
--> simpleserver.py - handle
--> handlers.py - run
--> handlers.py - finish_response
--> handlers.py - write

The first few lines in the definition of write() are...

def write(self, data):
    """'write()' callable as specified by PEP 3333"""

    assert type(data) is bytes, \
        "write() argument must be a bytes instance"

At this point data has a type which is "str". Surely write should attempt to convert to bytes before throwing this exception?!? I'm truly exasperated by this!

Could anyone throw any light on what I'm doing wrong!??!

// Response class based on Google WebAppEngine, Which is NOT written in Python 3
class Response(object):
.. Omitted .. (See Google AppEngine?!)
def wsgi_write(self, start_response):
    body = self.out.getvalue()
    if isinstance(body, str):
            body = body.encode('utf-8')
    elif self.headers.get('Content-Type', '').endswith('; charset=utf-8'):
            try:
                    body.decode('utf-8')
            except UnicodeError as e:

                    print('Response written is not UTF-8: %s', e)

    if (self.headers.get('Cache-Control') == 'no-cache' and not self.headers.get('Expires')):
            self.headers['Expires'] = 'Fri, 01 Jan 1990 00:00:00 GMT'
    self.headers['Content-Length'] = str(len(body))

    new_headers = []
    for header, value in self.__wsgi_headers:
            if not isinstance(value, str):
                    value = str(value)
            if ('\n' in header or '\r' in header or '\n' in value or '\r' in value):
                    value = value.replace('\n','').replace('\r','')
                    header = header.replace('\n','').replace('\r','')
            new_headers.append((header, value))

    self.__wsgi_headers = new_headers

    write = start_response('%d %s' % (self.__status, self.__wsgi_headers))
    write(bytes(body))
    self.out.close()

class WSGIApplication(ob开发者_Python百科ject):
.. Omitted..

class Test(RequestHandler):
    def post(self):
        if self.response == None:
            print("No response")
        self.response.out.write("Success!")
        self.response.set_status(200, 'OK')

if __name__ == '__main__':
    print("Starting application")
    application = WSGIApplication([('/test', Test)])
    server = wsgiref.simple_server.make_server('', 109, application)
    server.serve_forever()

The only thing I can think that it would be is the wsgi_write response from the google app engine Response object, which I've borrowed and manipulated for my own purposes. I'm really not sure of the unicode stuff in the response. I'd appreciate any pointers... I did try to convert it but I've obviously got some stuff wrong?!


Surely write should attempt to convert to bytes before throwing this exception?!?

No, the ones who use your server should convert to bytes before calling write(), using their favorite encoding (which they also should specify in a header).

(That said, they probably shouldn't use write at all, see PEP3333.)

Could anyone throw any light on what I'm doing wrong!??!

Yes, as the errors tells you: The client should send in a bytes instance, not a str instance (or better, return an iterable instead of using write()). I'm a bit mystified by your code, where you apparently convert a string to bytes before writing it, except if it already is bytes, in which case you convert it to a string!?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜