hio.core.http.httping

hio.core.http.httping module http async io (nonblocking) support

Module Contents

Classes

EventSource

Server Sent Event Stream Client parser

Parsent

Base class for objects that parse HTTP messages

Functions

httpDate1123(dt)

Return a string representation of a date according to RFC 1123

normalizeHostPort(host, port=None, defaultPort=80)

Given hostname host which could also be netloc which includes port

parseQuery(query)

Return dict of parsed query string.

updateQargsQuery(qargs=None, query='')

Returns duple of updated (qargs, query)

unquoteQuery(query)

Returns query string with unquoted values

packHeader(name, *values)

Format and return a header line.

packChunk(msg)

Return msg bytes in a chunk

parseLine(raw, eols=(CRLF, LF, CR), kind='event line')

Generator to parse line from raw bytearray

parseLeader(raw, eols=(CRLF, LF), kind='leader header line', headers=None)

Generator to parse entire leader of header lines from raw bytearray

parseChunk(raw)

Generator to parse next chunk from raw bytearray

parseBom(raw, bom=codecs.BOM_UTF8)

Generator to parse bom from raw bytearray

parseStatusLine(line)

Parse the response status line

parseRequestLine(line)

Parse the request start line

Attributes

CRLF

LF

CR

MAX_LINE_SIZE

MAX_HEADERS

HTTP_PORT

HTTPS_PORT

HTTP_11_VERSION_STRING

CONTINUE

SWITCHING_PROTOCOLS

PROCESSING

OK

CREATED

ACCEPTED

NON_AUTHORITATIVE_INFORMATION

NO_CONTENT

RESET_CONTENT

PARTIAL_CONTENT

MULTI_STATUS

IM_USED

MULTIPLE_CHOICES

MOVED_PERMANENTLY

FOUND

SEE_OTHER

NOT_MODIFIED

USE_PROXY

TEMPORARY_REDIRECT

BAD_REQUEST

UNAUTHORIZED

PAYMENT_REQUIRED

FORBIDDEN

NOT_FOUND

METHOD_NOT_ALLOWED

NOT_ACCEPTABLE

PROXY_AUTHENTICATION_REQUIRED

REQUEST_TIMEOUT

CONFLICT

GONE

LENGTH_REQUIRED

PRECONDITION_FAILED

REQUEST_ENTITY_TOO_LARGE

REQUEST_URI_TOO_LONG

UNSUPPORTED_MEDIA_TYPE

REQUESTED_RANGE_NOT_SATISFIABLE

EXPECTATION_FAILED

UNPROCESSABLE_ENTITY

LOCKED

FAILED_DEPENDENCY

UPGRADE_REQUIRED

PRECONDITION_REQUIRED

TOO_MANY_REQUESTS

REQUEST_HEADER_FIELDS_TOO_LARGE

INTERNAL_SERVER_ERROR

NOT_IMPLEMENTED

BAD_GATEWAY

SERVICE_UNAVAILABLE

GATEWAY_TIMEOUT

HTTP_VERSION_NOT_SUPPORTED

INSUFFICIENT_STORAGE

NOT_EXTENDED

NETWORK_AUTHENTICATION_REQUIRED

STATUS_DESCRIPTIONS

METHODS

MAXAMOUNT

_MAXLINE

_MAXHEADERS

