Mstdlib-1.24.0

Typedefs

typedef struct M_net_http_simple M_net_http_simple_t
 
typedef void(* M_net_http_simple_done_cb) (M_net_error_t net_error, M_http_error_t http_error, const M_http_simple_read_t *simple, const char *error, void *thunk)
 
typedef M_bool(* M_net_http_simple_iocreate_cb) (M_io_t *io, char *error, size_t errlen, void *thunk)
 

Functions

M_net_http_simple_tM_net_http_simple_create (M_event_t *el, M_dns_t *dns, M_net_http_simple_done_cb done_cb)
 
void M_net_http_simple_cancel (M_net_http_simple_t *hs)
 
void M_net_http_simple_set_proxy_authentication (M_net_http_simple_t *hs, const char *user, const char *pass)
 
void M_net_http_simple_set_proxy (M_net_http_simple_t *hs, const char *proxy_server)
 
void M_net_http_simple_set_timeouts (M_net_http_simple_t *hs, M_uint64 connect_ms, M_uint64 stall_ms, M_uint64 overall_ms)
 
void M_net_http_simple_set_max_redirects (M_net_http_simple_t *hs, M_uint64 max)
 
void M_net_http_simple_set_max_receive_size (M_net_http_simple_t *hs, M_uint64 max)
 
void M_net_http_simple_set_tlsctx (M_net_http_simple_t *hs, M_tls_clientctx_t *ctx)
 
void M_net_http_simple_set_iocreate (M_net_http_simple_t *hs, M_net_http_simple_iocreate_cb iocreate_cb)
 
void M_net_http_simple_set_message (M_net_http_simple_t *hs, M_http_method_t method, const char *user_agent, const char *content_type, const char *charset, const M_hash_dict_t *headers, const unsigned char *message, size_t message_len)
 
M_bool M_net_http_simple_send (M_net_http_simple_t *hs, const char *url, void *thunk) M_WARN_UNUSED_RESULT
 

Detailed Description

Simple HTTP network interface

Allows for sending a request to a remote system and receiving a response. The response will be delivered as an M_http_simple_read_t via a callback.

Redirects, and TLS upgrade/downgrades are handled internally by the module.

Redirects have a default limit of 16 but this can be changed. It is imperative that the limit never be disabled or be set excessively large. Loop tracking is not supported and exiting redirect loops is handled by the redirect limit.

Since this buffers data in memory the maximum received data size can be configured to prevent running out of memory. The default if not set is 50 MB.

By default there is no timeout waiting for the operation to complete. It will wait indefinitely unless timeouts are explicitly set.

Each instance of an M_net_http_simple_t can only be used once. Upon completion or cancel the object is internally destroyed and all references are invalidated.

Example:

