Retrieve HTTP Response Data

The HTTPc Response object will be filled by the µC/HTTP-client stack with the below fields received in the HTTP response:

  • The Server HTTP version
  • Status Code
  • Reason phrase
  • Content type (if body present)
  • Content Length (if body present)

If the function HTTPc_ReqSend was called in the blocking mode and the function returned with no errors, then the HTTPc Response object can be read by the application after the function call. Otherwise, the application must way until the On Transaction Complete function is called by the µC/HTTP-client stack to read the HTTPc Response object.

Two hook functions allow the application to retrieve more data from the HTTP response :

The first hook allows the application to retrieve header fields contained in the HTTP response. If the hook function is set via the function HTTPc_ReqSetParam with the parameter type HTTPc_PARAM_TYPE_RESP_HDR_HOOK, the hook will be called by the µC/HTTP-client stack for each header field parsed and recognized by the stack. The application as therefore the liberty to copy the data received on its side inside the hook function.

The second hook allows the application to retrieve the data contained in the HTTP response body. If the hook function is set via the function HTTPc_ReqSetParam with the parameter type HTTPc_PARAM_TYPE_RESP_BODY_HOOK, the hook will be called by the µC/HTTP-client stack for each piece of data received until all is received.

Examples

Blocking Mode

In the first example below, the function HTTPc_ReqSend is called in the blocking mode. Therefore, the HTTPc Response object can be read just after the function call.

Listing - Retrieve HTTP Response Data Example Code #1
#define  HTTP_SERVER_HOSTNAME   "www.example.com"
#define  HTTPc_EX_CFG_BUF_SIZE   1024

/*
*********************************************************************************************************
*                                         HTTPcEx_ReqSendGET()
*
* Description : Example function to send a GET request and retrieve HTTP response.
*
* Argument(s) : None.
*
* Return(s)   : DEF_OK,   if HTTP transaction was successful.
*               DEF_FAIL, otherwise.
*********************************************************************************************************
*/

