Qore HttpServerUtil Module Reference  1.1
HttpServer::AbstractStreamRequest Class Reference

abstract class for streaming HTTP chunked requests/responses More...

Public Member Methods

 constructor (HttpListenerInterface listener, AbstractHttpRequestHandler handler, Socket s, hash< auto > cx, hash< auto > hdr, auto body)
 creates the object with the given attributes More...
 
hash< HttpHandlerResponseInfohandleRequest ()
 handles the request
 

Private Member Methods

hash< HttpHandlerResponseInfogetResponseHeaderMessage ()
 this method returns the response message description hash by calling getResponseHeaderMessageImpl() More...
 
hash< HttpResponseInfogetResponseHeaderMessageImpl ()
 this method should return the response message description hash More...
 
 logChunk (bool send, int size)
 this method can be overridden in base classes to log each HTTP chunk sent More...
 
nothing recv (hash< auto > v)
 this is the primary callback for receiving chunked data; data will be logged, and then recvImpl() is called More...
 
nothing recvImpl (hash< auto > v)
 callback method for receiving chunked data; the default implementation in this base class does nothing More...
 
auto send ()
 this is the primary callback for sending chunked responses More...
 
auto sendImpl ()
 callback method for sending chunked data More...
 
hash< HttpHandlerResponseInfosendResponse ()
 called to either create the response hash or send a chunked response directly More...
 

Private Attributes

auto body
 any message body given in a non-chunked request; could already be deserialized
 
hash< auto > cx
 the call context variable
 
AbstractHttpRequestHandler handler
 the request handler for the request
 
hash< auto > hdr
 a hash of request headers
 
HttpListenerInterface listener
 an HttpListenerInterface object for the listener serving the request for logging purposes
 
Socket s
 the Socket object for the response
 
timeout timeout_ms = HttpServer::DefaultTimeout
 send and receive timeout
 

Detailed Description

abstract class for streaming HTTP chunked requests/responses

This class is the base class for handling HTTP stream requests; i.e. with chunked data

The calling order is as follows:

  • constructor(): this is called when the request is received
  • recv(): this is called once for each HTTP chunk (if data is sent chunked), and then once with any message trailer. If data is sent non-chunked, then this method is called with the monolithic message body and then again with NOTHING to signify the end of the transfer and to simulate a chunked transfer. The simulation of a chunked transfer or the actual chunked receive with the callbacks is made by the handleRequest() method. Subclasses should re-implement recvImpl() which is called by this method
  • getResponseHeaderMessage(): this is called after the message body has been received to get the response headers and optionally a message body. Subclasses should reimplement getResponseHeaderMessageImpl() which is called by this method
  • send(): this is called if no message body is returned by getResponseHeaderMessage(); each time this method returns data, the data is sent in a response chunk; when this method returns NOTHING, then no more data is sent. Subclasses should re-implement sendImpl() which is called by this method

Member Function Documentation

◆ constructor()

HttpServer::AbstractStreamRequest::constructor ( HttpListenerInterface  listener,
AbstractHttpRequestHandler  handler,
Socket  s,
hash< auto >  cx,
hash< auto >  hdr,
auto  body 
)
inline

creates the object with the given attributes

Parameters
listeneran HttpListenerInterface object for the listener serving the request for logging purposes
handlerthe handler serving the request
sthe Socket for serving the request
cxa call context hash
hdrincoming header hash; all keys will be converted to lower-case, additionally the following keys will be present:
  • method: the HTTP method received (ie "GET", "POST", etc)
  • path: the HTTP path given in the request, after processing by Qore::decode_uri_request()
  • http_version: the HTTP version number in the request (either "1.0" or "1.1")
bodyany message body in the request already received from the incoming socket

◆ getResponseHeaderMessage()

hash<HttpHandlerResponseInfo> HttpServer::AbstractStreamRequest::getResponseHeaderMessage ( )
private

this method returns the response message description hash by calling getResponseHeaderMessageImpl()

