Python Forum

Full Version: Converting web server from python 2 to python 3
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have been using this script, found online not my work!

In python2 it works perfectly, but in python3 (using 2to3) we get the "a bytes-like object is required, not 'str'" error.
I can't figure out how to encode "sys.argv[2]", if I replace it with static credentials: b'user:pass' the error goes away. This is not a problem actually, I would prefer it, but it creates another problem: setting the port. How/where is sys.argv[1] (the port number) actually used? Any help much appreciated.

import os
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
import sys
import base64

os.chdir("H:\\")

key = ""

class AuthHandler(SimpleHTTPRequestHandler):
    ''' Main class to present webpages and authentication. '''
    def do_HEAD(self):
        print "send header"
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()

    def do_AUTHHEAD(self):
        print "send header"
        self.send_response(401)
        self.send_header('WWW-Authenticate', 'Basic realm=\"Marradio\"')
        self.send_header('Content-type', 'text/html')
        self.end_headers()

    def do_GET(self):
        global key
        ''' Present frontpage with user authentication. '''
        if self.headers.getheader('Authorization') == None:
            self.do_AUTHHEAD()
            self.wfile.write('no auth header received')
            pass
        elif self.headers.getheader('Authorization') == 'Basic '+key:
            SimpleHTTPRequestHandler.do_GET(self)
            pass
        else:
            self.do_AUTHHEAD()
            self.wfile.write(self.headers.getheader('Authorization'))
            self.wfile.write('not authenticated')
            pass

def test(HandlerClass = AuthHandler,
         ServerClass = BaseHTTPServer.HTTPServer):
    BaseHTTPServer.test(HandlerClass, ServerClass)


if __name__ == '__main__':
    if len(sys.argv)<3:
        print "usage SimpleAuthServer.py [port] [username:password]"
        sys.exit()
    key = base64.b64encode(sys.argv[2])

    test()
Please, always include any (and complete, unaltered) errors in error tags.
This is very important as it exposes conditions that lead up to the actual error

Thank You
Apologies.

Traceback (most recent call last):
  File "E:\py3-server.py", line 52, in <module>
    key = base64.b64encode(sys.argv[2])
  File "C:\Python36\lib\base64.py", line 58, in b64encode
    encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'
key = base64.b64encode(sys.argv[2])
whatever's in argv[2], needs to be preceeded witk b, like b'my string'
Usage: py3-server.py 2727 user:password

sys.argv[2] = user:password
b'user:password' produces the same error.
I fixed it by changing the line:
Quote:encoded = binascii.b2a_base64(s, newline=False)
to:
Quote:encoded = binascii.b2a_base64(bytes(s, "utf-8"), newline=False)
in base64.py (which makes me nervous!)
Now we have a new error:

Quote:----------------------------------------
Exception happened during processing of request from ('192.168.0.10', 50059)
Traceback (most recent call last):
File "C:\Python36\lib\socketserver.py", line 317, in _handle_request_noblock
self.process_request(request, client_address)
File "C:\Python36\lib\socketserver.py", line 348, in process_request
self.finish_request(request, client_address)
File "C:\Python36\lib\socketserver.py", line 361, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "C:\Python36\lib\socketserver.py", line 696, in __init__
self.handle()
File "C:\Python36\lib\http\server.py", line 418, in handle
self.handle_one_request()
File "C:\Python36\lib\http\server.py", line 406, in handle_one_request
method()
File "E:\Python\FTP_server\py3-Marradio_server.py", line 30, in do_GET
if self.headers.getheader('Authorization') == None:
AttributeError: 'HTTPMessage' object has no attribute 'getheader'
----------------------------------------

OK so getheaders should be get in python 3, I would expect 2to3 to correct that.