| | |
| | | /******************************************************************************* |
| | | * File Name : HTTP.c |
| | | * Description : |
| | | * Created on : 2020年7月1日 |
| | | * Author : 杜键 |
| | | * Created on : 2020��7��1�� |
| | | * Author : �ż� |
| | | *******************************************************************************/ |
| | | |
| | | /******************************************************************************* |
| | |
| | | |
| | | static HIDO_UINT32 l_u32HTTPTryCnt = 0; |
| | | static HIDO_UINT32 l_u32HTTPPort = 80; |
| | | static HIDO_CHAR l_acHTTPPath[64]; |
| | | static HIDO_CHAR l_acHTTPPath[128]; // Increased from 64 to 128 for longer file paths |
| | | static HIDO_CHAR l_acHTTPHost[64]; |
| | | static HIDO_UINT32 l_u32HTTPPostLen = 0; |
| | | |
| | |
| | | * Input : |
| | | * Output : |
| | | * Return : |
| | | * Author : 杜键 |
| | | * Modified Date: : 2020年7月1日 |
| | | * Author : �ż� |
| | | * Modified Date: : 2020��7��1�� |
| | | *******************************************************************************/ |
| | | static HIDO_INT32 HTTPClient_Response(HIDO_UINT32 _u32RespCode, HIDO_UINT8 *_pu8Data, HIDO_UINT32 _u32Len) |
| | | { |
| | |
| | | * Input : |
| | | * Output : |
| | | * Return : |
| | | * Author : 杜键 |
| | | * Modified Date: : 2020年7月1日 |
| | | * Author : �ż� |
| | | * Modified Date: : 2020��7��1�� |
| | | *******************************************************************************/ |
| | | static HIDO_VOID HTTPClient_TimerCallback(HIDO_VOID *_pArg) |
| | | { |
| | |
| | | * Input : |
| | | * Output : |
| | | * Return : |
| | | * Author : 杜键 |
| | | * Modified Date: : 2020年11月14日 |
| | | * Author : �ż� |
| | | * Modified Date: : 2020��11��14�� |
| | | *******************************************************************************/ |
| | | static void HTTPClient_SocketEventProc(HIDO_INT32 _i32SockID, E_SocketEvent _eEvent, HIDO_VOID *_pArg) |
| | | { |
| | |
| | | HIDO_TimerCancel(l_u32HTTPClientTimerID); |
| | | l_eHTTPClientState = HTTP_CLIENT_STATE_IDLE; |
| | | |
| | | // 对于GET_FILE方法,发送NULL表示下载完成 |
| | | if(HTTP_METHOD_GET_FILE == l_eHTTPMethod) |
| | | { |
| | | HTTPClient_Response(l_u32HTTPRespCode, HIDO_NULL, 0); |
| | | } |
| | | else |
| | | { |
| | | HTTPClient_Response(l_u32HTTPRespCode, l_pu8HTTPRespBody, l_u32HTTPContentLength); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | HIDO_TimerCancel(l_u32HTTPClientTimerID); |
| | |
| | | |
| | | if (HTTP_RECV_STATE_HEAD == l_eHTTPRecvState) |
| | | { |
| | | /* 收到"\r\n\r\n */ |
| | | /* �յ�"\r\n\r\n */ |
| | | l_pu8HTTPRespBody = (HIDO_UINT8 *)HIDO_UtilStrnstr(l_acHTTPRecvBuff, "\r\n\r\n", u32RecvLen); |
| | | if (l_pu8HTTPRespBody != HIDO_NULL) |
| | | { |
| | |
| | | break; |
| | | } |
| | | |
| | | /* 获取文件分片信息 */ |
| | | /* ��ȡ�ļ���Ƭ��Ϣ */ |
| | | if(HTTP_METHOD_GET_FILE == l_eHTTPMethod) |
| | | { |
| | | HIDO_DataStruct stETag; |
| | | |
| | | memset(&l_stHTTPGetFileResponse, 0, sizeof(l_stHTTPGetFileResponse)); |
| | | |
| | | // 检查是否有Content-Range头(206 Partial Content响应) |
| | | pcKeyName = HIDO_UtilStrnstr(l_acHTTPRecvBuff, "Content-Range: ", u32RecvLen); |
| | | if (pcKeyName != HIDO_NULL) |
| | | { |
| | | // 有Range,解析Range信息 |
| | | if (HIDO_UtilParseFormat((HIDO_UINT8 *) pcKeyName, |
| | | u32RecvLen - (pcKeyName - l_acHTTPRecvBuff), "Content-Range: bytes %d-%d/%d\r\n", |
| | | &u32Range0, &u32Range1, &u32RangeAll) != 3) |
| | | { |
| | | Socket_Close(l_i32HTTPClientSockID); |
| | | |
| | | break; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Socket_Close(l_i32HTTPClientSockID); |
| | | |
| | | break; |
| | | } |
| | | |
| | | l_stHTTPGetFileResponse.m_u32RangeBegin = u32Range0; |
| | | l_stHTTPGetFileResponse.m_u32RangeEnd = u32Range1; |
| | | l_stHTTPGetFileResponse.m_u32RangeTotal = u32RangeAll; |
| | | } |
| | | else |
| | | { |
| | | // 无Range头,使用Content-Length作为总大小(200 OK响应) |
| | | l_stHTTPGetFileResponse.m_u32RangeBegin = 0; |
| | | l_stHTTPGetFileResponse.m_u32RangeEnd = l_u32HTTPContentLength - 1; |
| | | l_stHTTPGetFileResponse.m_u32RangeTotal = l_u32HTTPContentLength; |
| | | } |
| | | |
| | | // ETag是可选的 |
| | | pcKeyName = HIDO_UtilStrnstr(l_acHTTPRecvBuff, "ETag: ", u32RecvLen); |
| | | if (pcKeyName != HIDO_NULL) |
| | | { |
| | | if (HIDO_UtilParseFormat((HIDO_UINT8 *) pcKeyName, |
| | | u32RecvLen - (pcKeyName - l_acHTTPRecvBuff), "ETag: %p\r\n", &stETag) != 1) |
| | | u32RecvLen - (pcKeyName - l_acHTTPRecvBuff), "ETag: %p\r\n", &stETag) == 1) |
| | | { |
| | | Socket_Close(l_i32HTTPClientSockID); |
| | | |
| | | break; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Socket_Close(l_i32HTTPClientSockID); |
| | | |
| | | break; |
| | | } |
| | | |
| | | if((stETag.m_u32Len + 1) < sizeof(l_stHTTPGetFileResponse.m_acETag)) |
| | | { |
| | | memcpy(l_stHTTPGetFileResponse.m_acETag, stETag.m_pData, stETag.m_u32Len); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | l_u32HTTPRecvTotalLen = l_pu8HTTPRespBody - (HIDO_UINT8 *)l_acHTTPRecvBuff + l_u32HTTPContentLength; |
| | | l_eHTTPRecvState = HTTP_RECV_STATE_BODY; |
| | | |
| | | if (l_u32HTTPRecvBuffLen >= l_u32HTTPRecvTotalLen) |
| | | { |
| | | // 对于GET_FILE方法,需要先传递body数据 |
| | | if(HTTP_METHOD_GET_FILE == l_eHTTPMethod && l_u32HTTPContentLength > 0) |
| | | { |
| | | HTTPClient_Response(l_u32HTTPRespCode, l_pu8HTTPRespBody, l_u32HTTPContentLength); |
| | | } |
| | | Socket_Close(l_i32HTTPClientSockID); |
| | | } |
| | | } |
| | |
| | | { |
| | | if (l_u32HTTPRecvBuffLen >= l_u32HTTPRecvTotalLen) |
| | | { |
| | | // 对于GET_FILE方法,需要先传递body数据 |
| | | if(HTTP_METHOD_GET_FILE == l_eHTTPMethod && l_u32HTTPContentLength > 0) |
| | | { |
| | | HTTPClient_Response(l_u32HTTPRespCode, l_pu8HTTPRespBody, l_u32HTTPContentLength); |
| | | } |
| | | Socket_Close(l_i32HTTPClientSockID); |
| | | } |
| | | } |
| | |
| | | |
| | | /******************************************************************************* |
| | | * Function Name : HTTPClient_ParseUrl |
| | | * Description : 解析Url |
| | | * Description : ����Url |
| | | * Input : |
| | | * Output : |
| | | * Return : |
| | | * Author : 杜键 |
| | | * Modified Date: : 2020年7月1日 |
| | | * Author : �ż� |
| | | * Modified Date: : 2020��7��1�� |
| | | *******************************************************************************/ |
| | | HIDO_INT32 HTTPClient_ParseUrl(HIDO_CHAR *_pcUrl, HIDO_CHAR *_pcHost, HIDO_UINT32 _u32HostSize, |
| | | HIDO_CHAR *_pcPath, HIDO_UINT32 _u32PathSize, HIDO_UINT32 *_pu32Port) |
| | |
| | | * Input : |
| | | * Output : |
| | | * Return : |
| | | * Author : 杜键 |
| | | * Modified Date: : 2021年5月3日 |
| | | * Author : �ż� |
| | | * Modified Date: : 2021��5��3�� |
| | | *******************************************************************************/ |
| | | HIDO_INT32 HTTPClient_GetPostFileData(HIDO_UINT32 _u32Offset, HIDO_VOID *_pBuff, HIDO_UINT32 _u32BuffSize, HIDO_UINT32 *_pu32Len) |
| | | { |
| | |
| | | * Input : |
| | | * Output : |
| | | * Return : |
| | | * Author : 杜键 |
| | | * Modified Date: : 2020年7月1日 |
| | | * Author : �ż� |
| | | * Modified Date: : 2020��7��1�� |
| | | *******************************************************************************/ |
| | | HIDO_INT32 HTTPClient_Post(HIDO_CHAR *_pcUrl, HIDO_CHAR *_pcBody, HIDO_UINT32 _u32BodyLen, FN_HTTPResponseCallback _fnResponseCallback, HIDO_VOID *_pArg) |
| | | { |
| | |
| | | return HIDO_ERR; |
| | | } |
| | | |
| | | /* 解析Url */ |
| | | /* ����Url */ |
| | | if(HTTPClient_ParseUrl(_pcUrl, l_acHTTPHost, sizeof(l_acHTTPHost), l_acHTTPPath, sizeof(l_acHTTPPath), &l_u32HTTPPort) != HIDO_OK) |
| | | { |
| | | return HIDO_ERR; |
| | |
| | | * Input : |
| | | * Output : |
| | | * Return : |
| | | * Author : 杜键 |
| | | * Modified Date: : 2020年7月1日 |
| | | * Author : �ż� |
| | | * Modified Date: : 2020��7��1�� |
| | | *******************************************************************************/ |
| | | HIDO_INT32 HTTPClient_Get(HIDO_CHAR *_pcUrl, FN_HTTPResponseCallback _fnResponseCallback, HIDO_VOID *_pArg) |
| | | { |
| | |
| | | return HIDO_ERR; |
| | | } |
| | | |
| | | /* 解析Url */ |
| | | /* ����Url */ |
| | | if(HTTPClient_ParseUrl(_pcUrl, l_acHTTPHost, sizeof(l_acHTTPHost), l_acHTTPPath, sizeof(l_acHTTPPath), &l_u32HTTPPort) != HIDO_OK) |
| | | { |
| | | return HIDO_ERR; |
| | |
| | | |
| | | /******************************************************************************* |
| | | * Function Name : HTTPClient_GetFile |
| | | * Description : HTTP 下载文件 |
| | | * Input : _pcUrl 文件连接 |
| | | * : _fnGetFileCallback 文件下载事件回调 |
| | | * : _pstOpt 下载参数 |
| | | * : _pArg 用户参数,回调使用 |
| | | * Description : HTTP �����ļ� |
| | | * Input : _pcUrl ����� |
| | | * : _fnGetFileCallback �ļ������¼��ص� |
| | | * : _pstOpt ���ز��� |
| | | * �� _pArg �û�����,�ص�ʹ�� |
| | | * Output : None |
| | | * Return : HIDO_OK 成功,HIDO_ERR 失败 |
| | | * Author : 杜键 |
| | | * Modified Date: : 2020年7月1日 |
| | | * Return : HIDO_OK �ɹ�,HIDO_ERR ʧ�� |
| | | * Author : �ż� |
| | | * Modified Date: : 2020��7��1�� |
| | | *******************************************************************************/ |
| | | HIDO_INT32 HTTPClient_GetFile(HIDO_CHAR *_pcUrl, FN_HTTPGetFileCallback _fnGetFileCallback, ST_HTTPGetFileOpt *_pstOpt, HIDO_VOID *_pArg) |
| | | { |
| | | HIDO_INT32 ret; |
| | | |
| | | if(l_eHTTPClientState != HTTP_CLIENT_STATE_IDLE) |
| | | { |
| | | return HIDO_ERR; |
| | |
| | | return HIDO_ERR; |
| | | } |
| | | |
| | | /* 解析Url */ |
| | | if(HTTPClient_ParseUrl(_pcUrl, l_acHTTPHost, sizeof(l_acHTTPHost), l_acHTTPPath, sizeof(l_acHTTPPath), &l_u32HTTPPort) != HIDO_OK) |
| | | /* ����Url */ |
| | | ret = HTTPClient_ParseUrl(_pcUrl, l_acHTTPHost, sizeof(l_acHTTPHost), l_acHTTPPath, sizeof(l_acHTTPPath), &l_u32HTTPPort); |
| | | if(ret != HIDO_OK) |
| | | { |
| | | return HIDO_ERR; |
| | | } |
| | |
| | | /* URL */ |
| | | HIDO_UtilSnprintf(l_acHTTPUrl, sizeof(l_acHTTPUrl), _pcUrl); |
| | | |
| | | // 构建基础HTTP请求头 |
| | | l_u32HTTPSendBuffLen = HIDO_UtilSnprintf(l_acHTTPSendBuff, sizeof(l_acHTTPSendBuff), |
| | | "GET /%s HTTP/1.1\r\n" |
| | | "Host: %s\r\n" |
| | | "User-Agent: QUECTEL_MODULE\r\n" |
| | | "Connection: Keep-Alive\r\n" |
| | | "Accept: */*\r\n" |
| | | "Accept: */*\r\n", |
| | | l_acHTTPPath, l_acHTTPHost); |
| | | |
| | | // 只有当RangeEnd > RangeBegin且不为0时才添加Range头 |
| | | if(_pstOpt->m_u32RangeEnd > 0 && _pstOpt->m_u32RangeEnd != 0xFFFFFFFF) |
| | | { |
| | | l_u32HTTPSendBuffLen += HIDO_UtilSnprintf(l_acHTTPSendBuff + l_u32HTTPSendBuffLen, |
| | | sizeof(l_acHTTPSendBuff) - l_u32HTTPSendBuffLen, |
| | | "Range: bytes=%u-%u\r\n", |
| | | l_acHTTPPath, l_acHTTPHost, _pstOpt->m_u32RangeBegin, _pstOpt->m_u32RangeEnd); |
| | | _pstOpt->m_u32RangeBegin, _pstOpt->m_u32RangeEnd); |
| | | } |
| | | |
| | | if(strlen(_pstOpt->m_acIfRange) != 0) |
| | | { |
| | |
| | | |
| | | /******************************************************************************* |
| | | * Function Name : HTTPClient_PostFile |
| | | * Description : HTTP 上传文件 |
| | | * Input : _pcUrl HTTP路径 |
| | | * : _pcFileName 文件名称 |
| | | * : _fnResponseCallback HTTP响应回调函数 |
| | | * : _pArg 参数 |
| | | * Description : HTTP �ϴ��ļ� |
| | | * Input : _pcUrl HTTP·�� |
| | | * : _pcFileName ����� |
| | | * : _fnResponseCallback HTTP��Ӧ�ص����� |
| | | * : _pArg ���� |
| | | * Output : Mone |
| | | * Return : HIDO_OK 成功,HIDO_ERR 失败 |
| | | * Author : 杜键 |
| | | * Modified Date: : 2021年5月3日 |
| | | * Return : HIDO_OK �ɹ�,HIDO_ERR ʧ�� |
| | | * Author : �ż� |
| | | * Modified Date: : 2021��5��3�� |
| | | *******************************************************************************/ |
| | | HIDO_INT32 HTTPClient_PostFile(HIDO_CHAR *_pcUrl, FN_HTTPPostDataCallback _fnPostDataCallback, FN_HTTPResponseCallback _fnResponseCallback, |
| | | HIDO_VOID *_pArg) |
| | |
| | | return HIDO_ERR; |
| | | } |
| | | |
| | | /* 解析Url */ |
| | | /* ����Url */ |
| | | if(HTTPClient_ParseUrl(_pcUrl, l_acHTTPHost, sizeof(l_acHTTPHost), l_acHTTPPath, sizeof(l_acHTTPPath), &l_u32HTTPPort) != HIDO_OK) |
| | | { |
| | | return HIDO_ERR; |
| | |
| | | |
| | | /******************************************************************************* |
| | | * Function Name : HTTPClient_Poll |
| | | * Description : HTTP客户端轮询处理 |
| | | * Description : HTTP�ͻ�����ѯ���� |
| | | * Input : None |
| | | * Output : None |
| | | * Return : HIDO_OK 成功,HIDO_ERR 失败 |
| | | * Author : 杜键 |
| | | * Modified Date: : 2020年7月1日 |
| | | * Return : HIDO_OK �ɹ�,HIDO_ERR ʧ�� |
| | | * Author : �ż� |
| | | * Modified Date: : 2020��7��1�� |
| | | *******************************************************************************/ |
| | | HIDO_INT32 HTTPClient_Poll(HIDO_VOID) |
| | | { |
| | |
| | | |
| | | /******************************************************************************* |
| | | * Function Name : HTTPClient_Init |
| | | * Description : HTTP客户端初始化 |
| | | * Description : HTTP�ͻ��˳�ʼ�� |
| | | * Input : None |
| | | * Output : None |
| | | * Return : HIDO_OK 成功,HIDO_ERR 失败 |
| | | * Author : 杜键 |
| | | * Modified Date: : 2020年7月1日 |
| | | * Return : HIDO_OK �ɹ�,HIDO_ERR ʧ�� |
| | | * Author : �ż� |
| | | * Modified Date: : 2020��7��1�� |
| | | *******************************************************************************/ |
| | | HIDO_INT32 HTTPClient_Init(HIDO_VOID) |
| | | { |
| | |
| | | |
| | | return HIDO_OK; |
| | | } |
| | | |
| | | /******************************************************************************* |
| | | * Function Name : HTTPClient_GetState |
| | | * Description : 获取HTTPClient当前状态(用于调试) |
| | | * Return : 0=IDLE, 1=CONNECTING, 2=CONNECTED |
| | | *******************************************************************************/ |
| | | HIDO_INT32 HTTPClient_GetState(HIDO_VOID) |
| | | { |
| | | return (HIDO_INT32)l_eHTTPClientState; |
| | | } |
| | | |
| | | /******************************************************************************* |
| | | * Function Name : HTTPClient_Reset |
| | | * Description : 强制重置HTTPClient状态到IDLE(用于错误恢复) |
| | | *******************************************************************************/ |
| | | HIDO_VOID HTTPClient_Reset(HIDO_VOID) |
| | | { |
| | | l_eHTTPClientState = HTTP_CLIENT_STATE_IDLE; |
| | | HIDO_TimerCancel(l_u32HTTPClientTimerID); |
| | | } |