Returns
a hash with the following keys:
  • "code": the HTTP return code (see HttpServer::HttpCodes)
  • "body": the message body to return in the response; if this key is returned, then the reply is sent immediately; a chunked reply is not made, and send() and sendImpl() are not called
  • "close": (optional) set this key to True if the connection should be unconditionally closed when the handler returns
  • "hdr": (optional) set this key to a hash of extra header information to be returned with the response
Note
this method is called after the message body has been received

◆ getResponseHeaderMessageImpl()

hash<HttpResponseInfo> HttpServer::AbstractStreamRequest::getResponseHeaderMessageImpl ( )
private

this method should return the response message description hash

The default implementation in this class is to return a 501 Not Implemented response; override in subclasses to return a custom response. Omit the "body" key to ensure that a chunked response is sent and the send() and sendImpl() callbacks are called.

Returns
a hash with the following keys:
  • "code": the HTTP return code (see HttpServer::HttpCodes)
  • "body": the message body to return in the response; if this key is returned, then the reply is sent immediately; a chunked reply is not made, and send() and sendImpl() are not called
  • "close": (optional) set this key to True if the connection should be unconditionally closed when the handler returns
  • "hdr": (optional) set this key to a hash of extra header information to be returned with the response
Note
this method is called after the message body has been received

◆ logChunk()

HttpServer::AbstractStreamRequest::logChunk ( bool  send,
int  size 
)
private

this method can be overridden in base classes to log each HTTP chunk sent

private logChunk(bool send, int size) {
listener.log("cid %d %s CHUNK %d bytes", cx.id, send ? "send" : "recv", size);
}

By default this method does nothing

◆ recv()

nothing HttpServer::AbstractStreamRequest::recv ( hash< auto >  v)
private

this is the primary callback for receiving chunked data; data will be logged, and then recvImpl() is called

content decoding is not possible with chunked data because only the entire message can be decoded

◆ recvImpl()

nothing HttpServer::AbstractStreamRequest::recvImpl ( hash< auto >  v)
private

callback method for receiving chunked data; the default implementation in this base class does nothing

Parameters
vthe first time this method is called with a hash of the message headers in the "hdr" key, and then with any message body in the "data"; if a chunked HTTP message is received, then this method is called once for each chunk; when the message has been received, then this method is called with a hash representing any trailer data received in a chunked transfer or NOTHING if the data was received in a normal message body or if there was no trailer data in a chunked transfer. The argument to this callback is always a hash; data calls have the following keys:
  • "data": the string or binary data
  • "chunked": True if the data was received with chunked transfer encoding, False if not
Header or trailer data is placed in a hash with the following keys:
  • "hdr": this can be assigned to NOTHING for the trailer hash if the data was not sent chunked or no trailers were included in a chunked message
  • "obj": this is the owning object (so socket parameters can be changed based on headers received, such as, for example, socket character encoding)

◆ send()

auto HttpServer::AbstractStreamRequest::send ( )
private

this is the primary callback for sending chunked responses

first sendImpl() is called to get the raw data, and then any chunked data is encoded by this method if required

◆ sendImpl()

auto HttpServer::AbstractStreamRequest::sendImpl ( )
private

callback method for sending chunked data

The default implementation in this base class does nothing and returns nothing

Returns
The chunked HTTP data to send; this method must return either a string or a binary value each time it is called to give the chunked data to send; when all data has been sent, then a hash of message trailers can be returned or simply NOTHING which will close the chunked message

◆ sendResponse()

hash<HttpHandlerResponseInfo> HttpServer::AbstractStreamRequest::sendResponse ( )
private

called to either create the response hash or send a chunked response directly

This method calls getResponseHeaderMessageImpl() to get the response code, headers and optionally a response message body.

If a "Transfer-Encoding: chunked" header is included, then the response is sent chunked using the send() callback; in this case the "reply_sent" key in the response is set to True.

Otherwise, any message body is immediately encoded (if accepted by the requestor).