Menu

Expand
Rate this page:

HTTP Functions

Microvisor Public Beta

Microvisor is in a pre-release phase and the information contained in this document is subject to change. Some features referenced below may not be fully available until Microvisor’s General Availability (GA) release.

Microvisor system calls currently include the following functions to manage HTTP communications over the Internet.

The HTTP functions for managing requests and the responses they generate operate through Microvisor network channels. To learn how to establish network connections, and open channels through them, please see Microvisor network functions.

Return values and errors

All of the functions described below return a 32-bit integer that is one of the values from the standard Microvisor enumeration MvStatus. All possible error values for a given system call are provided with each function’s description.

Success is always signaled by a return value of zero (MV_STATUS_OKAY).

mvSendHttpRequest()

Issue an HTTP request via a channel

Declaration

extern enum MvStatus mvSendHttpRequest(MvChannelHandle handle,
                                       const struct MvHttpRequest *request);

Parameters

Parameter Description
handle The handle of the channel that will issue the request. This must be a channel of type MV_CHANNELTYPE_HTTP
request A pointer to non-secure memory in which network configuration data is stored by the application

Possible errors

Error Value Description
MV_STATUS_PARAMETERFAULT request does not reference memory accessible to the application
MV_STATUS_LATEFAULT One or more of the pointers within request — see below — are illegal
MV_STATUS_INVALIDHANDLE handle does not reference a valid channel of type MV_CHANNELTYPE_HTTP
MV_STATUS_INVALIDBUFFERSIZE The request structure will not fit in the channel’s send buffer
MV_STATUS_TOOMANYELEMENTS Too many headers (i.e., more than 32) are attached to request
MV_STATUS_CHANNELCLOSED The specified channel has already been closed
MV_STATUS_REQUESTALREADYSENT The request has already been sent, either successfully or not

Notifications

This call, if successful, may subsequently yield any of the following notifications.

Notification Event Type Description
MV_EVENTTYPE_CHANNELDATAREADABLE Issued to the host channel’s notification center when data has been received through the channel. Call mvReadHttpResponseData() to the ultimate outcome of the request

Description

The application makes use of channels of type MV_CHANNELTYPE_HTTP to issue HTTP requests to remote servers. The channel must be open for the request to be issued and of the correct type.

For each channel, only one request can be issued. If Microvisor returns MV_STATUS_PARAMETERFAULT, MV_STATUS_INVALIDHANDLE, MV_STATUS_INVALIDBUFFERSIZE or MV_STATUS_CHANNELCLOSED, then the request will not have been issued, and you can reconfigure the request and try again. Any other value indicates that the request has been sent, and any attempt to issue it again, or to use the channel for a fresh request, will result in MV_STATUS_REQUESTALREADYSENT being returned. Instead, send any subsequent HTTP request through a new channel. You can re-use the channel definition structure and buffers if you wish. Be sure to close the channel used for a given HTTP request once you have received the response or a failure notification.

The type of HTTP request is specified as the scheme prefix of the target URL. Only HTTPS — i.e., https:// — is supported. If your URL is prefixed http://, or some other scheme, the request will be rejected: the device will receive an MvHttpResponseData record with its result field equal to MV_HTTPRESULT_UNSUPPORTED_URI_SCHEME. Please see mvReadHttpResponseData() for details of the MvHttpResponseData structure.

The call’s request parameter takes a pointer to a MvHttpRequest structure:

struct MvHttpRequest {
  struct MvSizedString method;
  struct MvSizedString url;
  uint32_t num_headers;
  const struct MvHttpHeader *headers;
  struct MvSizedString body;
  uint32_t timeout_ms;
};

This structure’s properties are:

  • method — A data structure comprising the request HTTP method, i.e., GET, HEAD, POST, PUT, DELETE, PATCH or OPTIONS, as bytes and the number of bytes.
  • url — A data structure comprising the target URL as bytes and the number of bytes. Only https:// is supported as a prefix.
  • num_headers — The number of headers included in the headers array.
  • headers — A pointer to an array of one or more MvHttpHeader structures.
  • body — A data structure comprising the request body content as bytes and the number of bytes. Include an empty string if there is no body content.
  • timeout_ms — The request timeout in milliseconds. Microvisor supports timeouts from 5000ms to 10000ms.

Headers

Each entry in the headers array, if any, is a pointer to an MvHttpHeader structure:

struct MvHttpHeader {
  const uint8_t *data;
  uint32_t length;
};

This structure’s properties are:

  • data — A pointer to the header content. Do not terminate the header with <CR><LF>.
  • length — The number of bytes in data.

