简体   繁体   中英

Python HTTP proxy Raw Sockets

I'm trying to implement a http proxy using raw sockets. Basically the idea is getting a request from the client , sending the request to the server , then getting the response , and sending back to the client. It looks easy but i have been trying to figuring out for about 2 days. Here the response gets corrupted . Thanks :)

import socket
import sys
import requests

def merr(requesti):
    hosti = requesti.split("Host: ")
    hosti = hosti[1]
    hosti = hosti.split("User-Agent: ")
    hosti = hosti[0]
    hosti = hosti.strip()
    return hosti

def merr_buff(data):
    try:
        temp = requesti.split("Content-Length:")
        temp = temp[1]
        temp = temp.split("\n")
        temp = temp[0]
        temp = temp.replace(" ","")
        print temp
        return temp
    except:
        pass



def dergo(requesti, hosti):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((hosti, 80))
    s.send(str(requesti))
    print requesti
    fdx = s.recv(10000)
    return str(fdx)


def bind():
    HOST = ''   
    PORT = 8080 

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    print 'Socket created'

    try:
        s.bind((HOST, PORT))
    except socket.error , msg:
        print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
        sys.exit()

    print 'Socket bind complete'

    s.listen(200)   

    print 'Socket now listening'

    conn, addr = s.accept()


    while 1:
        data = conn.recv(32000)
        if(data != ''):

            if(data.find("HTTP/1.1") != -1):


                target = merr(data)
                print  target
                response = dergo(data,target)
                conn.send(response)
                print "U dergua"

                conn.close()
                conn, addr = s.accept()




    s.close()


bind()

You don't specify how the response is corrupt, but here are some problems I noticed with your code.

When you are sending data, socket.send may not send the whole string, it will return the number of bytes transmitted. Instead you could use socket.sendall which will attempt to send the whole string.

Similarly when receiving data from a socket, socket.recv will receive up to the buffer size specified, however this may not be the full content of the connection. You should keep calling socket.recv until the return value evaluates as false, for example (taken from the docs):

while 1:
    data = conn.recv(1024)
    if not data: break
    conn.sendall(data)
conn.close()

Try making these changes in your software and report back.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM