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.
#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.
#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.
#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); } }