http_proxy.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #!/usr/bin/env python
  2. import socket
  3. port = 8000
  4. def get_host(request_data):
  5. string = request_data.decode()
  6. host = ''
  7. i = 11
  8. while True:
  9. byte = string[i]
  10. if byte == ' ' or byte == '/':
  11. break
  12. host += byte
  13. i += 1
  14. print(f'Host: {host}')
  15. return host
  16. def forward_request(host, request_data):
  17. remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  18. remote_socket.connect((host, 80))
  19. remote_socket.sendall(request_data)
  20. print('Forwarded request to a remote server')
  21. return remote_socket
  22. def get_headers(remote_socket):
  23. response_data = b''
  24. flag = False
  25. while True:
  26. byte = remote_socket.recv(1)
  27. response_data += byte
  28. if response_data[-4:len(response_data)] == b'\r\n\r\n':
  29. break
  30. return response_data
  31. def get_content_length(headers):
  32. i = headers.decode().find("Content-Length")
  33. print(headers.decode())
  34. flag = False
  35. string_num = ''
  36. while True:
  37. char = headers.decode()[i]
  38. if char == '\n':
  39. break
  40. if char == ' ':
  41. flag = True
  42. if not flag:
  43. i +=1
  44. continue
  45. string_num +=char
  46. i += 1
  47. return int(string_num)
  48. def get_chunk_size(socket):
  49. chunk_size = b''
  50. while True:
  51. byte = socket.recv(1)
  52. if byte == b'\n':
  53. break
  54. chunk_size += byte
  55. #print("Size: ", chunk_size, " | ", int(chunk_size.decode(), 16) ," <<")
  56. return int(chunk_size.decode(), 16)
  57. def get_chunks(socket):
  58. response_data = b''
  59. while True:
  60. chunk_size = get_chunk_size(socket)
  61. if chunk_size == 0:
  62. break
  63. response_data += socket.recv(chunk_size+2)
  64. print(response_data.decode())
  65. return response_data
  66. def get_response_data(socket, headers):
  67. if headers.decode().find('chunked') != -1:
  68. response_data = get_chunks(socket)
  69. else:
  70. content_length = get_content_length(headers)
  71. response_data = socket.recv(content_length)
  72. return response_data
  73. def run_proxy_server(port):
  74. print("Start proxy server")
  75. server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  76. server_socket.bind(('localhost', port))
  77. server_socket.listen()
  78. while True:
  79. print(f'Proxy listen {port}...')
  80. client_socket, client_address = server_socket.accept()
  81. print(f'Connect to client: {client_address}')
  82. request_data = client_socket.recv(4096)
  83. host = get_host(request_data)
  84. try:
  85. remote_socket = forward_request(host, request_data)
  86. except:
  87. continue
  88. headers = get_headers(remote_socket)
  89. print(headers.decode())
  90. response_data = get_response_data(remote_socket, headers)
  91. print(f'Got response:\n{response_data}')
  92. client_socket.sendall(response_data)
  93. client_socket.close()
  94. if __name__ == '__main__':
  95. run_proxy_server(port)