Writing response body with BaseHTTPRequestHandler
Asked Answered
N

4

46

I'm playing a little with Python 3.2.2 and want to write a simple web server to access some data remotely. This data will be generated by Python so I don't want to use the SimpleHTTPRequestHandler as it's a file server, but a handler of my own.

I copied some example from the internet but I'm stuck because the response outputstream refuses to write the body content.

This is my code:

import http.server
import socketserver

PORT = 8000

class MyHandler(http.server.BaseHTTPRequestHandler):
    def do_HEAD(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        print(self.wfile)
        self.wfile.write("<html><head><title>Title goes here.</title></head>")
        self.wfile.write("<body><p>This is a test.</p>")
        # If someone went to "http://something.somewhere.net/foo/bar/",
        # then s.path equals "/foo/bar/".
        self.wfile.write("<p>You accessed path: %s</p>" % self.path)
        self.wfile.write("</body></html>")
        self.wfile.close()

try:
    server = http.server.HTTPServer(('localhost', PORT), MyHandler)
    print('Started http server')
    server.serve_forever()
except KeyboardInterrupt:
    print('^C received, shutting down server')
    server.socket.close()

What should be a correct code for writing the response body?

Thanks a lot.

Edit:

The error is:

...
  File "server.py", line 16, in do_GET
    self.wfile.write("<html><head><title>Title goes here.</title></head>")
  File "C:\Python32\lib\socket.py", line 297, in write
    return self._sock.send(b)
TypeError: 'str' does not support the buffer interface
Nitroparaffin answered 4/10, 2011 at 10:43 Comment(3)
I admit I don't have the basics in Python :) so I'm a little lost trying to figure out how to work with the types and tools for transforming them...Nitroparaffin
where is this line in your code? self.wfile.write(prueba)Pyosis
Oops, I'm sorry. That's the trace from another test (prueba = test). I'll fix it.Nitroparaffin
P
49

In Python3 string is a different type than that in Python 2.x. Cast it into bytes using either

self.wfile.write(bytes("<html><head><title>Title goes here.</title></head>/html>","utf-8")) 

or

self.wfile.write("<html><head><title>Title goes here.</title></head></html>".encode("utf-8"))
Pyosis answered 4/10, 2011 at 12:12 Comment(2)
Great. Now I think if there is a way to wrap an outputstream within a "printwriter" (yes, I'm a Java programmer), hehehe. Let's look for something (or simply define a simple conversion function)Nitroparaffin
I tried with the .encode() string transformation for Python 3 but there is still an error. You have to remove the last line: self.wfile.close() because the do_GET will close and flush the stream by itself.Thisbe
L
6

For Python 3, prefix the string literals with a b:

self.wfile.write(b"<foo>bar</foo>")
Libratory answered 9/6, 2016 at 12:7 Comment(1)
This is the cleanest solution here, nice! Can you confirm that this defaults to enoding utf-8?Fete
V
4

based on your code #comments you're probably looking for self.headers.getheaders('referer'), ie:

if 'http://www.icamefromthissite.com/' in self.headers.getheaders('referer'):
    do something
Valued answered 18/11, 2011 at 21:23 Comment(1)
Well, not really. I only wanted to control programmatically the output of the response. The approved answer is what I needed. To encode the strings into bytes in order to send the bytes to the response. Thanks anyway!Nitroparaffin
S
2

Just use this when using Python 3.X

self.wfile.write(bytes("<body><p>This is a test.</p>", "utf-8"))
Steenbok answered 23/8, 2017 at 6:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.