abstract class for streaming HTTP chunked requests/responses
More...
#include <HttpServerUtil.qm.dox.h>
|
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
|
|
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
◆ constructor()
creates the object with the given attributes
- Parameters
-
listener | an HttpListenerInterface object for the listener serving the request for logging purposes |
handler | the handler serving the request |
s | the Socket for serving the request |
cx | a call context hash |
hdr | incoming 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" )
|
body | any message body in the request already received from the incoming socket |
◆ getResponseHeaderMessage()
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
-
v | the 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()
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).