add trabalho5
This commit is contained in:
parent
bd74985f8f
commit
83606d3a97
|
@ -0,0 +1,165 @@
|
||||||
|
import socket
|
||||||
|
import select
|
||||||
|
from threading import Thread
|
||||||
|
import time
|
||||||
|
import logging
|
||||||
|
import logging.handlers
|
||||||
|
|
||||||
|
LOGGER_HOST = "localhost"
|
||||||
|
LOGGER_PORT = 514
|
||||||
|
|
||||||
|
CURRENT_THREADS = 0
|
||||||
|
MAX_THREADS = 10
|
||||||
|
BACKLOG = 50
|
||||||
|
|
||||||
|
class Logger:
|
||||||
|
_instance = None
|
||||||
|
def __init__(self):
|
||||||
|
self.logger = logging.getLogger('PythonProxy')
|
||||||
|
self.logger.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
handler = logging.handlers.SysLogHandler(address = (LOGGER_HOST, LOGGER_PORT))
|
||||||
|
|
||||||
|
self.logger.addHandler(handler)
|
||||||
|
|
||||||
|
self.logger.debug('Initiating Proxy logger!')
|
||||||
|
|
||||||
|
def log(self, message:str):
|
||||||
|
self.logger.debug(message)
|
||||||
|
print('INFO:', message)
|
||||||
|
|
||||||
|
def critical(self, message:str):
|
||||||
|
self.logger.critical(message)
|
||||||
|
print('CRITICAL:', message)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.logger.close()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def instance(self):
|
||||||
|
if self._instance is None:
|
||||||
|
self._instance = self()
|
||||||
|
return self._instance
|
||||||
|
|
||||||
|
|
||||||
|
class Server:
|
||||||
|
def __init__(self, host:str, port:int):
|
||||||
|
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
self.sock.bind((host, port))
|
||||||
|
self.sock.listen(BACKLOG)
|
||||||
|
print(f"Listening at: http://{host}:{port}")
|
||||||
|
|
||||||
|
def thread_check(self):
|
||||||
|
global CURRENT_THREADS, MAX_THREADS
|
||||||
|
while True:
|
||||||
|
if CURRENT_THREADS >= MAX_THREADS:
|
||||||
|
time.sleep(1)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
global CURRENT_THREADS
|
||||||
|
while True:
|
||||||
|
conn, client_addr = self.sock.accept()
|
||||||
|
self.thread_check()
|
||||||
|
|
||||||
|
CURRENT_THREADS += 1
|
||||||
|
thread = Thread(target = connectionHandle, args = (conn, client_addr, ))
|
||||||
|
CURRENT_THREADS -= 1
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.sock.close()
|
||||||
|
|
||||||
|
def connectionHandle(client_socket, client_address):
|
||||||
|
# print(f"Connection received from {client_address[0]}:{client_address[1]}")
|
||||||
|
|
||||||
|
request = client_socket.recv(16 * 1024)
|
||||||
|
logger = Logger.instance()
|
||||||
|
|
||||||
|
if len(request) == 0:
|
||||||
|
client_socket.close()
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
raw_request = request.decode()
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
print("UnicodeDecodeError")
|
||||||
|
client_socket.close()
|
||||||
|
return
|
||||||
|
|
||||||
|
if "CONNECT" in raw_request:
|
||||||
|
client_socket.sendall(b"HTTP/1.1 200 Connection Established\r\n\r\n")
|
||||||
|
request = client_socket.recv(16 * 1024)
|
||||||
|
|
||||||
|
request_url = raw_request.split(' ')[1]
|
||||||
|
request_host = ""
|
||||||
|
request_port = 443 if 'https' in request_url else 80
|
||||||
|
|
||||||
|
if request_url.startswith('http'):
|
||||||
|
request_host = request_url.split('/')[2]
|
||||||
|
else:
|
||||||
|
request_host = request_url.split('/')[0]
|
||||||
|
|
||||||
|
if request_host.startswith('www'):
|
||||||
|
request_host = request_host[4:]
|
||||||
|
|
||||||
|
if ':' in request_host:
|
||||||
|
request_port = int(request_host.split(':')[1])
|
||||||
|
request_host = request_host.split(':')[0]
|
||||||
|
|
||||||
|
# print(f"REQUEST [{client_address[0]}:{client_address[1]}] {raw_request}")
|
||||||
|
|
||||||
|
if "monitorando" in request_url:
|
||||||
|
body = "<HTML><HEAD><TITLE>403</TITLE><meta charset=\"UTF-8\"></HEAD> <BODY>Acesso não autorizado!</BODY> </HTML>"
|
||||||
|
client_socket.sendall(b"HTTP/1.1 403 Forbidden\r\n\r\n")
|
||||||
|
client_socket.sendall(body.encode())
|
||||||
|
client_socket.close()
|
||||||
|
return
|
||||||
|
|
||||||
|
# forward the request to the destination server
|
||||||
|
# print(f"Forwarding request to {request_host}:{request_port}")
|
||||||
|
destination_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
destination_socket.connect((request_host, request_port))
|
||||||
|
destination_socket.sendall(request)
|
||||||
|
|
||||||
|
# print(f"Waiting for response from {request_host}:{request_port}")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
triple = select.select([client_socket, destination_socket], [], [], 20)[0]
|
||||||
|
if not len(triple):
|
||||||
|
break
|
||||||
|
try:
|
||||||
|
if client_socket in triple:
|
||||||
|
data = client_socket.recv(16 * 1024)
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
destination_socket.send(data)
|
||||||
|
if destination_socket in triple:
|
||||||
|
data = destination_socket.recv(16 * 1024)
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
|
||||||
|
try:
|
||||||
|
status_code = data.decode().split(' ')[1:]
|
||||||
|
status_code = ' '.join(status_code)
|
||||||
|
logger.log(f"REQUEST [{client_address[0]}:{client_address[1]}] to [{request_host}:{request_port}] - {status_code} ({len(data)} bytes)")
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
client_socket.send(data)
|
||||||
|
except ConnectionAbortedError:
|
||||||
|
break
|
||||||
|
|
||||||
|
# print(f"Closing connection with {request_host}:{request_port} and {client_address[0]}:{client_address[1]}")
|
||||||
|
|
||||||
|
# close the sockets
|
||||||
|
destination_socket.close()
|
||||||
|
client_socket.close()
|
||||||
|
|
||||||
|
# print("Connection closed")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
ser = Server(host="0.0.0.0", port=8080)
|
||||||
|
ser.start()
|
Loading…
Reference in New Issue