Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Day11 #64

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
2014-01-16 Titus Brown <[email protected]>

* Added in simple HTTP response for HW 1.

2014-01-07 Titus Brown <[email protected]>

* Initialized repository, created server.py and README.
In-class exercise
107 changes: 88 additions & 19 deletions server.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,97 @@
#!/usr/bin/env python
import random
import socket
import time
import urlparse

s = socket.socket() # Create a socket object
host = socket.getfqdn() # Get local machine name
port = random.randint(8000, 9999)
s.bind((host, port)) # Bind to the port
def index(conn):
conn.send('<h1>Hello, world.</h1>')
conn.send('<p>This is foo\'s Web server.</p>')
conn.send('<p><a href = "content">content</p>')
conn.send('<p><a href = "file">file</p>')
conn.send('<p><a href = "image">image</p>')
conn.send('<p><a href = "form">form</p>')

print 'Starting server on', host, port
print 'The Web server URL for this would be http://%s:%d/' % (host, port)
def content(conn):
conn.send('<h1>You have reached the content page</h1>')

s.listen(5) # Now wait for client connection.
def file(conn):
conn.send('<h1>You are currently visiting the file page</h1>')

print 'Entering infinite loop; hit CTRL-C to exit'
while True:
# Establish connection with client.
c, (client_host, client_port) = s.accept()
print 'Got connection from', client_host, client_port
def image(conn):
conn.send('<h1>You are looking at the image page</h1>')

def form(conn):
conn.send('<form action="/submit" method="POST">')
conn.send('<p>Firstname</p><input type="text" name="firstname">')
conn.send('<p>Lastname</p><input type="text" name="lastname">')
conn.send('<input type="submit" value="Submit">')
conn.send('</form>')

def submit(conn, firstname, lastname):
conn.send('<h1>Hello Mr. {firstname} '
'{lastname}.</h1>'.format(firstname = firstname,
lastname = lastname))

def handle_connection(conn):
recieve = conn.recv(1000)
recieve = recieve.split('\n')
con = recieve[-1]
recieve = recieve[0].split()
method = recieve[0]
path = recieve[1]
parsed_url = urlparse.urlparse(path)
path = parsed_url.path

# send a response
c.send('HTTP/1.0 200 OK\r\n')
c.send('Content-type: text/html\r\n')
c.send('\r\n')
c.send('<h1>Hello, world.</h1>')
c.send('This is ctb\'s Web server.')
c.close()
conn.send('HTTP/1.0 200 OK\r\n')
conn.send('Content-type: text/html\r\n')
conn.send('\r\n')

if method == 'GET':
if path == '/':
index(conn)
elif path == '/content':
content(conn)
elif path == '/file':
file(conn)
elif path == '/image':
image(conn)
elif path == '/form':
form(conn)
elif path == '/submit':
parsed_query = urlparse.parse_qs(parsed_url.query)
submit(conn, parsed_query['firstname'][0],
parsed_query['lastname'][0])
elif method == 'POST':
if path == '/':
conn.send('<h1>We recieved a POST request!</h1>')
elif path == '/submit':
parsed_query = urlparse.parse_qs(con)
submit(conn, parsed_query['firstname'][0],
parsed_query['lastname'][0])


conn.close()

def main():
s = socket.socket() # Create a socket object
host = socket.getfqdn() # Get local machine name
port = random.randint(8000, 9999)
s.bind((host, port)) # Bind to the port

print 'Starting server on', host, port
print 'The Web server URL for this would be http://%s:%d/' % (host, port)

s.listen(5) # Now wait for client connection.


print 'Entering infinite loop; hit CTRL-C to exit'
while True:
# Establish connection with client.
c, (client_host, client_port) = s.accept()
print 'Got connection from', client_host, client_port

handle_connection(c)

if __name__ == '__main__':
main()
120 changes: 120 additions & 0 deletions test_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import server

class FakeConnection(object):
"""
A fake connection class that mimics a real TCP socket for the purpose
of testing socket I/O.
"""
def __init__(self, to_recv):
self.to_recv = to_recv
self.sent = ""
self.is_closed = False

