Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: qwj/python-proxy
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: ligggooo/python-proxy
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.
  • 2 commits
  • 6 files changed
  • 1 contributor

Commits on Sep 18, 2024

  1. revise

    ligggooo committed Sep 18, 2024
    Copy the full SHA
    5fb0fe8 View commit details
  2. proxy

    ligggooo committed Sep 18, 2024
    Copy the full SHA
    4a77f7e View commit details
Showing with 462 additions and 59 deletions.
  1. +41 −0 learning/proxy_001.py
  2. +40 −0 learning/proxy_002.py
  3. +85 −0 learning/proxy_003.py
  4. +60 −0 learning/proxy_004.py
  5. +1 −1 pproxy/__main__.py
  6. +235 −58 pproxy/server.py
41 changes: 41 additions & 0 deletions learning/proxy_001.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import socket
import threading
import urllib.parse


def handle_client(client_socket: socket.socket):
request_data = client_socket.recv(4096)
request_lines = request_data.decode().split("\r\n")
method, url, protocol = request_lines[0].split()
url_parts = urllib.parse.urlparse(url)
print(url_parts, method, protocol)
hostname = url_parts.netloc
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.connect((hostname, 80))
server_socket.sendall(request_data)
while True:
response_data = server_socket.recv(4096)
if response_data:
print("==>", response_data.decode())
client_socket.sendall(request_data)
else:
break
client_socket.close()
server_socket.close()


def main():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ("0.0.0.0", 8888)
server_socket.bind(server_address)
server_socket.listen(5)
print("started at %s %d" % server_address)
while True:
client_socket, client_address = server_socket.accept()
client_thread = threading.Thread(target=handle_client, args=(client_socket,))
client_thread.start()


if __name__ == "__main__":
print("hello")
main()
40 changes: 40 additions & 0 deletions learning/proxy_002.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import http.server
import socketserver
import urllib.request

class ProxyHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
try:
# Forward the request to the target server
url = self.path
with urllib.request.urlopen(url) as response:
self.send_response(response.status)
self.send_header('Content-type', response.headers['Content-Type'])
self.end_headers()
self.wfile.write(response.read())
except Exception as e:
self.send_error(500, f"Error: {e}")

def do_POST(self):
try:
# Forward the request to the target server
url = self.path
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
req = urllib.request.Request(url, data=post_data, method='POST')
with urllib.request.urlopen(req) as response:
self.send_response(response.status)
self.send_header('Content-type', response.headers['Content-Type'])
self.end_headers()
self.wfile.write(response.read())
except Exception as e:
self.send_error(500, f"Error: {e}")

def run(server_class=http.server.HTTPServer, handler_class=ProxyHTTPRequestHandler, port=8888):
server_address = ('0.0.0.0', port)
httpd = server_class(server_address, handler_class)
print(f'Starting proxy server on port {port}...')
httpd.serve_forever()

if __name__ == '__main__':
run()
85 changes: 85 additions & 0 deletions learning/proxy_003.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import socket
import threading
import select

# Function to handle the connection between the client and the target server
def handle_client(client_socket):
request = client_socket.recv(4096)

# Parse the request to get the target server and port
first_line = request.split(b'\n')[0]
url = first_line.split(b' ')[1]

http_pos = url.find(b'://')
if http_pos == -1:
temp = url
else:
temp = url[(http_pos + 3):]

port_pos = temp.find(b':')

# Find the end of the web server
webserver_pos = temp.find(b'/')
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 = int((temp[(port_pos + 1):])[:webserver_pos - port_pos - 1])
webserver = temp[:port_pos]

# Create a socket to connect to the target server
proxy_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
proxy_socket.connect((webserver, port))
proxy_socket.send(request)

# Function to forward data from one socket to another
def forward(source, destination):
while True:
data = source.recv(4096)
if len(data) == 0:
break
destination.sendall(data)

# Start threads to forward data in both directions
client_to_proxy = threading.Thread(target=forward, args=(client_socket, proxy_socket))
proxy_to_client = threading.Thread(target=forward, args=(proxy_socket, client_socket))
client_to_proxy.start()
proxy_to_client.start()

# Wait for both threads to finish
client_to_proxy.join()
proxy_to_client.join()

# Close the sockets
client_socket.close()
proxy_socket.close()

# Function to start the proxy server
def start_proxy(local_host, local_port):
# Create a socket to listen for incoming connections
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((local_host, local_port))
server.listen(5)
print(f"[*] Listening on {local_host}:{local_port}")

while True:
# Accept an incoming connection
client_socket, addr = server.accept()
print(f"[*] Accepted connection from {addr[0]}:{addr[1]}")

# Start a new thread to handle the connection
client_handler = threading.Thread(target=handle_client, args=(client_socket,))
client_handler.start()

if __name__ == "__main__":
# Define the local address
LOCAL_HOST = "0.0.0.0"
LOCAL_PORT = 8888

# Start the proxy server
start_proxy(LOCAL_HOST, LOCAL_PORT)
60 changes: 60 additions & 0 deletions learning/proxy_004.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import socket
import threading

# Function to handle the connection between the client and the target server
def handle_client(client_socket, remote_host, remote_port):
# Connect to the remote server
remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote_socket.connect((remote_host, remote_port))

# Function to forward data from one socket to another
def forward(source, destination):
while True:
data = source.recv(4096)
if len(data) == 0:
break
destination.sendall(data)

# Start threads to forward data in both directions
client_to_remote = threading.Thread(target=forward, args=(client_socket, remote_socket))
remote_to_client = threading.Thread(target=forward, args=(remote_socket, client_socket))
client_to_remote.start()
remote_to_client.start()

# Wait for both threads to finish
client_to_remote.join()
remote_to_client.join()

# Close the sockets
client_socket.close()
remote_socket.close()

# Function to start the proxy server
def start_proxy(local_host, local_port, remote_host, remote_port):
# Create a socket to listen for incoming connections
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((local_host, local_port))
server.listen(5)
print(f"[*] Listening on {local_host}:{local_port}")

while True:
# Accept an incoming connection
client_socket, addr = server.accept()
print(f"[*] Accepted connection from {addr[0]}:{addr[1]}")

# Start a new thread to handle the connection
client_handler = threading.Thread(
target=handle_client,
args=(client_socket, remote_host, remote_port)
)
client_handler.start()

if __name__ == "__main__":
# Define the local and remote addresses
LOCAL_HOST = "0.0.0.0"
LOCAL_PORT = 9999
REMOTE_HOST = "example.com"
REMOTE_PORT = 80

# Start the proxy server
start_proxy(LOCAL_HOST, LOCAL_PORT, REMOTE_HOST, REMOTE_PORT)
2 changes: 1 addition & 1 deletion pproxy/__main__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
if __name__ == '__main__':
from .server import main
from server import main
main()
293 changes: 235 additions & 58 deletions pproxy/server.py

Large diffs are not rendered by default.