Add Additional Header fields to an HTTP Request

µC/HTTP-client supports the addition of header fields to an HTTP request:

    • The preprocessor macro HTTPc_CFG_HDR_TX_EN must be set to DEF_ENABLED.
    • HTTPc_HDR objects must be used to set up headed fields to add.
    • Two methods are offered by the µC/HTTP-client stack to add header fields:
      1. Passing a header fields table to to the µC/HTTP-client stack
      2. Using a hook function that will ask the application for each header field to add to the request.

Some header fields are taken care of by the µC/HTTP-client stack and must therefore not be added by the application :

    • Host
    • Content-Type
    • Content-Length
    • Transfer-Encoding
    • Connection

Using a Header Fields Table

With the first option, before sending the HTTP request, the application can prepare a table of HTTPc_HDR objects that the µC/HTTP-client will include in the request. The API function HTTPc_ReqSetParam must be used with the parameter type HTTPc_PARAM_TYPE_REQ_HDR_TBL to pass out the table to the µC/HTTP-client stack.

Listing - Adding Header Fields with a Table Example Code
#define  HTTPc_CFG_HDR_NBR_MAX       10
#define  HTTPc_CFG_HDR_VAL_LEN_MAX  100

HTTPc_HDR      HTTPc_ReqHdrTbl[HTTPc_CFG_HDR_NBR_MAX];
CPU_CHAR       HTTPc_ReqHdrValTbl[HTTPc_CFG_HDR_NBR_MAX][HTTPc_CFG_HDR_VAL_LEN_MAX];

/*
*********************************************************************************************************
*                                           HTTPc_ReqPrepareHdr()
*
* Description : Prepare the HTTP header table.
*
* Argument(s) : p_tbl    Variable that will received the pointer to header table.
*
* Return(s)   : Number of Header fields in the table.
*********************************************************************************************************
*/
static  CPU_INT08U  HTTPc_ReqPrepareHdr (HTTPc_KEY_VAL  **p_tbl)
{
	HTTPc_HDR  *p_hdr;

    p_hdr           = &HTTPc_ReqHdrTbl[0];
    p_hdr->ValPtr   = &HTTPc_ReqHdrValTbl[0][0];
    p_hdr->HdrField =  HTTP_HDR_FIELD_ACCEPT;

    Str_Copy_N(p_hdr->ValPtr, "text/*", HTTPc_CFG_HDR_VAL_LEN_MAX);

    p_hdr->ValLen = Str_Len_N(p_hdr->ValPtr, HTTPc_CFG_HDR_VAL_LEN_MAX);

   *p_ext_hdr_tbl = &HTTPc_ReqHdrTbl[0];

    return (1);
}