#include <mstdlib/mstdlib.h>
#include <mstdlib/mstdlib_io.h>
#include <mstdlib/mstdlib_net.h>
#include <mstdlib/mstdlib_formats.h>
static void done_cb(M_net_error_t net_error, M_http_error_t http_error, const M_http_simple_read_t *simple, const char *error, void *thunk)
{
M_hash_dict_t *headers;
const char *key;
const char *val;
const unsigned char *data;
size_t len;
if (net_error != M_NET_ERROR_SUCCESS) {
M_printf("Net Error: %s: %s\n", M_net_errcode_to_str(net_error), error);
return;
}
if (http_error != M_HTTP_ERROR_SUCCESS) {
M_printf("HTTP Error: %s: %s\n", M_http_errcode_to_str(http_error), error);
return;
}
M_printf("---\n");
M_printf("Status code: %u - %s\n", M_http_simple_read_status_code(simple), M_http_simple_read_reason_phrase(simple));
M_printf("---\n");
M_printf("Headers:\n");
M_hash_dict_enumerate(headers, &he);
while (M_hash_dict_enumerate_next(headers, he, &key, &val)) {
M_printf("\t%s: %s\n", key, val);
}
M_printf("---\n");
M_printf("Body:\n");
data = M_http_simple_read_body(simple, &len);
M_printf("%.*s\n", (int)len, data);
M_printf("---\n");
}
static void trace_cb(void *cb_arg, M_io_trace_type_t type, M_event_type_t event_type, const unsigned char *data, size_t data_len)
{
const char *io_type = "UNKNOWN";
char *dump = NULL;
switch (type) {
io_type = "READ";
break;
io_type = "WRITE";
break;
return;
}
dump = M_str_hexdump(M_STR_HEXDUMP_NONE, 0, "\t", data, data_len);
if (M_str_isempty(dump)) {
M_free(dump);
dump = M_strdup("\t<No Data>");
}
M_printf("%s\n%s\n", io_type, dump);
M_free(dump);
}
static M_bool iocreate_cb(M_io_t *io, char *error, size_t errlen, void *thunk)
{
(void)error;
(void)errlen;
(void)thunk;
M_io_add_trace(io, NULL, trace_cb, io, NULL, NULL);
return M_TRUE;
}
int main(int argc, char **argv)
{
M_dns_t *dns;
dns = M_dns_create(el);
//M_tls_clientctx_set_verify_level(ctx, M_TLS_VERIFY_NONE);
hs = M_net_http_simple_create(el, dns, done_cb);
M_net_http_simple_set_message(hs, M_HTTP_METHOD_GET, NULL, "text/plain", "utf-8", NULL, NULL, 0);
if (M_net_http_simple_send(hs, "http://google.com/", NULL)) {
M_event_loop(el, M_TIMEOUT_INF);
} else {
M_printf("Send failed\n");
}
return 0;
}
M_bool M_dns_destroy(M_dns_t *dns)
struct M_dns M_dns_t
Definition: m_dns.h:43
M_dns_t * M_dns_create(M_event_t *event)
void M_event_destroy(M_event_t *event)
enum M_event_type M_event_type_t
Definition: m_event.h:189
struct M_event M_event_t
Definition: m_event.h:210
void M_event_done(M_event_t *event)
M_event_err_t M_event_loop(M_event_t *event, M_uint64 timeout_ms)
M_event_t * M_event_create(M_uint32 flags)
@ M_EVENT_FLAG_NONE
Definition: m_event.h:232
ssize_t M_printf(const char *fmt,...)
struct M_hash_dict M_hash_dict_t
Definition: m_hash_dict.h:52
void M_hash_dict_enumerate_free(M_hash_dict_enum_t *hashenum)
size_t M_hash_dict_enumerate(const M_hash_dict_t *h, M_hash_dict_enum_t **hashenum)
M_bool M_hash_dict_enumerate_next(const M_hash_dict_t *h, M_hash_dict_enum_t *hashenum, const char **key, const char **value)
struct M_hash_dict_enum M_hash_dict_enum_t
Definition: m_hash_dict.h:56
void M_hash_dict_destroy(M_hash_dict_t *h) M_FREE(1)
M_hash_dict_t * M_http_simple_read_headers_dict(const M_http_simple_read_t *simple)
const char * M_http_simple_read_reason_phrase(const M_http_simple_read_t *simple)
const unsigned char * M_http_simple_read_body(const M_http_simple_read_t *simple, size_t *len)
struct M_http_simple_read M_http_simple_read_t
Definition: m_http.h:785
M_uint32 M_http_simple_read_status_code(const M_http_simple_read_t *simple)
M_http_error_t
Definition: m_http.h:84
const char * M_http_errcode_to_str(M_http_error_t err)
@ M_HTTP_ERROR_SUCCESS
Definition: m_http.h:85
@ M_HTTP_METHOD_GET
Definition: m_http.h:139
M_io_error_t M_io_add_trace(M_io_t *io, size_t *layer_id, M_io_trace_cb_t callback, void *cb_arg, M_io_trace_cb_dup_t cb_dup, M_io_trace_cb_free_t cb_free)
enum M_io_trace_type M_io_trace_type_t
Definition: m_io_trace.h:54
@ M_IO_TRACE_TYPE_READ
Definition: m_io_trace.h:50
@ M_IO_TRACE_TYPE_WRITE
Definition: m_io_trace.h:51
@ M_IO_TRACE_TYPE_EVENT
Definition: m_io_trace.h:52
struct M_io M_io_t
Definition: m_io.h:59
void M_free(void *ptr) M_FREE(1)
const char * M_net_errcode_to_str(M_net_error_t err)
M_net_error_t
Definition: m_net.h:44
@ M_NET_ERROR_SUCCESS
Definition: m_net.h:45
M_bool M_net_http_simple_send(M_net_http_simple_t *hs, const char *url, void *thunk) M_WARN_UNUSED_RESULT
struct M_net_http_simple M_net_http_simple_t
Definition: m_net_http_simple.h:200
void M_net_http_simple_set_message(M_net_http_simple_t *hs, M_http_method_t method, const char *user_agent, const char *content_type, const char *charset, const M_hash_dict_t *headers, const unsigned char *message, size_t message_len)
void M_net_http_simple_cancel(M_net_http_simple_t *hs)
void M_net_http_simple_set_tlsctx(M_net_http_simple_t *hs, M_tls_clientctx_t *ctx)
void M_net_http_simple_set_timeouts(M_net_http_simple_t *hs, M_uint64 connect_ms, M_uint64 stall_ms, M_uint64 overall_ms)
M_net_http_simple_t * M_net_http_simple_create(M_event_t *el, M_dns_t *dns, M_net_http_simple_done_cb done_cb)
void M_net_http_simple_set_iocreate(M_net_http_simple_t *hs, M_net_http_simple_iocreate_cb iocreate_cb)
M_bool M_str_isempty(const char *s) M_WARN_UNUSED_RESULT
char * M_str_hexdump(int flags, size_t bytes_per_line, const char *line_prefix, const unsigned char *data, size_t data_len)
@ M_STR_HEXDUMP_NONE
Definition: m_str.h:1872
char * M_strdup(const char *s) M_WARN_UNUSED_RESULT M_MALLOC
M_bool M_tls_clientctx_set_default_trust(M_tls_clientctx_t *ctx)
M_tls_clientctx_t * M_tls_clientctx_create(void)
struct M_tls_clientctx M_tls_clientctx_t
Definition: m_tls.h:45
void M_tls_clientctx_destroy(M_tls_clientctx_t *ctx)