Microvisor automatically adds a Host: header for you. It also inserts a Content-Length: header based on the size of any data you include. Again, you do not need to add this yourself, and if you do include one, it will be overwritten by Microvisor.

The maximum number of headers you may attach is 32. An MV_STATUS_TOOMANYELEMENTS is issued for higher values.

Example

This snippet from our sample HTTP code shows how we use mvSendHttpRequest() to issue an HTTP request via the Twilio cloud. The calls takes an MvHttpRequest struct which defines the request. The function server_log() is not included here, but can be viewed in the sample HTTP code.

// Set up the request
unit32_t item_number = 1;
const char verb[] = "GET";
const char body[] = "";
char uri[46] = "";
sprintf(uri, "https://jsonplaceholder.typicode.com/todos/%u", item_number);
struct MvHttpHeader hdrs[] = {};
struct MvHttpRequest request_config = {
  .method = {
    .data = (uint8_t *)verb,
    .length = strlen(verb)
  },
  .url = {
    .data = (uint8_t *)uri,
    .length = strlen(uri)
  },
  .num_headers = 0,
  .headers = hdrs,
  .body = {
    .data = (uint8_t *)body,
    .length = strlen(body)
  },
  .timeout_ms = 10000
};

// Issue the request -- and check its status
enum MvStatus status = mvSendHttpRequest(http_handles.channel, &request_config);
if (status == MV_STATUS_OKAY) {
  server_log("Request sent to Twilio");
  return true;
}       

mvReadHttpResponseData()

Read the status of an HTTP response

Declaration

extern enum MvStatus mvReadHttpResponseData(MvChannelHandle handle,
                                            struct MvHttpResponseData *response_data);

Parameters

Parameter Description
handle The handle of the channel that passed the source request. This must be a channel of type MV_CHANNELTYPE_HTTP
response_data A pointer to non-secure memory to which an MvHttpResponseData structure will be written by Microvisor

Possible errors

Error Value Description
MV_STATUS_PARAMETERFAULT response_data does not reference memory accessible to the application
MV_STATUS_INVALIDHANDLE handle does not reference a valid channel of type MV_CHANNELTYPE_HTTP
MV_STATUS_RESPONSENOTPRESENT No HTTP response is present
MV_STATUS_CHANNELCLOSED The specified channel has already been closed

Description

Your application should call mvReadHttpResponseData() when the HTTP channel receives a notification of type MV_EVENTTYPE_CHANNELDATAREADABLE. Microvisor will write an MvHttpResponseData record which your code can then parse:

struct MvHttpResponseData {
  enum MvHttpResult result;
  uint32_t status_code;
  uint32_t num_headers;
  uint32_t body_length;
};

This structure’s properties are:

  • result — A value indicating the outcome of the request operation.
  • status_code — The standard HTTP status code returned.
  • num_headers — The number of headers in the response.
  • body_length — The length of the response body in bytes.

The value written to the record’s result field will be one of the following:

Constant Code Value Description
MV_HTTPRESULT_OK 0 The HTTP request succeeded — but check the status code
MV_HTTPRESULT_UNSUPPORTEDURISCHEME 1 An unsupported URI scheme, e.g., http://, was used in the request
MV_HTTPRESULT_UNSUPPORTEDMETHOD 2 An unsupported HTTP method was used in the request
MV_HTTPRESULT_INVALIDHEADERS 3 Invalid headers were provided in the request
MV_HTTPRESULT_INVALIDTIMEOUT 4 An invalid timeout was specified in the request (it should be in the range 5000-10000)
MV_HTTPRESULT_REQUESTFAILED 5 The HTTP request failed
MV_HTTPRESULT_RESPONSETOOLARGE 6 The HTTP response returned by the server (headers plus body) didn’t fit into the HTTP channel’s receive buffer

Example

This snippet from our sample HTTP code shows how we use mvReadHttpResponseData() to access the response to a previously issued HTTP request. The functions server_log() and server_error() are not included here, but can be viewed in the sample HTTP code.

static struct MvHttpResponseData resp_data;
enum MvStatus status = mvReadHttpResponseData(http_handles.channel, &resp_data);
if (status == MV_STATUS_OKAY) {
  // Check we successfully issued the request (`result` is OK) and
  // the request was successful (status code 200)
  if (resp_data.result == MV_HTTPRESULT_OK) {
    if (resp_data.status_code == 200) {
      server_log("HTTP response header count: %lu", resp_data.num_headers);
      server_log("HTTP response body length: %lu", resp_data.body_length);
    } else {
      server_error("HTTP status code: %lu", resp_data.status_code);
    }
  } else {
    server_error("Request failed. Status: %i", resp_data.result);;
  }
} else {
  server_error("Response data read failed. Status: %i", status);
}