/*
*********************************************************************************************************
*                                           HTTPc_ReqPrepare()
*
* Description : Prepare the HTTP request to send.
*
* Argument(s) : p_req    Pointer to the HTTP Request object to configure.
*
* Return(s)   : DEF_OK,   if the request was configured successfully.
*               DEF_FAIL, otherwise.
*********************************************************************************************************
*/
static  CPU_BOOLEAN  HTTPc_ReqPrepare (HTTPc_REQ_OBJ  *p_req) 
{
    HTTPc_PARAM_TBL   tbl_obj;
    HTTPc_HDR        *p_hdr_tbl;
    CPU_INT08U        hdr_nbr;
    HTTPc_ERR         err;

                                                                /* -------------- SET HEADER FIELDS DATA -------------- */
    hdr_nbr = HTTPc_ReqPrepareHdr(&p_hdr_tbl);
    if (hdr_nbr <= 0) {
        return (DEF_FAIL);
    }

                                                                /* ------------ SET HEADER FIELDS PARAMETER ----------- */
    tbl_obj.EntryNbr = hdr_nbr;
    tbl_obj.TblPtr   = (void *)p_hdr_tbl;
    HTTPc_ReqSetParam(p_req, HTTPc_PARAM_TYPE_REQ_HDR_TBL, &tbl_obj, &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

    ...  /* TODO other operations on request if necessary. */

    return (DEF_OK);


Using a Hook Function

The Second option is to set up a hook function. The hook function will be called by the µC/HTTP-client core to add a Header Field to the request. The hook function will be called until it return DEF_YES to notified the µC/HTTP-client stack that all the fields have been added. The API function HTTPc_ReqSetParam must be used with the parameter type HTTPc_PARAM_TYPE_REQ_HDR_HOOK to pass out hook function pointer to the µC/HTTP-client stack.

Listing - Adding Header Fields with a Hook Example Code
#define  HTTPc_CFG_HDR_NBR_MAX       10
#define  HTTPc_CFG_HDR_VAL_LEN_MAX  100

CPU_INT08U     HTTPc_ReqHdrIx;
HTTPc_HDR      HTTPc_ReqHdrTbl[HTTPc_CFG_HDR_NBR_MAX];
CPU_CHAR       HTTPc_ReqHdrValTbl[HTTPc_CFG_HDR_NBR_MAX][HTTPc_CFG_HDR_VAL_LEN_MAX];


/*
*********************************************************************************************************
*                                           HTTPc_ReqPrepare()
*
* Description : Prepare the HTTP request to send.
*
* Argument(s) : p_req    Pointer to the HTTP Request object to configure.
*
* Return(s)   : DEF_OK,   if the request was configured successfully.
*               DEF_FAIL, otherwise.
*********************************************************************************************************
*/
static  CPU_BOOLEAN  HTTPc_ReqPrepare (HTTPc_REQ_OBJ  *p_req) 
{
    HTTPc_ERR       err;

                                                                /* ------------ SET STRING QUERY PARAMETER ------------ */
    HTTPc_ReqSetParam(p_req, HTTPc_PARAM_TYPE_REQ_HDR_HOOK, &HTTPc_ReqHdrHook, &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

    p_req->UserDataPtr = (void *)&HTTPc_ReqHdrIx;

    ...  /* TODO other operations on request if necessary. */

    return (DEF_OK);
}


/*
*********************************************************************************************************
*                                           HTTPc_ReqHdrHook()
*
* Description : Hook function to retrieve the header fields to include in the HTTP request.
*
* Argument(s) : p_conn   Pointer to the HTTP Connection object.
*
*               p_req    Pointer to the HTTP Request object.
*
*               p_hdr    Variable that will received the pointer to the Header field object.
*
* Return(s)   : DEF_YES, if all the header fields to include have been passed.
*               DEF_NO,  otherwise.
*********************************************************************************************************
*/
static  CPU_BOOLEAN  HTTPc_ReqHdrHook (HTTPc_CONN_OBJ   *p_conn,
                                       HTTPc_REQ_OBJ    *p_req,
                                       HTTPc_HDR       **p_hdr)
{
    HTTPc_HDR       *p_hdr_item;
    CPU_INT08U       index;


    index = *(CPU_INT08U)p_req->UserDataPtr;

    switch(index) {
        case 0:
             p_hdr_item           = &HTTPc_ReqHdrTbl[0];
             p_hdr_item->ValPtr   = &HTTPc_ReqHdrValTbl[0][0];
             p_hdr_item->HdrField =  HTTP_HDR_FIELD_ACCEPT;
            (void)Str_Copy_N(p_hdr_item->ValPtr, "text/*", HTTPc_CFG_HDR_VAL_LEN_MAX);
             p_hdr_item->ValLen = Str_Len_N(p_hdr_item->ValPtr, HTTPc_CFG_HDR_VAL_LEN_MAX);
            *p_hdr = p_hdr_item;
             index++;
            *(CPU_INT08U)p_req->UserDataPtr = index;
             return (DEF_NO);

        case 1:
             p_hdr_item           = &HTTPc_ReqHdrTbl[1];
             p_hdr_item->ValPtr   = &HTTPc_ReqHdrValTbl[1][0];
             p_hdr_item->HdrField =  HTTP_HDR_FIELD_DATE;
            (void)Str_Copy_N(p_hdr_item->ValPtr, "Thurday, 21-Aug-14 02:15:31 GMT", HTTPc_CFG_HDR_VAL_LEN_MAX);
             p_hdr_item->ValLen = Str_Len_N(p_hdr_item->ValPtr, HTTPc_CFG_HDR_VAL_LEN_MAX);
            *p_hd = p_hdr_item;
             index = 0;
            *(CPU_INT08U)p_req->UserDataPtr = index;
             return (DEF_YES);

        default:
            *p_hdr = DEF_NULL;
             index = 0;
            *(CPU_INT08U)p_req->UserDataPtr = index;
             return (DEF_YES);
    }
}