Typedef Documentation

◆ M_net_http_simple_t

typedef struct M_net_http_simple M_net_http_simple_t

◆ M_net_http_simple_done_cb

typedef void(* M_net_http_simple_done_cb) (M_net_error_t net_error, M_http_error_t http_error, const M_http_simple_read_t *simple, const char *error, void *thunk)

Done callback called when the request has completed.

Once this callback returns the M_net_http_simple_t object that called this callback is destroyed internally. All external references are thus invalidated.

Parameters
[in]net_errorIndicates where there was a network problem of some type or if the network operation succeeded. If set to anything other than M_NET_ERROR_SUCCESS http_error and simple should not be vaulted because HTTP data was never received and parsed.
[in]http_errorStatus of the HTTP response data parse.
[in]simpleThe parsed HTTP data object. Will only be non-NULL when net_error is M_NET_ERROR_SUCCESS and http_error is M_HTTP_ERROR_SUCCESS.
[in]errorTextual error message when either net_error or http_error indicate an error condition.
[in]thunkThunk parameter provided to send call.

◆ M_net_http_simple_iocreate_cb

typedef M_bool(* M_net_http_simple_iocreate_cb) (M_io_t *io, char *error, size_t errlen, void *thunk)

Callback to set additional I/O layers on the internal network request I/O object.

The primary use for this callback is to add tracing or bandwidth shaping. TLS should not be added here because it is handled internally.

Due to redirects multiple connection to multiple servers may need to be established. The callback may be called multiple times. Once for each I/O object created to establish a connection with a given server.

Parameters
[in]ioThe base I/O object to add layers on top of.
[in]errorError buffer to set a textual error message when returning a failure response.
[in]errlenSize of error buffer.
[in]thunkThunk parameter provided to send call.
Returns
M_TRUE on success. M_FALSE if setting up the I/O object failed and the operation should abort.

Function Documentation

◆ M_net_http_simple_create()

M_net_http_simple_t * M_net_http_simple_create ( M_event_t el,
M_dns_t dns,
M_net_http_simple_done_cb  done_cb 
)

Create an HTTP simple network object.

Parameters
[in]elEvent loop to operate on.
[in]dnsDNS object. Must be valid for the duration of this object's life.
[in]done_cbCallback that's called on completion of the request.
Returns
HTTP network object on success. Otherwise NULL on error.

◆ M_net_http_simple_cancel()

void M_net_http_simple_cancel ( M_net_http_simple_t hs)

Cancel the operation that's in progress.

The hs object is invalided by this call. The registered done callback will not be called.

Can be used to cancel an operation that has not yet been sent in order to destroy the hs object.

Parameters
[in]hsHTTP simple network object.

◆ M_net_http_simple_set_proxy_authentication()

void M_net_http_simple_set_proxy_authentication ( M_net_http_simple_t hs,
const char *  user,
const char *  pass 
)

Set proxy server authentication.

Parameters
[in]hsHTTP simple network object.
[in]userFor use in basic credential user:pass
[in]passFor use in basic credential user:pass

◆ M_net_http_simple_set_proxy()

void M_net_http_simple_set_proxy ( M_net_http_simple_t hs,
const char *  proxy_server 
)

Set proxy server.

Parameters
[in]hsHTTP simple network object.
[in]proxy_serverURL to proxy request through.

◆ M_net_http_simple_set_timeouts()