mvReadHttpResponseHeader()

Read header data from an HTTP response

Declaration

extern enum MvStatus mvReadHttpResponseHeader(MvChannelHandle handle,
                                              uint32_t header_index,
                                              uint8_t *buffer,
                                              uint32_t buffer_size);

Parameters

Parameter Description
handle The handle of the channel that passed the source request. This must be a channel of type MV_CHANNELTYPE_HTTP
header_index The index of the header you require
buffer A pointer to non-secure memory into which the header will be written by Microvisor
buffer_size The size of the buffer in bytes

Possible errors

Error Value Description
MV_STATUS_PARAMETERFAULT buffer does not reference memory accessible to the application
MV_STATUS_INVALIDHANDLE handle does not reference a valid channel of type MV_CHANNELTYPE_HTTP
MV_STATUS_HEADERINDEXINVALID The specified header index is greater the number of headers in the response - 1
MV_STATUS_RESPONSENOTPRESENT No HTTP response is present
MV_STATUS_CHANNELCLOSED The specified channel has already been closed

Description

Your call to mvReadHttpResponseData() will indicate the number of headers, if any, included in the response. To read one of these headers, call this function and pass in a header_index value indicating the desired header’s position in the sequence of headers. Microvisor will write the header into the buffer you specify in the call.

Example

The following function demonstrates how you can use mvReadHttpResponseHeader() to extract one or more headers from the response to a previously issued HTTP request and log them. The functions server_log() and server_error() are not included here, but can be viewed in our sample HTTP code.

/**
 * @brief Output all received headers.
 *
 * @param n: The number of headers to list.
 */
void output_headers(uint32_t n) {
  if (n > 0) {
    uint8_t buffer[2048];
    for (uint32_t i = 0 ; i < n ; ++i) {
      memset((void *)buffer, 0x00, 256);
      enum MvStatus status = mvReadHttpResponseHeader(http_handles.channel, i, buffer, 2048);
      if (status == MV_STATUS_OKAY) {
        server_log("%lu. %s", i + 1, buffer);
      } else {
        server_error("Could not read header %lu", i + 1);
      }
    }
  }
}

mvReadHttpResponseBody()

Read body data from an HTTP response

Declaration

extern enum MvStatus mvReadHttpResponseBody(MvChannelHandle handle,
                                            uint32_t offset,
                                            uint8_t *buffer,
                                            uint32_t buffer_size);

Parameters

Parameter Description
handle The handle of the channel that passed the source request. This must be a channel of type MV_CHANNELTYPE_HTTP
offset The byte offset from the start of the body to read from
buffer A pointer to non-secure memory into which the body data will be written by Microvisor
buffer_size The size of the buffer in bytes

Possible Errors

Error Value Description
MV_STATUS_PARAMETERFAULT buffer does not reference memory accessible to the application
MV_STATUS_INVALIDHANDLE handle does not reference a valid channel of type MV_CHANNELTYPE_HTTP
MV_STATUS_OFFSETINVALID The value of offset exceeds the size of the returned body
MV_STATUS_RESPONSENOTPRESENT No HTTP response is present
MV_STATUS_CHANNELCLOSED The specified channel has already been closed

Description

Your call to mvReadHttpResponseData() will indicate the length of the response’s body, if any. To read all or part of the body data, call this function.

To read just a portion of the body, set a non-zero value of offset as the start byte and/or specify a buffer size below that of the response body’s length. Microvisor will read from the response body from the byte at offset up to the end of the target buffer.

Example

This snippet from our sample HTTP code shows how we use mvReadHttpResponseBody() to access the body data within the response to a previously issued HTTP request. See the mvReadHttpResponseData() example for the code that wraps this stanza. The functions server_log() and server_error() are not included here, but can be viewed in the sample HTTP code.

// Set up a buffer that we'll get Microvisor to write
// the response body into
uint8_t buffer[resp_data.body_length + 1];
memset((void *)buffer, 0x00, resp_data.body_length + 1);
status = mvReadHttpResponseBody(http_handles.channel, 0, buffer, resp_data.body_length);
if (status == MV_STATUS_OKAY) {
  // Retrieved the body data successfully so log it
  server_log("Message JSON:\n%s", buffer);
} else {
  server_error("HTTP response body read status %i", status);
}
Rate this page:

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd by visiting Twilio's Stack Overflow Collective or browsing the Twilio tag on Stack Overflow.

Thank you for your feedback!

Please select the reason(s) for your feedback. The additional information you provide helps us improve our documentation:

Sending your feedback...
🎉 Thank you for your feedback!
Something went wrong. Please try again.

Thanks for your feedback!

thanks-feedback-gif