61#if !defined(_NETWORKPROTOCOLS_H_)
62#define _NETWORKPROTOCOLS_H_
74#define PROTOCOL_HTTP_SERVER 1
75#define PROTOCOL_HTTP_CLIENT 2
76#define PROTOCOL_MESSAGE 4
77#define PROTOCOL_TELNET 8
78#define PROTOCOL_3GCAM 16
79#define ENCRYPTION_SSL 1
80#define ENCRYPTION_AES 2
149 this->content =
new char[size+1];
150 memcpy(this->content,
content, size);
151 this->content[size] = 0;
197 bool processHeader(
const char* buffer, uint32 size,
bool &isInvalid);
232 const char*
getPostData(
const char* entry, uint32& size,
const char**
type);
236 const char*
getPostData(
const char* entry, uint32& size);
284 bool createRequest(uint8
type,
const char* host,
const char* uri, std::map<std::string, std::string>& headerEntries,
const char* content,
const char* contentType, uint32 contentSize,
bool keepAlive, uint64
ifModifiedSince);
303 bool createWebsocketRequest(
const char* uri,
const char* host,
const char* protocolName,
const char* origin);
319 std::map<std::string, std::string>
params;
359 JSONM(
const char* data, uint64 size);
362 JSONM(
const char* json);
377 const char*
getData(
const char* name, uint64& size);
381 const char*
getData(uint32 chunk, uint64& size);
391 bool setJSON(
const char* json);
395 uint32
addData(
const char* name,
const char* data, uint64 size,
const char* type);
409 bool setRawJSON(
const char* json);
410 bool extractMultipartInfo();
411 bool updateMultipartJSON();
521 bool processHeader(
const char* buffer, uint64 size,
bool &isInvalid);
581#define TELNET_WINDOWS 1
600 bool setLine(
const char* buffer,
bool addCR);
604 bool setLine(
const char* buffer, uint32 len,
bool addCR =
false);
608 bool giveData(
char* buffer, uint32 len);
613 bool setCR(uint8 type);
634#define HTTP_MOVED_PERMANENTLY 1
635#define HTTP_USE_LOCAL_COPY 2
636#define HTTP_MALFORMED_URL 3
637#define HTTP_UNAUTHORIZED 4
638#define HTTP_ACCESS_DENIED 5
639#define HTTP_FILE_NOT_FOUND 6
640#define HTTP_INTERNAL_ERROR 7
641#define HTTP_NOT_IMPLEMENTED 8
642#define HTTP_SERVICE_NOT_AVAILABLE 9
643#define HTTP_GATEWAY_TIMEOUT 10
644#define HTTP_SERVER_UNAVAILABLE 11
645#define HTTP_SERVER_NOREPLY 12
646#define HTTP_SERVER_MALFORMED_REPLY 13
647#define HTTP_SWITCH_PROTOCOL 14
655"HTTP/1.1 301 Moved Permanently",
656"HTTP/1.1 304 Use Local Copy",
657"HTTP/1.1 400 Bad Request <H1>Malformed URL</H1>",
658"HTTP/1.1 401 Unauthorized",
659"HTTP/1.1 403 Access Denied",
660"HTTP/1.1 404 Object Not Found",
661"HTTP/1.1 500 Internal Server Error <H1>Error while creating page</H1>",
662"HTTP/1.1 501 Not Implemented <H1>Not implemented</H1>",
663"HTTP/1.1 503 Service Unavailable <H1>Service Unavailable</H1>",
664"HTTP/1.1 504 Gateway Timeout <H1>Gateway Timeout</H1>",
665"HTTP/1.1 500 Internal Server Error <H1>Server unavailable</H1>",
666"HTTP/1.1 500 Internal Server Error <H1>No reply from server</H1>",
667"HTTP/1.1 500 Internal Server Error <H1>Malformed server reply</H1>",
668"HTTP/1.1 101 Switching Protocols"
707 bool processHeader(
const char* buffer, uint32 size,
bool &isInvalid);
740 bool createPage(uint8 status, uint64
time,
const char* serverName,
741 uint64 lastMod,
bool keepAlive,
bool cache,
const char* contentType,
742 const char* content, uint32 contentSize = 0,
const char* additionalHeaderEntries = NULL);
752 uint64 ifLastMod,
bool keepAlive,
bool cache,
753 const char* filename);
784 std::map<std::string, std::string>
params;
The binary DataMessage container — the central data-exchange object of Psyclone/CMSDK.
Raw socket transport layer: TCP/UDP/SSL connections and TCP listeners with buffered,...
#define PROTOCOL_TELNET
Line-based Telnet-style text protocol.
#define PROTOCOL_HTTP_CLIENT
Speak HTTP as a client: send requests, parse replies.
#define PROTOCOL_HTTP_SERVER
Serve HTTP: parse requests, send replies (server role).
#define PROTOCOL_MESSAGE
CMSDK binary DataMessage protocol (size-prefixed frames).
The central Psyclone data container: a self-contained binary message with typed, named user entries.
static HTTPRequest * ReceiveHTTPRequest(NetworkConnection *con, uint32 timeout)
Read a full request from the connection.
static bool SendHTTPRequest(NetworkConnection *con, HTTPRequest *req)
Serialise and send a request.
static HTTPReply * ReceiveHTTPReply(NetworkConnection *con, uint32 timeout)
Read a full reply from the connection.
static bool SendHTTPReply(NetworkConnection *con, HTTPReply *reply)
Serialise and send a reply.
static bool CheckBufferForCompatibility(const char *buffer, uint32 length)
static bool InitialiseConversation(NetworkConnection *con)
No initial exchange needed.
One named entry of an HTTP POST body (form field or uploaded file part).
std::string type
MIME Content-Type of this part.
bool setContent(const char *content, uint32 size)
Copy content bytes into this entry (NUL-terminated internally).
std::string filename
Original filename for file uploads (empty for plain fields).
uint32 contentSize
Size of content in bytes.
std::string name
Form field name (Content-Disposition name attribute).
char * content
Owned content bytes (NUL-terminated for convenience).
static bool InitialiseConversation(NetworkConnection *con)
No initial exchange needed for HTTP.
static bool SendHTTPReply(NetworkConnection *con, HTTPReply *reply)
Serialise and send a reply.
static HTTPReply * ReceiveHTTPReply(NetworkConnection *con, uint32 timeout)
Read a full reply from the connection.
static bool SendHTTPRequest(NetworkConnection *con, HTTPRequest *req)
Serialise and send a request.
static HTTPRequest * ReceiveHTTPRequest(NetworkConnection *con, uint32 timeout)
Read a full request from the connection.
static bool CheckBufferForCompatibility(const char *buffer, uint32 length)
static WebsocketData * ReceiveWebsocketData(NetworkConnection *con, uint32 timeout)
Read one complete WebSocket message (reassembling fragments).
static bool SendWebsocketData(NetworkConnection *con, WebsocketData *wsData)
Send a WebSocket frame.
A parsed or generated HTTP response.
bool isWebsocketUpgrade()
uint32 contentLength
Body length in bytes.
const char * getRawContent(uint32 &size)
Get the raw, untransformed body bytes.
bool createAuthorizationReply(const char *realm)
Build a 401 Basic-auth challenge.
const char * getProtocol()
const char * getContent(uint32 &size)
Get the (decoded) response body.
uint8 type
HTTP_* status id of this reply.
uint64 time
Timestamp of creation/receipt (ms epoch).
bool processHeader(const char *buffer, uint32 size, bool &isInvalid)
Parse the response header block from raw bytes.
uint32 headerLength
Header block length within data, in bytes.
bool setDecodedContent(const char *buffer, uint32 size)
Replace the body with already-decoded bytes (e.g.
static HTTPReply * CreateErrorReply(uint8 type)
Build a canned error reply.
static HTTPReply * CreateWebsocketHTTPReply(const char *key, const char *version)
Build the "101 Switching Protocols" reply for a WebSocket handshake.
std::map< std::string, std::string > params
Auxiliary parsed parameters.
bool chunked
Body uses HTTP/1.1 chunked transfer encoding.
bool processContent(const char *buffer, uint32 size)
Append body bytes after the header has been parsed.
bool createFromFile(uint64 time, const char *serverName, uint64 ifLastMod, bool keepAlive, bool cache, const char *filename)
Build a response by reading a file from disk (MIME type from extension).
static HTTPReply * CreateAuthorizationReply(const char *realm)
Build a 401 reply requesting Basic authentication.
bool createOptionsResponse(uint8 status, uint64 time, const char *serverName, bool keepAlive, const char *origin, const char *operations)
Build a CORS-preflight (OPTIONS) response.
bool createWebsocketHTTPReply(const char *key, const char *version)
Build the 101 WebSocket handshake completion in-place.
char * data
Owned raw reply bytes (header followed by body).
bool keepAlive
Whether the connection stays open after this reply.
std::map< std::string, std::string > entries
Parsed header fields (name to value).
HTTPReply(uint64 source=0)
Construct an empty reply.
bool createPage(uint8 status, uint64 time, const char *serverName, uint64 lastMod, bool keepAlive, bool cache, const char *contentType, const char *content, uint32 contentSize=0, const char *additionalHeaderEntries=NULL)
Build a complete response with headers and content.
const char * getHeaderEntry(const char *entry)
Look up a header field (case-insensitive).
bool createErrorPage(uint8 status, uint64 time, const char *serverName, bool keepAlive)
Build a canned error page for the given status.
uint64 source
Packed uint64 endpoint of the sender (0 if local).
A parsed or generated HTTP request (also used for WebSocket upgrade handshakes).
bool parseURIParameters(const char *text)
Parse "a=1&b=2" style parameters from a URI query string into params.
const char * getBasicAuthorization()
const char * getContent(uint32 &size)
Get the (decoded) request body.
const char * getRawContent(uint32 &size)
Get the raw, untransformed body bytes as received.
bool parseContentParameters(const char *content, uint32 size)
Parse a URL-encoded form body into params.
uint64 time
Timestamp when reception/creation started (ms epoch).
std::string getBasicAuthorizationPassword()
const char * getHeaderEntry(const char *entry)
Look up a header field (case-insensitive).
DataMessage * convertToMessage()
Convert this HTTP request into a binary DataMessage (URI, params and content mapped to message fields...
std::map< std::string, std::string > entries
Parsed header fields (name to value).
HTTPRequest(uint64 source=0, uint64 startRecTime=0)
Construct an empty request.
uint32 headerLength
Length of the header block in data, in bytes.
uint32 contentLength
Body length (from Content-Length / parsing), in bytes.
bool parseContentChunk(const char *chunk, uint32 size)
Parse one chunk of a multipart body (between boundaries) into postEntries.
const char * getPostData(const char *entry, uint32 &size, const char **type)
Get a multipart POST part's content, size and MIME type.
static HTTPRequest * CreateWebsocketRequest(const char *uri, const char *host, const char *protocolName, const char *origin)
Build a client-side WebSocket upgrade request (RFC 6455 handshake).
uint8 type
HTTP_* method id.
bool createWebsocketRequest(const char *uri, const char *host, const char *protocolName, const char *origin)
Fill this object with a WebSocket upgrade handshake request.
char * data
Owned raw request bytes (header followed by body).
uint64 ifModifiedSince
Parsed If-Modified-Since timestamp (ms epoch; 0 = absent).
std::map< std::string, HTTPPostEntry * > postEntries
Multipart POST parts by name (owned).
std::string decodeBasicAuthorization()
Decode the Basic Authorization header.
bool processContent(const char *buffer, uint32 size)
Append body bytes after the header has been parsed.
bool processHeader(const char *buffer, uint32 size, bool &isInvalid)
Parse the HTTP header block from raw bytes.
const char * getProtocol()
std::string getBasicAuthorizationUser()
bool createRequest(uint8 type, const char *host, const char *uri, const char *content, uint32 contentSize, bool keepAlive, uint64 ifModifiedSince)
Build a simple request with optional raw body.
std::map< std::string, std::string > params
URI query and form parameters (name to value).
uint64 source
Packed uint64 endpoint of the sender (0 if local).
uint64 endReceiveTime
Timestamp when the request was fully received (ms epoch).
bool createMultipartRequest(uint8 type, const char *host, const char *uri, std::map< std::string, std::string > &headerEntries, std::map< std::string, HTTPPostEntry * > &bodyEntries, bool keepAlive, uint64 ifModifiedSince)
Build a multipart/form-data request from several named parts.
std::string postBoundary
Multipart boundary string, when applicable.
const char * getPostDataType(const char *entry)
bool setBasicAuthorization(const char *authB64)
Set the Authorization header from a pre-encoded base64 credential.
bool keepAlive
Whether the connection should be kept open after replying.
const char * getParameter(const char *entry)
Look up a URI query or form parameter by name.
const char * getRequest()
bool isWebsocketUpgrade()
const char * getData(const char *name, uint64 &size)
Get an attachment's bytes by name.
uint64 mOffset
Byte offset where the binary multipart section begins.
uint32 addData(const char *name, const char *data, uint64 size, const char *type)
Append a binary attachment.
uint64 jmSize
Total size of jmData in bytes.
DataMessage * convertToMessage()
Convert this container into a binary DataMessage.
std::string getDataType(const char *name)
std::string getInfoString()
std::map< uint32, JSONMEntry > entries
Attachment metadata by chunk index.
std::string getDataName(uint32 chunk)
char * jmData
Owned serialised container buffer (JSON + attachments).
bool setJSON(const char *json)
Replace the JSON text portion (multipart metadata is regenerated).
static bool SendMessage(NetworkConnection *con, DataMessage *msg, uint64 receiver=0)
Serialise and send one message.
static bool CheckBufferForCompatibility(const char *buffer, uint32 length)
static bool InitialiseConversation(NetworkConnection *con)
Perform the initial message-protocol greeting.
static DataMessage * ReceiveMessage(NetworkConnection *con, uint32 timeout)
Read one full message frame.
Abstract base class for all point-to-point network connections.
static bool InitialiseConversation(NetworkConnection *con)
Perform any protocol-specific initial exchange on a new connection.
uint8 protocol
PROTOCOL_* id of this handler.
static bool CheckBufferForCompatibility(const char *buffer, uint32 length)
Sniff whether buffer looks like this protocol.
One line of Telnet-style text traffic.
bool giveData(char *buffer, uint32 len)
Take ownership of an existing buffer as the line text (no copy).
uint32 size
Line length in bytes.
TelnetLine(uint64 source)
Construct an empty line.
char cr[3]
Active line-ending characters (\r\n or \n, NUL-terminated).
uint32 user
Optional user/session tag for multi-user telnet servers.
bool setCR(uint8 type)
Select the line-ending convention.
char * data
Owned line text.
uint64 time
Timestamp of creation/receipt (ms epoch).
uint64 source
Packed uint64 endpoint of the sender.
bool setLine(const char *buffer, bool addCR)
Set the line text from a NUL-terminated string.
static TelnetLine * ReceiveTelnetLine(NetworkConnection *con, uint32 timeout)
Read one line terminated by CR/LF.
static bool CheckBufferForCompatibility(const char *buffer, uint32 length)
static bool SendTelnetLine(NetworkConnection *con, TelnetLine *line)
Send one line (with its line ending).
static bool InitialiseConversation(NetworkConnection *con)
Send any initial prompt/negotiation.
One WebSocket frame/message (RFC 6455): parsing, generation and control frames.
uint64 endReceiveTime
Timestamp when the frame was fully received (ms epoch).
const char * getRawData(uint64 &size)
Get the serialised on-the-wire frame bytes (header + masked payload).
static uint8 const max_extended_header_length
Maximum length of the variable portion of the WebSocket header.
WSSTATUS
Parsing status of this frame: not started, awaiting more bytes, or fully received.
uint64 payloadSize
Declared payload length from the header.
static uint8 const payload_size_code_16bit
Basic length 126: a 16-bit big-endian length follows.
static uint8 const BHB1_PAYLOAD
Byte 1: 7-bit basic payload length / extension code.
static uint8 const payload_size_code_64bit
Basic length 127: a 64-bit big-endian length follows.
static uint8 const BHB0_OPCODE
Byte 0: 4-bit opcode (see DataType).
static uint64 const payload_size_jumbo
Maximum size of a jumbo WebSocket payload (basic payload = 127).
bool isTerminationConfirmation()
uint64 contentSize
Payload bytes accumulated so far.
static uint8 const payload_size_basic
Maximum size of a basic WebSocket payload.
const char * getContent(uint64 &size)
Get the decoded (unmasked) payload.
uint32 headerLength
Parsed frame header length in bytes (2..14).
static WebsocketData * CreatePing()
bool isFinal
FIN bit: true when this is the last fragment of a message.
static uint8 const max_header_length
Maximum length of a WebSocket header.
static uint8 const basic_header_length
static uint8 const BHB0_RSV3
Byte 0: reserved bit 3 (extensions; must be 0).
char * data
Owned decoded payload bytes.
bool isTerminationRequest()
static uint8 const BHB0_RSV1
Byte 0: reserved bit 1 (extensions; must be 0).
uint8 opcode
RFC 6455 opcode (see DataType).
DataType
Frame content type, mapping to the RFC 6455 opcode.
static WebsocketData * CreatePong()
enum cmlabs::WebsocketData::DataType dataType
uint32 maskingKey
32-bit masking key (0 when unmasked, i.e.
bool processContent(const char *buffer, uint64 size)
Append (and unmask) payload bytes after the header has been parsed.
static WebsocketData * CreateTerminationConfirmation()
char * rawData
Owned serialised frame bytes (for sending).
static uint8 const BHB0_FIN
Byte 0: FIN — set on the final fragment of a message.
WebsocketData(uint64 source=0, uint64 startRecTime=0)
Construct an empty frame.
static uint16 const payload_size_extended
Maximum size of an extended WebSocket payload (basic payload = 126).
bool setData(DataType dataType, bool maskData, const char *data=NULL, uint64 size=0)
Set the payload and build the serialised frame for sending.
static uint8 const BHB1_MASK
Byte 1: MASK — payload is XOR-masked (required client-to-server).
uint64 time
Timestamp when reception/creation started (ms epoch).
enum cmlabs::WebsocketData::WSSTATUS status
uint64 source
Packed uint64 endpoint of the sender (0 if local).
bool processHeader(const char *buffer, uint64 size, bool &isInvalid)
Parse the frame header from raw bytes (handles 16/64-bit extended lengths).
static uint8 const BHB0_RSV2
Byte 0: reserved bit 2 (extensions; must be 0).
uint32 packages
Number of fragments accumulated into this message.
Recursive mutual-exclusion lock, optionally named for cross-process use.
Third-party (vendored): jsmn minimalistic JSON tokenizer by Serge Zaitsev (MIT licence),...
std::string BytifySize(double val)
Format a byte count with binary units, e.g.
std::string StringFormat(const char *format,...)
printf into a std::string.
bool NetworkProtocols_UnitTest()
static char HTTP_Status[][128]
Full HTTP status lines (with inline error bodies for error cases), indexed by the HTTP_* status ids a...
static char HTTP_Type[][8]
HTTP method name strings, indexed by the HTTP_* method ids (index 0 unused).
Third-party (vendored): SHA-1 hash from Stephan Brumme's portable hashing library (create....
Metadata for one binary attachment chunk inside a JSONM container.
uint64 size
Attachment size in bytes.
std::string type
MIME type of the attachment.
std::string getInfoString()
uint64 offset
Byte offset of the attachment within the container data.
uint32 chunk
Chunk index within the container (1-based).
std::string name
Attachment name.