void M_net_http_simple_set_timeouts ( M_net_http_simple_t hs,
M_uint64  connect_ms,
M_uint64  stall_ms,
M_uint64  overall_ms 
)

Set operation timeouts.

On timeout the operation will abort.

No timeouts are set by default. Set to 0 to disable a timeout.

Parameters
[in]hsHTTP simple network object.
[in]connect_msConnect timeout in milliseconds. Will trigger when a connection has not been established within this time.
[in]stall_msStall timeout in milliseconds. Will trigger when the time between read and write events has been exceeded. This helps prevent a server from causing a denial of service by sending 1 byte at a time with a large internal between each one.
[in]overall_msOverall time the operation can take in milliseconds. When exceeded the operation will abort.

◆ M_net_http_simple_set_max_redirects()

void M_net_http_simple_set_max_redirects ( M_net_http_simple_t hs,
M_uint64  max 
)

Set the maximum number of allowed redirects

Default 16 redirects.

Parameters
[in]hsHTTP simple network object.
[in]maxMaximum number of redirects. 0 will disable redirects.

◆ M_net_http_simple_set_max_receive_size()

void M_net_http_simple_set_max_receive_size ( M_net_http_simple_t hs,
M_uint64  max 
)

Set max receive data size

Default 50 MB.

Parameters
[in]hsHTTP simple network object.
[in]maxMaximum number of bytes that can be received. 0 will disable redirects. Use the value (1024*1024*50) bytes to set a 50 MB limit.

◆ M_net_http_simple_set_tlsctx()

void M_net_http_simple_set_tlsctx ( M_net_http_simple_t hs,
M_tls_clientctx_t ctx 
)

Set the TLS client context for use with HTTPS connections.

It is highly recommend a TLS client context be provided even if the initial connection address is not HTTPS. It is possible for a redirect to imitate a redirect upgrade to a TLS connection.

Even if the system is known to not support HTTPS it's possible it will be changed to require it in the future. Providing the client context will prevent connections from failing in the future due to this type of server side change.

The context is only applied when necessary.

Parameters
[in]hsHTTP simple network object.
[in]ctxThe TLS client context. The context does not have to persist after being set here.

◆ M_net_http_simple_set_iocreate()

void M_net_http_simple_set_iocreate ( M_net_http_simple_t hs,
M_net_http_simple_iocreate_cb  iocreate_cb 
)

Set the I/O create callback.

The callback is called when the hs object internally creates an I/O connection with a remote system.

Parameters
[in]hsHTTP simple network object.
[in]iocreate_cbI/O create callback.

◆ M_net_http_simple_set_message()

void M_net_http_simple_set_message ( M_net_http_simple_t hs,
M_http_method_t  method,
const char *  user_agent,
const char *  content_type,
const char *  charset,
const M_hash_dict_t headers,
const unsigned char *  message,
size_t  message_len 
)

Set message data that should be sent with the request.

This is optional. If this function is not called M_net_http_simple_send will issue a GET with no data.

Parameters
[in]hsHTTP simple network object.
[in]methodHTTP method.
[in]user_agentUser agent to identify the request using. Optional.
[in]content_typeType of data being sent. Optional if no data is being sent. Or if set in headers.
[in]charsetCharacter set of data being sent. Only applies to textual data and should not be be set for binary. Optional depending on content type or if included in headers.
[in]headersAdditional headers to send with the request. Optional.
[in]messageThe data to send. Optional.
[in]message_lenThe length of the data. Required if message is not NULL otherwise should be 0.

◆ M_net_http_simple_send()

M_bool M_net_http_simple_send ( M_net_http_simple_t hs,
const char *  url,
void *  thunk 
)

Start sending the request async.

On success, the hs object is freed internally once the send completes and the done callback is called. It must not be reused.

On failure of this call it can be called again if the error can be corrected. Otherwise if this fails M_net_http_simple_cancel needs to be called to cleanup the hs object.

Parameters
[in]hsHTTP simple network object.
[in]urlThe full URL to send the request to. Must include http:// or https://.
[in]thunkThunk parameter that will be passed to the done callback. If allocated, must not be freed before the done callback is called. Unless this function returns M_FALSE which prevents the done callback from running. For example, allocating a thunk and freeing in the done callback. Or freeing when this returns M_FALSE.
Returns
M_TRUE when successfully starting the send process. hs will be freed internally. Otherwise, M_FALSE if sending could not commence. Will not call the done callback when M_FALSE. If not attempting again, allocated memory needs to be freed. An allocated thunk should be freed if necessary (would have been freed in the done callback). M_net_http_simple_cancel should be called on the hs object