86 lines
1.7 KiB
Python
86 lines
1.7 KiB
Python
|
import json
|
||
|
|
||
|
from datetime import datetime
|
||
|
from izzylib import url
|
||
|
|
||
|
from ..http_utils import (
|
||
|
Headers,
|
||
|
Cookies,
|
||
|
convert_to_bytes,
|
||
|
create_message,
|
||
|
first_line,
|
||
|
methods,
|
||
|
ports
|
||
|
)
|
||
|
|
||
|
try: from ..http_signatures import sign_request
|
||
|
except ImportError: sign_request = None
|
||
|
|
||
|
|
||
|
class Request:
|
||
|
def __init__(self, url, body=None, headers={}, cookies={}, method='GET'):
|
||
|
method = method.upper()
|
||
|
|
||
|
if method not in methods:
|
||
|
raise ValueError(f'Invalid HTTP method: {method}')
|
||
|
|
||
|
self._body = b''
|
||
|
|
||
|
self.version = 1.1
|
||
|
self.url = Url(url)
|
||
|
self.headers = Headers(headers)
|
||
|
self.cookies = Cookies(cookies)
|
||
|
self.method = method
|
||
|
|
||
|
if self.url.proto not in ['http', 'https', 'ws', 'wss']:
|
||
|
raise ValueError(f'Invalid protocol in url: {self.url.proto}')
|
||
|
|
||
|
if not self.headers.get('host'):
|
||
|
self.headers.host = self.host
|
||
|
|
||
|
|
||
|
@property
|
||
|
def body(self):
|
||
|
return self._body
|
||
|
|
||
|
|
||
|
@body.setter
|
||
|
def body(self, data):
|
||
|
self._body = convert_to_bytes(data)
|
||
|
self.headers.setall('Content-Length', str(len(self._body)))
|
||
|
|
||
|
|
||
|
@property
|
||
|
def host(self):
|
||
|
return self.url.host
|
||
|
|
||
|
|
||
|
@property
|
||
|
def port(self):
|
||
|
return self.url.port or ports[self.url.proto]
|
||
|
|
||
|
|
||
|
@property
|
||
|
def secure(self):
|
||
|
return self.url.proto in ['https', 'wss']
|
||
|
|
||
|
|
||
|
def set_header(self, key, value):
|
||
|
self.headers.setall(key, value)
|
||
|
|
||
|
|
||
|
def unset_header(self, key):
|
||
|
self.headers.pop(key, None)
|
||
|
|
||
|
|
||
|
def sign_headers(self, privkey, keyid):
|
||
|
if not sign_request:
|
||
|
raise ImportError(f'Could not import HTTP signatures. Header signing disabled')
|
||
|
|
||
|
return sign_request(self, privkey, keyid)
|
||
|
|
||
|
|
||
|
def compile(self):
|
||
|
first = first_line(method=self.method, path=self.url.path_full)
|
||
|
return create_message(first, self.headers, self.cookies, self.body)
|