Skip to content

Commit 7e161b9

Browse files
committed
2 parents f3d1a0d + a1c8dd5 commit 7e161b9

File tree

6 files changed

+65
-7
lines changed

6 files changed

+65
-7
lines changed
775 Bytes
Binary file not shown.
Binary file not shown.
Binary file not shown.

src/client/client_cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def main(sys_args):
4949
try:
5050
headers = json.loads(args.header)
5151
except json.JSONDecodeError:
52-
raise InvalidHeaderFormat("❌ Error: Invalid header format. Please provide valid JSON.")
52+
raise InvalidHeaderFormat("❌ Error:Formato de encabezado inválido. Por favor, proporcione un JSON válido.")
5353

5454
response: HTTPResponse = final_request(method=args.method, url=args.url, headers=headers, body=args.data)
5555

src/client/http_client.py

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
11
import socket
2+
import json
3+
import ssl
24
from http_parser import parse_http_url,parse_http_response
35
from exceptions import NotConnection
46

57
# GLOBAL VARIABLES
68
_versionHttp = 'HTTP/1.1'
7-
default_port = 80
9+
default_http_port = 80
10+
default_https_port = 443
811

912
class HttpClient:
1013

11-
def __init__(self,host, port :int, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, blocksize = 8192):
14+
def __init__(self,host, port :int,use_https,timeout=socket._GLOBAL_DEFAULT_TIMEOUT, blocksize = 8192):
1215

1316
self.host = host
1417
self.port = port
18+
self.use_https = use_https
1519
self.timeout = timeout
1620
self.mySocket = None
1721
self.blocksize = blocksize
1822

1923
# se hace uso del protocolo TCP/IP
2024
def connect (self):
2125
# se establece una conexion TCP con el servidor
22-
self.mySocket = socket.create_connection((self.host,self.port),self.timeout)
26+
raw_mySocket = socket.create_connection((self.host,self.port),self.timeout)
2327

28+
if self.use_https:
29+
# si es https se envuelve el socket en una conexion TLS/SSL
30+
context = ssl.create_default_context()
31+
self.mySocket = context.wrap_socket(raw_mySocket,server_hostname=self.host)
32+
33+
else: # si es HTTP
34+
self.mySocket = raw_mySocket
2435

2536
def request(self,method,url,body="", headers= None):
2637
# construye y envia una solicitud HTTP
@@ -70,8 +81,9 @@ def final_request (method="GET",url="/",headers = None,body =""):
7081
# extraer la informacion de la URL
7182
host,port,path,query = parse_http_url(url)
7283

84+
use_https = (port == default_https_port) or url.startswith("https://")
7385
# crear una instancia de HttpClient para establecer una conexion
74-
conn = HttpClient(host,port)
86+
conn = HttpClient(host,port,use_https)
7587

7688
data = None
7789

@@ -90,3 +102,49 @@ def final_request (method="GET",url="/",headers = None,body =""):
90102
# devuelve la respuesta parseada
91103
return data
92104

105+
106+
if __name__ == "__main__":
107+
108+
# Case 1 : My API - DownTrack
109+
host = "http://localhost:5217"
110+
endpoint = "/api/Authentication/register"
111+
112+
body = json.dumps({
113+
"id":33590,
114+
"name": "User_335",
115+
"userName": "username_33590",
116+
"email": "example3@gmail.com",
117+
"password": "Password_333!",
118+
"userRole": "Technician",
119+
"specialty": "mechanic",
120+
"salary": 19090,
121+
"expYears": 10,
122+
"departamentId": 1,
123+
"sectionId": 1
124+
})
125+
126+
headers = {
127+
"Content-Type": "application/json"
128+
}
129+
130+
response = final_request("POST", f"{host}{endpoint}", headers=headers, body=body)
131+
132+
print("Código de estado:", response.code)
133+
print("Encabezados:", response.headers)
134+
print("Cuerpo:", response.body[:500])
135+
136+
# Case 2: HTTPS
137+
138+
response = final_request("GET","https://reqres.in/api/users?page=2", headers={}, body="")
139+
140+
print("Código de estado:", response.code)
141+
print("Encabezados:", response.headers)
142+
print("Cuerpo:", response.body[:500])
143+
144+
# Case 3: HTTPS
145+
response = final_request("GET","https://jsonplaceholder.typicode.com", headers={}, body="")
146+
147+
print("Código de estado:", response.code)
148+
print("Encabezados:", response.headers)
149+
print("Cuerpo:", response.body[:500])
150+

src/client/http_parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55

66
def parse_http_url(url):
77
# Expresión regular para parsear la URL
8-
regex = r'^(http://)?([^:/\s]+)(?::(\d+))?(/[^?\s]*)?(\?[^#\s]*)?$'
8+
regex = r'^(https?://)?([^:/\s]+)(?::(\d+))?(/[^?\s]*)?(\?[^#\s]*)?$'
99
match = re.match(regex, url)
1010

1111
if not match:
1212
raise UrlIncorrect(f"Invalid URL: {url}")
1313

1414
scheme = match.group(1) or "http://" # Si no tiene esquema, asignamos "http://"
1515
host = match.group(2)
16-
port = match.group(3) or 80 # Si no tiene puerto, asignamos el puerto por defecto 80
16+
port = match.group(3) or (443 if scheme.startswith("https") else 80) # Si no tiene puerto, asignamos el puerto por defecto 80
1717
path = match.group(4) or "/" # Si no tiene path, asignamos "/"
1818
query = match.group(5) or "" # Si no tiene query, dejamos como cadena vacía
1919

0 commit comments

Comments
 (0)