def recv(self, n):
if n > len(self.to_recv):
r = self.to_recv
self.to_recv = ""
return r

r, self.to_recv = self.to_recv[:n], self.to_recv[n:]
return r

def send(self, s):
self.sent += s

def close(self):
self.is_closed = True

# Test a basic GET call.

def test_handle_connection_index():
conn = FakeConnection("GET / HTTP/1.0\r\n\r\n")
expected_return = 'HTTP/1.0 200 OK\r\n' + \
'Content-type: text/html\r\n' + \
'\r\n' + \
'<h1>Hello, world.</h1>' + \
'<p>This is foo\'s Web server.</p>' + \
'<p><a href = "content">content</p>' + \
'<p><a href = "file">file</p>' + \
'<p><a href = "image">image</p>' \
'<p><a href = "form">form</p>'

server.handle_connection(conn)

assert conn.sent == expected_return, 'Got: %s' % (repr(conn.sent),)

def test_handle_connection_content():
conn = FakeConnection("GET /content HTTP/1.0\r\n\r\n")
expected_return = 'HTTP/1.0 200 OK\r\n' + \
'Content-type: text/html\r\n' + \
'\r\n' + \
'<h1>You have reached the content page</h1>'

server.handle_connection(conn)

assert conn.sent == expected_return, 'Got: %s' % (repr(conn.sent),)

def test_handle_connection_file():
conn = FakeConnection("GET /file HTTP/1.0\r\n\r\n")
expected_return = 'HTTP/1.0 200 OK\r\n' + \
'Content-type: text/html\r\n' + \
'\r\n' + \
'<h1>You are currently visiting the file page</h1>'

server.handle_connection(conn)

assert conn.sent == expected_return, 'Got: %s' % (repr(conn.sent),)

def test_handle_connection_image():
conn = FakeConnection("GET /image HTTP/1.0\r\n\r\n")
expected_return = 'HTTP/1.0 200 OK\r\n' + \
'Content-type: text/html\r\n' + \
'\r\n' + \
'<h1>You are looking at the image page</h1>'

server.handle_connection(conn)

assert conn.sent == expected_return, 'Got: %s' % (repr(conn.sent),)

def test_handle_connection_post():
conn = FakeConnection("POST / HTTP/1.0\r\n\r\n")
expected_return = 'HTTP/1.0 200 OK\r\n' + \
'Content-type: text/html\r\n' + \
'\r\n' + \
'<h1>We recieved a POST request!</h1>'

server.handle_connection(conn)

assert conn.sent == expected_return, 'Got: %s' % (repr(conn.sent),)

def test_handle_connection_form():
conn = FakeConnection("GET /form HTTP/1.0\r\n\r\n")
expected_return = 'HTTP/1.0 200 OK\r\n' + \
'Content-type: text/html\r\n' + \
'\r\n' + \
'<form action="/submit" method="GET">' + \
'<p>Firstname</p><input type="text" name="firstname">' + \
'<p>Lastname</p><input type="text" name="lastname">''<input type="submit" value="Submit">' + \
'</form>'

server.handle_connection(conn)

def test_handle_connection_submit_get():
conn = FakeConnection("GET /submit?firstname=X&lastname=Y HTTP/1.0\r\n\r\n")
expected_return = 'HTTP/1.0 200 OK\r\n' + \
'Content-type: text/html\r\n' + \
'\r\n' + \
'<h1>Hello Mr. X Y</h1>'

server.handle_connection(conn)

def test_handle_connection_submit_post():
conn = FakeConnection("POST /submit HTTP/1.0" + \
"Content-Type: application/x-www-form-urlencoded" + \
"Content-Length: 30\r\n\r\n" + \
"firstname=X&lastname=Y")
expected_return = expected_return = 'HTTP/1.0 200 OK\r\n' + \
'Content-type: text/html\r\n' + \
'\r\n' + \
'<h1>Hello Mr. X Y</h1>'
server.handle_connection(conn)