Search code examples
pythonsocketsproxy-server

Homework - Python Proxy Server


For a programming exercise (from Computer Networking: A Top-Down Approach (6th Edition) by Kurose and Ross), we're trying to develop a simple proxy server in python.

We were given the following code, wherever it says #Fill in start. ... #Fill in end. that is where we need to write code. My specific question and attempts will be below this original snippet.

We need to start the python server with: python proxyserver.py [server_ip] then navigate to localhost:8888/google.com and it should work when we're finished.

from socket import *
import sys
if len(sys.argv) <= 1:
  print 'Usage : "python ProxyServer.py server_ip"\n[server_ip : It is the IP Address Of Proxy Server'
  sys.exit(2)

# Create a server socket, bind it to a port and start listening 
tcpSerSock = socket(AF_INET, SOCK_STREAM)
# Fill in start.
# Fill in end.

while 1:
  # Strat receiving data from the client
  print 'Ready to serve...'
  tcpCliSock, addr = tcpSerSock.accept()
  print 'Received a connection from:', addr 
  message = # Fill in start. # Fill in end. print message

  # Extract the filename from the given message print message.split()[1]
  filename = message.split()[1].partition("/")[2] print filename
  fileExist = "false"
  filetouse = "/" + filename
  print filetouse
  try:
    # Check wether the file exist in the cache
    f = open(filetouse[1:], "r")
    outputdata = f.readlines()
    fileExist = "true"

    # ProxyServer finds a cache hit and generates a response message     
    tcpCliSock.send("HTTP/1.0 200 OK\r\n") 
    tcpCliSock.send("Content-Type:text/html\r\n")
    # Fill in start.
    # Fill in end.
      print 'Read from cache'
  # Error handling for file not found in cache
except IOError:
  if fileExist == "false":
    # Create a socket on the proxyserver
    c = # Fill in start. # Fill in end. 
    hostn = filename.replace("www.","",1)
    print hostn
      try:
        # Connect to the socket to port 80
        # Fill in start.
        # Fill in end.

        # Create a temporary file on this socket and ask port 80 for the file requested by the client
        fileobj = c.makefile('r', 0)
        fileobj.write("GET "+"http://" + filename + "HTTP/1.0\n\n")

        # Read the response into buffer
        # Fill in start.
        # Fill in end.

        # Create a new file in the cache for the requested file. 
        # Also send the response in the buffer to client socket and the corresponding file in the cache
        tmpFile = open("./" + filename,"wb")
        # Fill in start.
        # Fill in end.
      except:
        print "Illegal request"
    else:
      # HTTP response message for file not found 
      # Fill in start.
      # Fill in end.
  # Close the client and the server sockets
    tcpCliSock.close()
# Fill in start.
# Fill in end.

Where it says:

# Create a socket on the proxyserver
c = # Fill in start. # Fill in end. 

I tried:

c = socket(AF_INET, SOCK_STREAM)

This seems to be how you create a socket, then for connecting to port 80 of the host, I have:

c.connect((hostn, 80))

Here, hostn is correctly google.com according to some local print statements I have. The next section for me to fill in says to #Read response into buffer but I don't really understand what that means. I presume it has something to do with the fileobj that is created just above.

Thanks in advance, please let me know if I missed anything I should be adding.

UPDATE

My current code can be found here to see what I've been trying:

https://github.com/ardavis/Computer-Networks/blob/master/Lab%203/ProxyServer.py


Solution

  • This seems to be my potential solution. The pdf from the homework mentions I need to do something at the end, not sure what it is. But the cache and proxy seems to function with this. I hope it helps someone else.

    from socket import *
    import sys
    
    if len(sys.argv) <= 1:
        print 'Usage: "python ProxyServer.py server_ip"\n[server_ip : It is the IP Address of the Proxy Server'
        sys.exit(2)
    
    # Create a server socket, bind it to a port and start listening
    tcpSerPort = 8888
    tcpSerSock = socket(AF_INET, SOCK_STREAM)
    
    # Prepare a server socket
    tcpSerSock.bind(('', tcpSerPort))
    tcpSerSock.listen(5)
    
    while True:
        # Start receiving data from the client
        print 'Ready to serve...'
        tcpCliSock, addr = tcpSerSock.accept()
        print 'Received a connection from: ', addr
        message = tcpCliSock.recv(1024)
    
        # Extract the filename from the given message
        print message.split()[1]
        filename = message.split()[1].partition("/")[2]
        fileExist = "false"
        filetouse = "/" + filename
        try:
            # Check whether the file exists in the cache
            f = open(filetouse[1:], "r")
            outputdata = f.readlines()
            fileExist = "true"
            print 'File Exists!'
    
            # ProxyServer finds a cache hit and generates a response message
            tcpCliSock.send("HTTP/1.0 200 OK\r\n")
            tcpCliSock.send("Content-Type:text/html\r\n")
    
            # Send the content of the requested file to the client
            for i in range(0, len(outputdata)):
                tcpCliSock.send(outputdata[i])
            print 'Read from cache'
    
            # Error handling for file not found in cache
        except IOError:
            print 'File Exist: ', fileExist
            if fileExist == "false":
                # Create a socket on the proxyserver
                print 'Creating socket on proxyserver'
                c = socket(AF_INET, SOCK_STREAM)
    
                hostn = filename.replace("www.", "", 1)
                print 'Host Name: ', hostn
                try:
                    # Connect to the socket to port 80
                    c.connect((hostn, 80))
                    print 'Socket connected to port 80 of the host'
    
                    # Create a temporary file on this socket and ask port 80
                    # for the file requested by the client 
                    fileobj = c.makefile('r', 0)
                    fileobj.write("GET " + "http://" + filename + " HTTP/1.0\n\n")
    
                    # Read the response into buffer
                    buff = fileobj.readlines() 
    
                    # Create a new file in the cache for the requested file.
                    # Also send the response in the buffer to client socket
                    # and the corresponding file in the cache
                    tmpFile = open("./" + filename, "wb")
                    for i in range(0, len(buff)):
                        tmpFile.write(buff[i])
                        tcpCliSock.send(buff[i])
    
                except:
                    print 'Illegal request'
    
            else:
                # HTTP response message for file not found
                # Do stuff here
                print 'File Not Found...Stupid Andy'
                a = 2
        # Close the socket and the server sockets
        tcpCliSock.close()
    
    # Do stuff here