0

Elsewhere on this forum in a comment was offered the skeleton of a web server in Python. I have grabbed this an limped off to expand the skeleton to something I can use on an Arduino YUN shield which runs the openWrt flavour of Linux and has Python-2.7.13.

I have got a little way in and have struck a brick wall. I send an empty GET request as per the comments at the top of the code and I get a TypeError. Could some Python please point out my obvious mistake?

Here is the collected console output from the server:

Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 284, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 310, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 323, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 638, in __init__
    self.handle()
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 340, in handle
    self.handle_one_request()
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 328, in handle_one_request
    method()
  File "pythonWebServer.py", line 67, in do_GET
    self.sendPage(servedFileName)
TypeError: sendPage() takes exactly 1 argument (2 given)
Starting httpd...
/index.htm
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 41960)
----------------------------------------
Traceback (most recent call last):
  File "pythonWebServer.py", line 88, in <module>
    run(port=int(argv[1])) 
  File "pythonWebServer.py", line 82, in run
    httpd.serve_forever() 
  File "/usr/lib/python2.7/SocketServer.py", line 225, in serve_forever
    r, w, e = select.select([self], [], [], poll_interval)
KeyboardInterrupt

And here is the code which produces that 'TypeError':

#!/usr/bin/python 
""" 
Very simple HTTP server in python.   
Usage:: 
    ./pythonWebServer.py [<port>] 
 
Send a GET request:: 
    curl http://localhost 
  
Send a HEAD request:: 
     curl -I http://localhost 
  
Send a POST request:: 
     curl -d "foo=bar&bin=baz" http://localhost 
  
"""

import os.path
import fileinput
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 

servedFileName = "?"
dummyArgs = "Empty"
class S(BaseHTTPRequestHandler):
    def sendPage(filePath):
        if os.path.exists(filePath):
            for line in fileinput.input(filePath):
                self.wfile.write(line)             
            return True
        else:
            self._set_headers() 
            self.wfile.write("<html><body><h1> File: "+ filePath + " not found</h1></body></html>") 
            return False

    def pythonSub(subPath, subData):
        if os.path.exists(subPath):
#            modName = trim(subPath)
# need to strip off .py extension here ?? 
            import subPath
            subPath.pyScript(subData)
            return True
        else:
            self._set_headers() 
            self.wfile.write("<html><body><h1> File: "+ subPath + " not found</h1></body></html>") 
            return False

    def _set_headers(self): 
        self.send_response(200) 
        self.send_header('Content-type', 'text/html') 
        self.end_headers() 
 
    def do_GET(self):
        if self.path == "/":
            if os.path.exists("index.html"):
                servedFileName = "/index.html"
            elif os.path.exists("index.htm"):
                servedFileName = "/index.htm"
            elif os.path.exists("index.py"):
                self.pythonSub("/index.py", dummyArgs)
        else:
            if instr(self.path, ".py"): # I know what I mean - I'll fix this later.
                self.pythonSub(self.path, dummyArgs)
            else:    
                servedFileName = self.path
        if servedFileName != "?":
            print servedFileName
            self.sendPage(servedFileName)
            servedFileName = "?"

    def do_HEAD(self): 
        self._set_headers() 
         
    def do_POST(self): 
        content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
        POSTdata = self.rfile.read(content_length) # <--- Gets the data itself
        pythonSub(self.path, POSTdata)
         
def run(server_class=HTTPServer, handler_class=S, port=80): 
    server_address = ('', port) 
    httpd = server_class(server_address, handler_class) 
    print 'Starting httpd...' 
    httpd.serve_forever() 

if __name__ == "__main__": 
    from sys import argv 
 
    if len(argv) == 2: 
        run(port=int(argv[1])) 
    else: 
        run() 
Bellerofont
  • 1,081
  • 18
  • 17
  • 16
  • 1
    `def sendPage(filePath):` has no self variable make it `def sendPage(self, filePath):`. It's the non-implicit variable which refer to itself. In many other OO capable languages its called `this` and is implicitly available in non-static methods of that class, but in python the convention is to use the name `self`. – Paul Rooney Feb 02 '17 at 04:34
  • Thank you. Fixed. 'self' seems to be handled very differently to 'this' in C++. – OldBikerPete Feb 02 '17 at 05:42

0 Answers0