hio.core.http.httping.CRLF = b'\r\n'[source]
hio.core.http.httping.LF = b'\n'[source]
hio.core.http.httping.CR = b'\r'[source]
hio.core.http.httping.MAX_LINE_SIZE = 65536[source]
hio.core.http.httping.MAX_HEADERS = 100[source]
hio.core.http.httping.HTTP_PORT = 80[source]
hio.core.http.httping.HTTPS_PORT = 443[source]
hio.core.http.httping.HTTP_11_VERSION_STRING = HTTP/1.1[source]
hio.core.http.httping.CONTINUE = 100[source]
hio.core.http.httping.SWITCHING_PROTOCOLS = 101[source]
hio.core.http.httping.PROCESSING = 102[source]
hio.core.http.httping.OK = 200[source]
hio.core.http.httping.CREATED = 201[source]
hio.core.http.httping.ACCEPTED = 202[source]
hio.core.http.httping.NON_AUTHORITATIVE_INFORMATION = 203[source]
hio.core.http.httping.NO_CONTENT = 204[source]
hio.core.http.httping.RESET_CONTENT = 205[source]
hio.core.http.httping.PARTIAL_CONTENT = 206[source]
hio.core.http.httping.MULTI_STATUS = 207[source]
hio.core.http.httping.IM_USED = 226[source]
hio.core.http.httping.MULTIPLE_CHOICES = 300[source]
hio.core.http.httping.MOVED_PERMANENTLY = 301[source]
hio.core.http.httping.FOUND = 302[source]
hio.core.http.httping.SEE_OTHER = 303[source]
hio.core.http.httping.NOT_MODIFIED = 304[source]
hio.core.http.httping.USE_PROXY = 305[source]
hio.core.http.httping.TEMPORARY_REDIRECT = 307[source]
hio.core.http.httping.BAD_REQUEST = 400[source]
hio.core.http.httping.UNAUTHORIZED = 401[source]
hio.core.http.httping.PAYMENT_REQUIRED = 402[source]
hio.core.http.httping.FORBIDDEN = 403[source]
hio.core.http.httping.NOT_FOUND = 404[source]
hio.core.http.httping.METHOD_NOT_ALLOWED = 405[source]
hio.core.http.httping.NOT_ACCEPTABLE = 406[source]
hio.core.http.httping.PROXY_AUTHENTICATION_REQUIRED = 407[source]
hio.core.http.httping.REQUEST_TIMEOUT = 408[source]
hio.core.http.httping.CONFLICT = 409[source]
hio.core.http.httping.GONE = 410[source]
hio.core.http.httping.LENGTH_REQUIRED = 411[source]
hio.core.http.httping.PRECONDITION_FAILED = 412[source]
hio.core.http.httping.REQUEST_ENTITY_TOO_LARGE = 413[source]
hio.core.http.httping.REQUEST_URI_TOO_LONG = 414[source]
hio.core.http.httping.UNSUPPORTED_MEDIA_TYPE = 415[source]
hio.core.http.httping.REQUESTED_RANGE_NOT_SATISFIABLE = 416[source]
hio.core.http.httping.EXPECTATION_FAILED = 417[source]
hio.core.http.httping.UNPROCESSABLE_ENTITY = 422[source]
hio.core.http.httping.LOCKED = 423[source]
hio.core.http.httping.FAILED_DEPENDENCY = 424[source]
hio.core.http.httping.UPGRADE_REQUIRED = 426[source]
hio.core.http.httping.PRECONDITION_REQUIRED = 428[source]
hio.core.http.httping.TOO_MANY_REQUESTS = 429[source]
hio.core.http.httping.REQUEST_HEADER_FIELDS_TOO_LARGE = 431[source]
hio.core.http.httping.INTERNAL_SERVER_ERROR = 500[source]
hio.core.http.httping.NOT_IMPLEMENTED = 501[source]
hio.core.http.httping.BAD_GATEWAY = 502[source]
hio.core.http.httping.SERVICE_UNAVAILABLE = 503[source]
hio.core.http.httping.GATEWAY_TIMEOUT = 504[source]
hio.core.http.httping.HTTP_VERSION_NOT_SUPPORTED = 505[source]
hio.core.http.httping.INSUFFICIENT_STORAGE = 507[source]
hio.core.http.httping.NOT_EXTENDED = 510[source]
hio.core.http.httping.NETWORK_AUTHENTICATION_REQUIRED = 511[source]
hio.core.http.httping.STATUS_DESCRIPTIONS[source]
hio.core.http.httping.METHODS = ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE', 'OPTIONS', 'TRACE', 'CONNECT'][source]
hio.core.http.httping.MAXAMOUNT = 1048576[source]
hio.core.http.httping._MAXLINE = 65536[source]
hio.core.http.httping._MAXHEADERS = 100[source]
exception hio.core.http.httping.HTTPException[source]

Bases: Exception

Common base class for all non-exit exceptions.

exception hio.core.http.httping.InvalidURL[source]

Bases: HTTPException

Common base class for all non-exit exceptions.

