Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

write the code for a Web server in Python. The Web server should return a minimu

ID: 669823 • Letter: W

Question

write the code for a Web server in Python. The Web server should return a minimum website, or an error code, when contacted by a web browser.

Use the attached code template to write a Web server that can be accessed by a web browser. The symbols "%%%%%%% " indicate you should add a line of code.

When the browser requests the website it should return it. When the browser requests a non-existent website it should return a 404 error code. The website should be contained in a .html file and display the message "Hello world!". You should be able to find many examples of minimum websites in the Internet.

Running the server:

1) Include the HTML file of your website in the same directory as your Web server Python code.

2) Run your Web server Python code (e.g., type "python webServer.py" into a terminal)

3) Open a web browser and type "localhost:portNumber/fileName.html" in the address bar. localhost is the address of your server, portNumber is the port you have assigned to the server inside your Web server code, and fileName.html is the name of the html file that contains the website itself. Press enter, and you should see your website displayed on the web browser.

4) Repeat step 2, but this time replace "filename.html" with "otherFile.html", where "otherFile.html" is a file that does not exist in your Web server's directory. Your Web server should return a 404 error code.

What to hand in:

First, create a directory named "webServer" and place 1)your website's .html file and 2) your .py file with your Web server code inside it. 2) Compress your webServer directory into a .zip file named after your last name (e.g., salinas.zip). Send an email to salinas@cs.wichita.edu with "CS 736: Programming Assignment" in the subject line and attach your .zip file.

# Import socket module

%%%%%%%

# Create a TCP server socket

#(AF_INET is used for IPv4 protocols)

#(SOCK_STREAM is used for TCP)

%%%%%%%

# Assign a port number

serverPort = 6789

# Bind the socket to server address and server port

%%%%%%%

# Listen to at most 1 connection at a time

%%%%%%%

# Server should be up and running and listening to the incoming connections

while True:

        print 'Ready to serve...'

       

        # Set up a new connection from the client

        %%%%%%%

       

        # If an exception occurs during the execution of try clause

        # the rest of the clause is skipped

        # If the exception type matches the word after except

        # the except clause is executed

        try:

               # Receive the request message from the client

               %%%%%%%

               # Extract the path of the requested object from the message

               # The path is the second part of HTTP header, identified by [1]

               filename = message.split()[1]

               # Because the extracted path of the HTTP request includes

               # a character '', we read the path from the second character

               f = open(filename[1:])

               # Store the entire contenet of the requested file in a temporary buffer

               outputdata = f.read()

               # Send the HTTP response header line to the connection socket

               connectionSocket.send("WRITE THE HEADER LINE HERE")

               # Send the content of the requested file to the connection socket

               for i in range(0, len(outputdata)):

                       %%%%%%%       

               %%%%%%%

              

               # Close the client connection socket

               %%%%%%%

        except IOError:

               # Send HTTP response message for file not found

               connectionSocket.send("WRITE THE HEADER LINE HERE")

               connectionSocket.send("<html><head></head><body><h1>WRITE A MESSSAGE ERROR HERE</h1></body></html> ")

               # Close the client connection socket

               %%%%%%%

#Close the Socket

%%%%%%%  

Explanation / Answer

Example program:

>To do this, the easiest way seem to me to be using a web server on the Pi.
import socket
import re
# Standard socket stuff:
host = '' # do we need socket.gethostname() ?
port = 8080
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((host, port))
sock.listen(1) # don't queue up any requests
# Loop forever, listening for requests:
while True:
csock, caddr = sock.accept()
print "Connection from: " + `caddr`
req = csock.recv(1024) # get the request, 1kB max
print req
# Look in the first line of the request for a move command
# A move command should be e.g. 'http://server/move?a=90'
match = re.match('GET /move?a=(d+)sHTTP/1', req)
if match:
angle = match.group(1)
print "ANGLE: " + angle + " "
csock.sendall("""HTTP/1.0 200 OK
Content-Type: text/html
<html>
<head>
<title>Success</title>
</head>
<body>
Boo!
</body>
</html>
""")
else:# If there was no recognised command then return a 404 (page not found)
print "Returning 404"
csock.sendall("HTTP/1.0 404 Not Found ")
csock.close()

>This is about as simple as a web server gets. It sets up a server socket to listen on using port 8080 and doesn't queue up any requests . When a connection is made from the client (e.g. a web browser) the sock.accept() creates a client socket to communicate with the client on. We then just read at most 1kB of data from the client, which is the HTTP headers saying what the client wants and using a regular expression we see if it is a "move" request and pull out the angle. If it was a move request then we print the angle to the console and return a simple web page by using csock.sendall . Otherwise we return a 404 error. Finally we close the client socket and loop round to the top again to wait for another connection.

Python code:

Connection from: ('192.168.1.129', 54340)
GET /move?a=20 HTTP/1.1
Host: raspberry1.scphillips.com:8080
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
DNT: 1
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en;q=0.8,en-US;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
ANGLE: 20
Connection from: ('192.168.1.129', 54344)
GET /favicon.ico HTTP/1.1
Host: raspberry1.scphillips.com:8080
Connection: keep-alive
Accept: */*
DNT: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en;q=0.8,en-US;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Returning 404

>So here we first get a connection from IP address 192.168.1.129 asking for "/move?a=20" using HTTP version 1.1. It then says that it wants that "page" from "Host: raspberry1.scphillips.com:8080". This is in case my web browser is talking to a proxy - the proxy needs to know where to get the page from (however, in this case there is no proxy). There are then a load of other headers that describe what the client is and how it would like information sent to it (language, character set, etc).
>The web server ignores all but the first line of the headers, spots that it's a move request and prints out the angle to the console. Immediately we then get a second request from the web browser asking for the "favicon.ico" - this just happens automatically. The favicon is the little icon you see in the address bar of most websites. Web browsers request them a lot. Our web server just ignores this request and sends a 404 (page not found)