HTTP Client Request

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 6

"""

b'GET / HTTP/1.1\r\nHost: localhost:25000\r\nUpgrade-Insecure-Requests: 1\r\


nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nUser-
Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML,
like Gecko) Version/13.1.1 Safari/605.1.15\r\nAccept-Language: en-gb\r\nAccept-
Encoding: gzip, deflate\r\nConnection: keep-alive\r\n\r\n'

SENDED :
for http request : get
b'GET /?address=10+rue+des+chardonnerets+31270+villeneuve+tolosane HTTP/1.1\r\
nHost: 127.0.0.1:65432\r\nUser-Agent: python-requests/2.24.0\r\nAccept-Encoding:
gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
sended : http get request with test as param
b'GET /?test HTTP/1.1\r\nHost: 127.0.0.1:65432\r\nUser-Agent:
python-requests/2.24.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\
nConnection: keep-alive\r\n\r\n'
sended : http get request with 2 entries as param, dict :
b'GET /?address=10+rue+des+chardonnerets+31270+villeneuve+tolosane&anothet=123
HTTP/1.1\r\nHost: 127.0.0.1:46527\r\nUser-Agent: python-requests/2.24.0\r\nAccept-
Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
sended : http get request no param
b'GET / HTTP/1.1\r\nHost: 127.0.0.1:46527\r\nUser-Agent: python-requests/2.24.0\r\
nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
sended : http request post
b'POST /?Hello%20world! HTTP/1.1\r\nHost: 127.0.0.1:46527\r\nUser-Agent: python-
requests/2.24.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection:
keep-alive\r\nContent-Length: 0\r\n\r\n'
sended http request post with header test: gg
b'POST / HTTP/1.1\r\nHost: 127.0.0.1:46527\r\nUser-Agent: python-requests/2.24.0\r\
nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\ntest:
gg\r\nContent-Length: 0\r\n\r\n'
b'GET / HTTP/1.1\r\nHost: localhost:25000\r\nUpgrade-Insecure-Requests: 1\r\
nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nUser-
Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML,
like Gecko) Version/13.1.1 Safari/605.1.15\r\nAccept-Language: en-gb\r\nAccept-
Encoding: gzip, deflate\r\nConnection: keep-alive\r\n\r\n'
possible answer
#{"Host" : None, "User-Agent" : "Googlebot", "Connection" : "close"} -> header
#Some chars may not be sended correctly. -> for ' ' or so, use % + 0*(2-len(c)) +
hex(ord(char))[2:]
#TODO -> create two folders one server and one client with an http request parser
and an http request maker.
#setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
#Test purposes only.
"""

from select import select


from socket import socket, AF_INET, AF_INET6, SOCK_STREAM, timeout
from threading import Thread
from time import sleep
from os import stat, listdir, path

def launch_http_server(host='localhost', port=25000, data=b"", rsize=1024,


root=""):
global LOOP
LOOP = True
print("Server available @: http://{0}:{1}/".format(host, port))
server_socket = socket(AF_INET, SOCK_STREAM)
try:
server_socket.bind((host, port))
except:
server_socket = socket(AF_INET6, SOCK_STREAM)
try:
server_socket.bind((host, port))
except:
raise RuntimeError("Unable to connect to {0}:{1}".format(host,
port))
while LOOP:
error = True
while error and LOOP:
try:
error = False
server_socket.listen()
server_socket.settimeout(1)
client_socket, address = server_socket.accept()#address =
(client_host, client_port)
except timeout as e:
error = True
if not LOOP: break
wfd = open("buffer.bin", "wb")
version, method, uri, parameters, header =
raw_http_server_parser(client_socket, wfd)
if method == "GET":
if uri == "": uri = "index.html" #The browser might do something
tricky with the website's name when on a local network.
print("Client @{0}".format(address))
if path.exists(root+uri) and path.isfile(root+uri):
raw_http_server_request(client_socket, 200, "OK",
{"Connection": "close", "Content-Length": str(stat(uri).st_size), "Content-Type":
"text; charset=UTF-8", "Accept-Ranges": "bytes"}, uri, 1.0, 256)
else:
raw_http_server_request(client_socket, 404, "Not Found",
{"Connection": "close"}, b"", 1.0)
wfd.close()
client_socket = select([], [client_socket], [])[1][0]
client_socket.send(data)
client_socket.close()
print('Server stopped.')
server_socket.close()
return

def start_http_server(host='localhost', port=25000, data=b"", rsize=1024):


server_thread = Thread(target=launch_http_server, args=(host, port, data,
rsize, ""))
server_thread.start()
return (host, port)

def stop_http_server():
global LOOP
LOOP = False
#----- HTTP Client Request Function -----
def raw_http_client_request(sock, method: str, uri: str ="", parameters: list =[],
header: dict ={}, data=b"", version: float =1.0, rwsize: int =256):
sock.send(str(method).encode("ascii") + b" /" + str(uri).encode("ascii"))
if parameters:
sock.send(b"?")
if not isinstance(parameters, str):
i = 0
for item in parameters:
sock.send(str(item).encode('ascii'))
if isinstance(parameters, dict):
sock.send(b"=" + parameters[item].encode("ascii"))
if i < len(parameters)-1:
sock.send(b"&")
i += 1
else:
sock.send(str(parameters).encode('ascii'))
sock.send(b" HTTP/" + str(version).encode("ascii") + b"\r\n")
for key in header:
sock.send(str(key).encode("ascii") + b": " +
str(header[key]).encode("ascii") + b"\r\n")
sock.send(b"\r\n")
if isinstance(data, bytes):
sock.send(data)
else:
fd = open(str(data), 'rb')
while True:
temp = fd.read(rwsize)
sock.send(temp)
if len(temp) < rwsize: break
fd.close()
return

#----- HTTP Server Request Function -----


def raw_http_server_request(sock, status: int, message: str, header: dict ={},
data=b"", version: float =1.0, rwsize: int =256):
sock.send(b"HTTP/" + str(version).encode("ascii") + b" " +
str(status).encode("ascii") + b" " + str(message).encode("ascii") + b"\r\n")
for key in header:
sock.send(str(key).encode("ascii") + b": " +
str(header[key]).encode("ascii") + b"\r\n")
sock.send(b"\r\n")
if isinstance(data, bytes):
sock.send(data)
else:
fd = open(str(data), "rb")
while True:
temp = fd.read(rwsize)
sock.send(temp)
if len(temp) < rwsize: break
fd.close()
return

#----- HTTP Client Parser Function -----


b'HTTP/1.0 200 OK\r\nAccept-Ranges: bytes\r\nAge: 412973\r\nCache-Control: max-
age=604800\r\nContent-Type: text/html; charset=UTF-8\r\nDate: Tue, 04 Jan 2022
17:19:01 GMT\r\nEtag: "3147526947"\r\nExpires: Tue, 11 Jan 2022 17:19:01 GMT\r\
nLast-Modified: Thu, 17 Oct 2019 07:18:26 GMT\r\nServer: ECS (dcb/7F83)\r\nVary:
Accept-Encoding\r\nX-Cache: HIT\r\nContent-Length: 1256\r\nConnection: close\r\n\r\
n<!doctype html>\n<html>\n<head>\n <title>Example Domain</title>\n\n <meta
charset="utf-8" />\n <meta http-equiv="Content-type" content="text/html;
charset=utf-8" />\n <meta name="viewport" content="width=device-width, initial-
scale=1" />\n <style type="text/css">\n body {\n background-color:
#f0f0f2;\n margin: 0;\n padding: 0;\n font-family: -apple-
system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue",
Helvetica, Arial, sans-serif;\n \n }\n div {\n width: 600px;\n
margin: 5em auto;\n padding: 2em;\n background-color: #fdfdff;\n
border-radius: 0.5em;\n box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\
n }\n a:link, a:visited {\n color: #38488f;\n text-decoration:
none;\n }\n @media (max-width: 700px) {\n div {\n margin: 0
auto;\n width: auto;\n }\n }\n </style> \n</head>\n\
n<body>\n<div>\n <h1>Example Domain</h1>\n <p>This domain is for use in
illustrative examples in documents. You may use this\n domain in literature
without prior coordination or asking for permission.</p>\n <p><a
href="https://www.iana.org/domains/example">More information...</a></p>\n</div>\
n</body>\n</html>\n'
def raw_http_client_parser(sock, fd, rsize=256):
status_code = 0
status_message = ""
version = ""
header = {}
data_buffer = b""
length = 0
start_header = True
while start_header or length > 0:
sock = select([sock], [], [])[0][0]#r,w,e
data_buffer += sock.recv(rsize)
if start_header and b"\r\n\r\n" in data_buffer:
index = data_buffer.find(b"\r\n\r\n")#b"\r\n\r\n" -> pattern and
4 lower is the pattern's length
temp = data_buffer[:index].decode("ascii").split("\r\n")
version, status_code, status_message = temp[0].split(' ')
version = version.split('/')[1]
del temp[0]
data_buffer = data_buffer[index+4:]
for element in temp:
key = element[:element.find(":")] #temporary
value = element[element.find(":")+1:].lstrip(' ')#
variables
header[key] = value
if "Content-Length" in header: length = int(header["Content-
Length"])
start_header = False
fd.write(data_buffer)
length -= len(data_buffer)
data_buffer = b""
pass
if not start_header:
fd.write(data_buffer)
if len(data_buffer) < rsize: break#Used for the head method
answer
length -= rsize
#print(length)
return (version, status_code, status_message, header)
#----- HTTP Server Request Parser Function -----
#NOTE -> Could be optimized.
def raw_http_server_parser(sock, fd, rsize=256, limit=0xffffffff):
header = {}
method = ""
uri = ""
parameters = ""
data_buffer = b""
length = 0
start_header = True
while start_header or (length > 0 and length < limit):
sock = select([sock], [], [])[0][0]#r,w,e
data_buffer += sock.recv(rsize)
if start_header and b"\r\n\r\n" in data_buffer:
index = data_buffer.find(b"\r\n\r\n")#b"\r\n\r\n" -> pattern and
4 lower is the pattern's length
temp = data_buffer[:index].decode("ascii").split("\r\n")
method, uri, version = temp[0].split(' ')
uri = uri.lstrip("/")
if "?" in uri:
uri, parameters = uri.split("?")
version = temp[0].split(' ')[2].split('/')[1]
del temp[0]
data_buffer = data_buffer[index+4:]
for element in temp:
key = element[:element.find(":")] #temporary
value = element[element.find(":")+1:].lstrip(' ')#
variables
header[key] = value
if "Content-Length" in header: length = int(header["Content-
Length"])
start_header = False
fd.write(data_buffer)
length -= len(data_buffer)
data_buffer = b""
pass
if not start_header:
fd.write(data_buffer)
if len(data_buffer) < rsize: break#Used for the head method
answer
length -= rsize
#print(length)
return (version, method, uri, parameters, header)

#----- URI Versatile Encoder -----


UNRESERVED = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'-', '_', '.', '~']
RESERVED = ['!', '#', '$', '&', "'", '(', ')', '*', '+', ',', '/', ':', ';', '=',
'?', '@', '[', ']']

def encodeURI(uri, characters_encoding="utf-8",


unreserved_chracter_set=UNRESERVED):
uri = str(uri).encode(characters_encoding)
str_uri = ""
for c in uri:
if chr(c) in unreserved_chracter_set:
str_uri += chr(c)
else:
str_uri += "%" + "0" * (2-len(hex(c)[2:])) + hex(c)[2:].upper()
return str_uri

#----- Commands Executioner -----


cmds = []
funcs = []

def register_cmd(cmd, func):


global cmds, funcs
cmds.append(cmd)
funcs.append(func)

def unregister_cmd(cmd):
global cmds, funcs
i = cmds.index(cmd)
if i >= 0:
del funcs[i], cmds[i]

def execute_cmd(cmd, *args):


global cmds, funcs
if cmd in cmds:
return funcs[cmds.index(cmd)](*args)
return None

from sys import exit

#----- Main -----


if __name__ == "__main__":
register_cmd("STOPSERVER", stop_http_server)
register_cmd("STARTSERVER", start_http_server)
register_cmd("EXIT", exit)
while True:
cmdstr = input("+> ")
cmd, args = cmdstr.split(" ")[0], cmdstr.split(" ")[1:]
execute_cmd(cmd, *args)

#%C3%A7%D0%BF ->for: çп
#%C3%A7 ->for: ç
#%D0%BF ->for: п

"""
["GET", "POST", "HEAD", "TRACE", "PUT", "DELETE", "CONNECT", "OPTIONS", "PATCH"]
1.1
{"Host:" : None, "User-Agent:" : "Googlebot", "Connection:" : "close"}
80

for server -> each conn has a security number that can be changed through post with
the given good passwords and all. -> each request processing depends on whether the
security number of the connection is correct or not.

"""

You might also like