Python BaseHTTPRequestHandler throws Lookup error on anything but utf-8

205 views Asked by At

I Need to write a server program in Python serving webpages and handling other GET and POST requests to and from client. I'm new to servers in Python, so I looked up some examples and after a while I had a basic Requesthandler running with some routing to my pages as a start. Routing worked in browser and pages were displayed there but I only got text, no styles, no pictures. Then I looked a bit further and realised that I also needed to handle GET requests for these .css, .js,.jpg files. So I did that, and ended up with smth like this:

class Serv(BaseHTTPRequestHandler):
    def do_GET(self):
        #route incoming path to correct page
        if self.path in("","/"):
            self.path = "/my_site/index.html"

        #TODO do same for every page in the site

        if self.path == "/foo":
            self.path = "/my_site/fooandstuff.html"

        if self.path == "/bar":
            self.path = "/my_site/subdir/barfly.html"


        try:
            sendReply = False
            if self.path.endswith(".html"):
                mimetype = "text/html"
                sendReply = True
            if self.path.endswith(".jpg"):
                mimetype = "image/jpg"
                sendReply = True
            if self.path.endswith(".js"):
                mimetype = "application/javascript"
                sendReply = True
            if self.path.endswith(".css"):
                mimetype = "text/css"
                sendReply = True

            if sendReply == True:
                f = open(self.path[1:]).read()
                self.send_response(200)
                self.send_header('Content-type',mimetype)
                self.end_headers()
                self.wfile.write(f.encode(mimetype))
            return
        except IOError:
            self.send_error(404, "File not found %s" % self.path)

When I run this and request a page, I get the following LookupError:

  File "d:/somedir/myfile.py", line 47, in do_GET
    self.wfile.write(f.encode(mimetype))
LookupError: unknown encoding: text/html

if I change text/html to utf-8, that seems te "solve" the problem, but then I run into the same Lookuperror but this time for image/jpg, and so on. It seems like wfile.write only accepts utf-8, although , when I look around, I see people passing file.read() just like that to wfile.write

wfile.write(file.read())

and for them it seems to work. Yet, when I do that, what I get is

File "C:\Users\myuser\AppData\Local\Programs\Python\Python37\lib\socketserver.py", line 799, in write
    self._sock.sendall(b)
TypeError: a bytes-like object is required, not 'str'

What could cause this to happen?

2

There are 2 answers

0
Blindshot On

for server handling with python better lookup flask sample code will look like

from flask import Flask, render_template, url_for, request, redirect
import csv

@app.route('/')
def my_home():
    return render_template('index.html')


@app.route('/<string:page_name>')
def html_page(page_name):
    return render_template(page_name)

put all HTML in the same folder as your server.py in a folder called [template] and all CSS and java in folder called [static] assets and all include. dont forget to change paths in css, java and html

0
Kunga Led On

The answer was in the opening of an image file, that needed an extra argument "rb" , like this:

        if mimetype != "image/jpg":
            f = open(self.path[1:])
        else:
            f = open(self.path[1:], "rb")

and then also:

        if mimetype == "image/jpg": 
            self.wfile.write(f.read())
        else:
            self.wfile.write(f.read().encode("utf-8"))