exception hio.core.http.httping.UnknownProtocol(version)[source]

Bases: HTTPException

Common base class for all non-exit exceptions.

exception hio.core.http.httping.BadStatusLine(line)[source]

Bases: HTTPException

Common base class for all non-exit exceptions.

exception hio.core.http.httping.BadRequestLine(line)[source]

Bases: BadStatusLine

Common base class for all non-exit exceptions.

exception hio.core.http.httping.BadMethod(method)[source]

Bases: HTTPException

Common base class for all non-exit exceptions.

exception hio.core.http.httping.LineTooLong(kind)[source]

Bases: HTTPException

Common base class for all non-exit exceptions.

exception hio.core.http.httping.PrematureClosure(msg)[source]

Bases: HTTPException

Common base class for all non-exit exceptions.

exception hio.core.http.httping.HTTPError(status, reason='', title='', detail='', fault=None, headers=None)[source]

Bases: Exception

HTTP error for use with Valet or Other WSGI servers to raise exceptions caught by the WSGI server.

status is int HTTP status code, e.g. 400
reason is  str HTTP status text, "Unknown Error"
title  is str title of error
headers is dict of extra headers to add to the response
error

An internal application error code

Type

int

__slots__ = ['status', 'reason', 'title', 'detail', 'headers', 'fault'][source]
__repr__(self)[source]

Return repr(self).

render(self, jsonify=False)[source]

Render and return the attributes as a bytes If jsonify then render as serialized json

hio.core.http.httping.httpDate1123(dt)[source]

Return a string representation of a date according to RFC 1123 (HTTP/1.1).

The supplied date must be in UTC. import datetime httpDate1123(datetime.datetime.utcnow()) ‘Wed, 30 Sep 2015 14:29:18 GMT’

hio.core.http.httping.normalizeHostPort(host, port=None, defaultPort=80)[source]

Given hostname host which could also be netloc which includes port and or port generate and return tuple (hostname, port) priority is if port is provided in hostname as host:port then use otherwise use port otherwise use defaultPort

hio.core.http.httping.parseQuery(query)[source]

Return dict of parsed query string. Utility function

hio.core.http.httping.updateQargsQuery(qargs=None, query='')[source]

Returns duple of updated (qargs, query) Where qargs parameter is dict of query arguments and query parameter is query string The returned qargs is updated with query string arguments and the returned query string is generated from the updated qargs If provided, qargs may have additional fields not in query string This allows combining query args from two sources, a dict and a string

https://www.w3.org/TR/2014/REC-html5-20141028/forms.html#url-encoded-form-data

hio.core.http.httping.unquoteQuery(query)[source]

Returns query string with unquoted values

hio.core.http.httping.packHeader(name, *values)[source]

Format and return a header line.

For example: h.packHeader(‘Accept’, ‘text/html’)

hio.core.http.httping.packChunk(msg)[source]

Return msg bytes in a chunk

hio.core.http.httping.parseLine(raw, eols=(CRLF, LF, CR), kind='event line')[source]

Generator to parse line from raw bytearray Each line demarcated by one of eols kind is line type string for error message

Yields None If waiting for more to parse Yields line Otherwise

Consumes parsed portions of raw bytearray

Raise error if eol not found before MAX_LINE_SIZE

hio.core.http.httping.parseLeader(raw, eols=(CRLF, LF), kind='leader header line', headers=None)[source]

Generator to parse entire leader of header lines from raw bytearray Each line demarcated by one of eols Yields None If more to parse Yields cimdict of headers Otherwise as indicated by empty headers

Raise error if eol not found before MAX_LINE_SIZE

hio.core.http.httping.parseChunk(raw)[source]

Generator to parse next chunk from raw bytearray Consumes used portions of raw Yields None If waiting for more bytes Yields tuple (size, parms, trails, chunk) Otherwise Where:

size is int size of the chunk parms is dict of chunk extension parameters trails is dict of chunk trailer headers (only on last chunk if any) chunk is chunk if any or empty if not

Chunked-Body = *chunk

last-chunk trailer CRLF

chunk = chunk-size [ chunk-extension ] CRLF

chunk-data CRLF

