Chunked Transfer Encoding

The POST and PUT methods can be used to transfer data to the HTTP server. The data is included in the body part of the HTTP request.

When the size of the data to transmit is unknown before starting the HTTP request, the Chunked Transfer Encoding can be used. It will split the data into chunks of known size and will sent an empty chunk to advertise the end of the data. 

Additional HTTP header fields must be included when a body is present. The content type of the data must be specified with the Content-Type header field and for the Chunked Transfer encoding the Transfer-Encoding header field must be specified. Those headers will be added automatically by the µC/HTTP-client stack after the required parameters are configured. For more details, refer to section Chunked Transfer Encoding in the HTTP Reference Guide.

The function HTTPc_ReqSetParam() must be used to configure the additional parameters necessary when data is transmitted in chunks. Three parameters must be set up :

  • HTTPc_PARAM_TYPE_REQ_BODY_CONTENT_TYPE
  • HTTPc_PARAM_TYPE_REQ_BODY_CHUNK
  • HTTPc_PARAM_TYPE_REQ_BODY_HOOK

The first parameter is to set the content-type of the data, the second is a Boolean to enable the Chunked Transder Encoding and the third is to set the hook function that will be used by the µC/HTTP-client stack to retrieve the data.

Example

Since all the API function are in blocking mode in the example bellow, the HTTPc objects and string can be allocated on the application stack without problems.

The example below implements a function to send a PUT request :

  1.  An HTTP Connection is configured. 
  2. An HTTP request is configured with the three body parameters : content-type, chunk enabled and hook function.
  3. The Connection is open.
  4. The request is sent.


Listing - Chunked Transfer Encoding Example Code
/*
*********************************************************************************************************
*                                      HTTPcEx_ReqSendPUT_Chunked()
*
* Description : Example function to send a HTTP PUT request with the Chunked Transfer Encoding.
*
* Argument(s) : none.
*
* Return(s)   : DEF_YES, is request sent successfully.
*               DEF_NO,  otherwise.
*********************************************************************************************************
*/

CPU_BOOLEAN  HTTPcEx_ReqSendPUT_Chunked (void)
{
	HTTPc_CONN_OBJ        conn;
    HTTPc_REQ_OBJ         req;
    HTTPc_RESP_OBJ        resp;
    CPU_CHAR              buf[512];
    HTTPc_FLAGS           flags;
    HTTP_CONTENT_TYPE     content_type;
    CPU_SIZE_T            str_len;
    CPU_BOOLEAN           result;
    CPU_BOOLEAN           chunk_en;
    HTTPc_ERR             err;


                                                                /* ---------------- INIT NEW CONNECTION --------------- */
    HTTPc_ConnClr(&conn, &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

																/* -------------- SET CONNECTION PARAM ---------------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
    HTTPc_ConnSetParam(&conn,
                        HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK,
                       &HTTPcEx_ConnCloseCallback,
                       &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }
#endif

																   /* ----------- SET REQUEST BODY PARAMETERS ------------ */
    content_type = HTTP_CONTENT_TYPE_JSON;
    HTTPc_ReqSetParam(&req,
                       HTTPc_PARAM_TYPE_REQ_BODY_CONTENT_TYPE,
                      &content_type,
                      &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

    chunk_en = DEF_YES;
    HTTPc_ReqSetParam(&req,
                       HTTPc_PARAM_TYPE_REQ_BODY_CHUNK,
                      &chunk_en,
                      &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

    HTTPc_ReqSetParam(&req,
                       HTTPc_PARAM_TYPE_REQ_BODY_HOOK,
                      &HTTPcEx_ReqBodyHook,
                      &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
    HTTPc_ReqSetParam(&req,
                       HTTPc_PARAM_TYPE_TRANS_ERR_CALLBACK,
                      &HTTPcEx_TransErrCallback,
                      &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }
#endif

                                                                /* ----------------- OPEN CONNECTION ------------------ */
    str_len = Str_Len("www.example.com");
    flags = HTTPc_FLAG_NONE;
    result = HTTPc_ConnOpen(&conn,
                            &buf,
                             APP_HTTPc_CFG_BUF_SIZE,
                            "www.example.com",
                             str_len,
                             flags,
                            &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }
    if (result != DEF_OK) {
        return (DEF_FAIL);
    }

                                                                /* ---------------- SEND HTTP REQUEST ----------------- */
    str_len = Str_Len("/");
    flags = HTTPc_FLAG_NONE;
    result = HTTPc_ReqSend(&conn,
                           &req,
                           &resp,
                            HTTP_METHOD_PUT,
                           "/",
                            str_len,
                            flags,
                           &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

    return (DEF_OK);
}

For examples on the On Request Body hook function , refer to section Request's Body Standard Transfer since the hook function is used regardless of the transfer mode.