CPU_BOOLEAN  HTTPcEx_ReqSendGET (void)
{          
    HTTPc_CONN_OBJ   conn;
    HTTPc_REQ_OBJ    req;
    HTTPc_RESP_OBJ   resp;
    CPU_CHAR         buf[HTTPc_EX_CFG_BUF_SIZE];
    HTTPc_FLAGS      flags;
    CPU_SIZE_T       str_len;
    CPU_BOOLEAN      result;
    HTTPc_ERR        err;

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

                                                                /* --------------- SET CONN'S CALLBACKS --------------- */
#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

                                                                /* ----------------- INIT NEW REQUEST ----------------- */
    HTTPc_ReqClr(&req, &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

                                                                /* ------------- SET TRANS HOOK FUNCTIONS ------------- */
    HTTPc_ReqSetParam(&req, 
                       HTTPc_PARAM_TYPE_RESP_HDR_HOOK, 
                      &HTTPcEx_RespHdrHook, 
                      &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

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

                                                                /* ---------- SET TRANS CALLBACK FUNCTIONS ------------ */
#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(HTTP_SERVER_HOSTNAME);
    flags = HTTPc_FLAG_NONE;
    result = HTTPc_ConnOpen(&conn,
                            &buf,
                             HTTPc_EX_CFG_BUF_SIZE,
                             HTTP_SERVER_HOSTNAME,
                             str_len,
                             flags,
                            &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }
    if (result == DEF_OK) {
        printf("Connection to server succeeded.\n\r");
    } else {
        printf("Connection to server failed.\n\r");
    }

                                                                /* ---------------- SEND HTTP REQUEST ----------------- */
    str_len = Str_Len("/");
    flags = HTTPc_FLAG_NONE;
    result = HTTPc_ReqSend(&conn,
                           &req,
                           &resp,
                           HTTP_METHOD_GET,
                           "/",
                           str_len,
                           flags,
                          &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }
    if (result == DEF_OK) {
        printf("%s\n\r", p_resp->ReasonPhrasePtr);
    }

	return (DEF_OK);
}


No-Blocking Mode

In this second example, the function HTTPc_ReqSend is called in the no-blocking mode. Therefore, the HTTPc Response object can be read once the On Transaction Complete function was called.

Listing - Retrieve HTTP Response Data Example Code #2
#define  HTTP_SERVER_HOSTNAME   "www.example.com"
#define  HTTPc_EX_CFG_BUF_SIZE   1024

HTTPc_CONN_OBJ  HTTPcEx_Conn;
HTTPc_REQ_OBJ   HTTPcEx_Req;
HTTPc_RESP_OBJ  HTTPcEx_Resp;
CPU_CHAR        HTTPcEx_ConnBuf[HTTPc_EX_CFG_BUF_SIZE];


/*
*********************************************************************************************************
*                                         HTTPcEx_ReqSendGET()
*
* Description : Example function to send a GET request and retrieve HTTP response.
*
* Argument(s) : None.
*
* Return(s)   : DEF_OK,   if HTTP transaction was successful.
*               DEF_FAIL, otherwise.
*********************************************************************************************************
*/

CPU_BOOLEAN  HTTPcEx_ReqSendGET (void)
{          
    HTTPc_CONN_OBJ   *p_conn;
    HTTPc_REQ_OBJ    *p_req;
    HTTPc_RESP_OBJ   *p_resp;
    CPU_CHAR         *p_buf;
    HTTPc_FLAGS       flags;
    CPU_SIZE_T        str_len;
    CPU_BOOLEAN       result;
    HTTPc_ERR         err;


    p_conn = &HTTPcEx_Conn;
    p_req  = &HTTPcEx_Req;
    p_resp = &HTTPcEx_Resp;
    p_buf  = &HTTPcEx_ConnBuf[0];

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

                                                                /* --------------- SET CONN'S CALLBACKS --------------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
    HTTPc_ConnSetParam(p_conn,
                       HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK,
                      &HTTPcEx_ConnCloseCallback,
                      &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }
#endif

                                                                /* ----------------- INIT NEW REQUEST ----------------- */
    HTTPc_ReqClr(p_req, &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

                                                                /* ------------- SET TRANS HOOK FUNCTIONS ------------- */
    HTTPc_ReqSetParam(p_req, 
                      HTTPc_PARAM_TYPE_RESP_HDR_HOOK, 
                     &HTTPcEx_RespHdrHook, 
                     &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

    HTTPc_ReqSetParam(p_req, 
                      HTTPc_PARAM_TYPE_RESP_BODY_HOOK, 
                     &HTTPcEx_RespBodyHook, 
                     &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

                                                                /* ---------- SET TRANS CALLBACK FUNCTIONS ------------ */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
    HTTPc_ReqSetParam(p_req, 
                      HTTPc_PARAM_TYPE_TRANS_COMPLETE_CALLBACK, 
                     &HTTPcEx_TransDoneCallback, 
                     &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

    HTTPc_ReqSetParam(p_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(HTTP_SERVER_HOSTNAME);
    flags = HTTPc_FLAG_NONE;
    result = HTTPc_ConnOpen(p_conn,
                            p_buf,
                            HTTPc_EX_CFG_BUF_SIZE,
                            HTTP_SERVER_HOSTNAME,
                            str_len,
                            flags,
                           &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }
    if (result == DEF_OK) {
        printf("Connection to server succeeded.\n\r");
    } else {
        printf("Connection to server failed.\n\r");
    }

                                                                /* ---------------- SEND HTTP REQUEST ----------------- */
    str_len = Str_Len("/");
    flags = HTTPc_FLAG_NONE;
    DEF_BIT_SET(flags, HTTPc_FLAG_REQ_NO_BLOCK);
    result = HTTPc_ReqSend(p_conn,
                           p_req,
                           p_resp,
                           HTTP_METHOD_GET,
                           "/",
                           str_len,
                           flags,
                          &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

	return (DEF_OK);
}


/*
*********************************************************************************************************
*                                      HTTPcEx_TransDoneCallback()
*
* Description : Example callback function to be notified when an HTTP transaction was completed.
*
*               Once this callback is called, the HTTPc Response object is ready to be read by the application
*               if no error occurred.
*
* Argument(s) : p_conn     Pointer to current HTTPc Connection object.
*
*               p_req      Pointer to current HTTPc Requet object.
*
*               p_resp     Pointer to current HTTPc Response object.
*
*               status     DEF_OK, if transaction was complete successfully.
*                          DEF_NO, otherwise.
*
* Return(s)   : None.
*********************************************************************************************************
*/

static  void  HTTPcEx_TransDoneCallback(HTTPc_CONN_OBJ    *p_conn,
                                        HTTPc_REQ_OBJ     *p_req,
                                        HTTPc_RESP_OBJ    *p_resp,
                                        CPU_BOOLEAN        status)
{
	if (status == DEF_OK) {
        printf("Transaction response status: %s\n\r", p_resp->ReasonPhrasePtr);
    } else {
        printf("Transaction failed\n\r");
    }
}


Response Header and Body Hook Functions

The example code below is an implementation of the On Response Header hook function and the On Response Body hook function.

Listing - Response Hook Functions Example Code
#define  HTTPc_EX_CFG_HDR_VAL_BUF_LEN  100

CPU_CHAR  HTTPcEx_HdrValBuf[HTTPc_EX_CFG_HDR_VAL_BUF_LEN];

/*
*********************************************************************************************************
*                                         HTTPcEx_RespHdrHook()
*
* Description : Example hook function to retrieve Header Fields received in the HTTP response.
*
* Argument(s) : p_conn      Pointer to current HTTPc Connection object.
*
*               p_req       Pointer to current HTTPc Request object.
*
*               hdr_field   Header field type received.
*
*               p_hdr_val   Pointer to Header field value string received.
*
*               val_len     Length of value string.
*
* Return(s)   : None.
*********************************************************************************************************
*/

static  void  HTTPcEx_RespHdrHook(HTTPc_CONN_OBJ    *p_conn,
                                  HTTPc_REQ_OBJ     *p_req,
                                  HTTP_HDR_FIELD     hdr_field,
                                  CPU_CHAR          *p_hdr_val,
                                  CPU_INT16U         val_len)
{
    CPU_CHAR    *p_buf;
    CPU_INT16U   len;

    p_buf = &HTTPcEx_HdrValBuf[0];

    switch (hdr_field) {
        case HTTP_HDR_FIELD_DATE:
        case HTTP_HDR_FIELD_SERVER:
             len = DEF_MIN((HTTPc_EX_CFG_HDR_VAL_BUF_LEN - 1), val_len);
             Mem_Copy(p_buf, p_hdr_val, len);
             p_buf += len;
            *p_buf  = '\0';
             break;


        default:
             break;
    }
}


/*
*********************************************************************************************************
*                                         HTTPcEx_RespBodyHook()
*
* Description : Example hook function to retrieve body data.
*
*               In this example, a html file is received and is copied into a file. 
*               µC/FS is used as File System.
*
* Argument(s) : p_conn        Pointer to current HTTPc Connection object.
*
*               p_req         Pointer to current HTTPc Request object.
*
*               content_type  Content type of the body received in the HTTP response.
*
*               p_data        Pointer to the data piece received.
*
*               data_len      Length of data piece received.
*
*               last_chunk    DEF_YES, if this represent the last piece of the data body to receive.
*                             DEF_NO,  if data still remains to be received.
*
* Return(s)   : None.
*********************************************************************************************************
*/

static  void  HTTPcEx_RespBodyHook (HTTPc_CONN_OBJ     *p_conn,
                                    HTTPc_REQ_OBJ      *p_req,
                                    HTTP_CONTENT_TYPE   content_type,
                                    void               *p_data,
                                    CPU_INT32U          data_len,
                                    CPU_BOOLEAN         last_chunk)
{
    FS_FILE            *p_file;
    FS_FLAGS            fs_flags;
    CPU_SIZE_T          size_wr;
    CPU_SIZE_T          size_wr_tot;
    CPU_BOOLEAN         is_open;
    FS_ERR              err_fs;


    is_open = FSFile_IsOpen("\\index.html",
                            &fs_flags,
                            &err_fs);
    if (err_fs != FS_ERR_NONE) {
        return;
    }

    if (is_open == DEF_NO) {
        fs_flags = 0;
        DEF_BIT_SET(fs_flags, FS_FILE_ACCESS_MODE_WR);
        DEF_BIT_SET(fs_flags, FS_FILE_ACCESS_MODE_CREATE);
        DEF_BIT_SET(fs_flags, FS_FILE_ACCESS_MODE_TRUNCATE);
        p_file = FSFile_Open("index.html",
                              fs_flags,
                             &err_fs);
        if (err_fs != FS_ERR_NONE) {
            return;
        }
        p_req->UserDataPtr = (void *)p_file;
    } else {
        p_file = (FS_FILE *)p_req->UserDataPtr;
    }

    switch (content_type) {
        case HTTP_CONTENT_TYPE_HTML:
             if (p_data != DEF_NULL) {
                 size_wr     = 0;
                 size_wr_tot = 0;
                 while (size_wr < data_len) {
                     size_wr = FSFile_Wr(p_file,
                                         p_data,
                                         data_len,
                                        &err_fs);
                     if (err_fs != FS_ERR_NONE) {
                         return;
                     }
                     size_wr_tot += size_wr;
                 }
             }
             break;

        case HTTP_CONTENT_TYPE_OCTET_STREAM:
        case HTTP_CONTENT_TYPE_PDF:
        case HTTP_CONTENT_TYPE_ZIP:
        case HTTP_CONTENT_TYPE_GIF:
        case HTTP_CONTENT_TYPE_JPEG:
        case HTTP_CONTENT_TYPE_PNG:
        case HTTP_CONTENT_TYPE_JS:
        case HTTP_CONTENT_TYPE_PLAIN:
        case HTTP_CONTENT_TYPE_CSS:
        case HTTP_CONTENT_TYPE_JSON:
        default:
             break;
    }

    if (last_chunk == DEF_YES) {
        FSFile_Close(p_file, &err_fs);
    }
}