0

This is my code for my seminar at university in computer network course.

Require: write a proxy web server. Receive HTTP request from the browser port 8888 and send HTTP request to web server port 80. It seems like I had trouble sending request to web server.

Could you show me my error in this situation?

Many thanks

import socket
import sys
import _thread
import traceback
import ssl
def CreateServer(host, port): 
    Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    Server.bind((host,port))
    Server.listen(5)
    return Server

def ReadRequest(Client):
    re = ""
    Client.settimeout(10.0)
try:
    re = Client.recv(1024).decode()
    while (re):
        re = re + Client.recv(1024).decode()
except socket.timeout: # fail after 1 second of no activity
    if not re:
        print("Didn't receive data! [Timeout]")
finally:
    return re

#2. Client connect Server + 3. Read HTTP Request
def ReadHTTPRequest(Server): 
    re = ""
    while (re == ""):
        Client, address = Server.accept()
        print("Client: ", address," da ket noi toi Server")
        re = ReadRequest(Client)
    return Client,address, re

def proxy_server(webserver, port, conn, data, addr):
    print("{} {} {} {}".format(webserver, port, conn, addr))
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(10.0)
        s.connect((webserver, port))
        s.sendall(data)
        while 1:
            reply = s.recv(1024)
            if len(reply) > 0:
                conn.send(reply)
                print("[*] Request sent: {} > {}".format(addr[0],webserver))
            else:
                break        
    
        s.close()
        conn.close()
    
    except Exception as e:
        print(e)
        traceback.print_exc()
        s.close()
        conn.close()
        sys.exit(1)

def conn_string(Client,Request,addr):
    try:
        #print(addr)
        first_line=Request.split('\n')[0]
        url=first_line.split(" ")[1]
        http_pos=url.find("://")
        if http_pos==-1:
            temp=url
        else:
            temp=url[(http_pos+3):]
        port_pos=temp.find(":")
        webserver_pos=temp.find("/")
        if webserver_pos == -1:
            webserver_pos = len(temp)
        webserver = ""
        port = -1
        if port_pos == -1 or webserver_pos < port_pos:
            port = 80
            webserver = temp[:webserver_pos]
        else:
            port = 80
            #port = int(temp[(port_pos + 1):][:webserver_pos - port_pos -1])
            webserver = temp[:port_pos]
        proxy_server(webserver,port,Client,Request.encode(),addr)
    except Exception as e:
        print (e)
        traceback.print_exc()



if __name__=="__main__":
    try:
        Server=CreateServer("",8888)
        print("[*] Intializing socket. Done.")
        print("[*] Socket binded successfully...")
        print("[*] Server started successfully [{}]".format(8888))
    except Exception as e:
        print(e)
        sys.exit(2)
    while True:
        try:
             Client,addr,Request=ReadHTTPRequest(Server)
             print("---------HTTP request: ")
             print(Request)
             _thread.start_new_thread(conn_string,(Client,Request,addr))
        except KeyboardInterrupt:
            Server.close()
            print("\n[*] Shutting down..")
            sys.exit()
    Server.close()


  [1]: https://i.sstatic.net/216ZO.png

1 Answer 1

1

You are simply forwarding the original request to the server, i.e. with the full URL inside the request:

GET http://ktdbcl.hcmus.edu.vn/ HTTP/1.1
Host: ktdbcl.hcmus.edu.vn
...

Instead only the path should be forwarded:

GET / HTTP/1.1
Host: ktdbcl.hcmus.edu.vn
...

Apart from that the reading of request and response is severely broken. You don't properly parse the HTTP protocol but instead simply wait some time and treat no data for some seconds as end of message. Since today multiple requests and responses will be done over the same connection your code will thus severely slow down any browsing.

Instead of waiting for multiple seconds for no data as the marker for end of request/response you should properly parse the HTTP protocol and wait for the appropriate end of request marker defined by the HTTP standard - see RFC 7230.

Sign up to request clarification or add additional context in comments.

2 Comments

Sorry if it bothers you, but im a newbie and i dont know how to parse http url to forward it, can you show me in detail? @Steffen Ullrich
@ChâuTrinh: Newbie is no excuse to let others do the work but should be a motivation to learn. Please make yourself familiar of how HTTP works - you'll find information in the standard I've linked to but also in Wikipedia. And the rest is coding, which you also should learn - especially if this is code for a seminar where it is likely expected that the work is your own.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.