chunk-size = 1*HEX last-chunk = 1*(“0”) [ chunk-extension ] CRLF chunk-extension= *( “;” chunk-ext-name [ “=” chunk-ext-val ] ) chunk-ext-name = token chunk-ext-val = token | quoted-string chunk-data = chunk-size(OCTET) trailer = *(entity-header CRLF)

hio.core.http.httping.parseBom(raw, bom=codecs.BOM_UTF8)[source]

Generator to parse bom from raw bytearray Yields None If waiting for more to parse Yields bom If found Yields empty bytearray Otherwise Consumes parsed portions of raw bytearray

hio.core.http.httping.parseStatusLine(line)[source]

Parse the response status line

hio.core.http.httping.parseRequestLine(line)[source]

Parse the request start line

class hio.core.http.httping.EventSource(raw=None, events=None, dictable=False)[source]

Bases: object

Server Sent Event Stream Client parser

Bom[source]
close(self)[source]

Assign True to .closed

parseEvents(self)[source]

Generator to parse events from .raw bytearray and append to .events Each event is dict with the following items:

id: event id utf-8 decoded or empty

name: event name utf-8 decoded or empty data: event data utf-8 decoded json: event data deserialized to dict when applicable pr None

assigns .retry if any

Yields None If waiting for more bytes Yields True When done

event = *( comment / field ) end-of-line comment = colon *any-char end-of-line field = 1*name-char [ colon [ space ] *any-char ] end-of-line end-of-line = ( cr lf / cr / lf / eof ) eof = < matches repeatedly at the end of the stream > lf =

0xA

cr =

0xD

space = 0x20 colon = 0x3A bom =  when encoded as utf-8 b’’ name-char = a Unicode character other than LF, CR, or : any-char = a Unicode character other than LF or CR Event streams in this format must always be encoded as UTF-8. [RFC3629]

parseEventStream(self)[source]

Generator to parse event stream from .raw bytearray stream appends each event to .events deque. assigns .bom if any assigns .retry if any Parses until connection closed

Each event is dict with the following items:

id: event id utf-8 decoded or empty

name: event name utf-8 decoded or empty data: event data utf-8 decoded json: event data deserialized to dict when applicable pr None

Yields None If waiting for more bytes Yields True When completed and sets .ended to True If BOM present at beginning of event stream then assigns to .bom and deletes. Consumes bytearray as it parses

stream = [ bom ] *event event = *( comment / field ) end-of-line comment = colon *any-char end-of-line field = 1*name-char [ colon [ space ] *any-char ] end-of-line end-of-line = ( cr lf / cr / lf / eof ) eof = < matches repeatedly at the end of the stream > lf =

0xA

cr =

0xD

space = 0x20 colon = 0x3A bom =  when encoded as utf-8 b’’ name-char = a Unicode character other than LF, CR, or : any-char = a Unicode character other than LF or CR Event streams in this format must always be encoded as UTF-8. [RFC3629]

makeParser(self, raw=None)[source]

Make event stream parser generator and assign to .parser Assign msg to .msg If provided

parse(self)[source]

Service the event stream parsing must call .makeParser to setup parser When done parsing,

.parser is None .ended is True

class hio.core.http.httping.Parsent(msg=None, dictable=None, method='GET')[source]

Bases: object

Base class for objects that parse HTTP messages

reinit(self, msg=None, dictable=None, method='GET')[source]

Reinitialize Instance msg = bytearray of request msg to parse dictable = Boolean flag If True attempt to convert json body method = method verb of associated request

close(self)[source]

Assign True to .closed and close parser

checkPersisted(self)[source]

Checks headers to determine if connection should be kept open until client closes it Sets the .persisted flag

parseHead(self)[source]

Generator to parse headers in heading of .msg Yields None if more to parse Yields True if done parsing

parseBody(self)[source]

Parse body

parseMessage(self)[source]

Generator to parse message bytearray. Parses msg if not None Otherwise parse .msg

makeParser(self, msg=None)[source]

Make message parser generator and assign to .parser Assign msg to .msg If provided

parse(self)[source]

Service the message parsing must call .makeParser to setup parser When done parsing,

.parser is None .ended is True

dictify(self)[source]

Attempt to convert body to dict data if .dictable or json content-type