AP05/net_utils/http_utils.c
2025-04-06 14:41:47 +08:00

1073 lines
30 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netdb.h>
#include <regex.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <pthread.h>
#include "md5.h"
#include "main.h"
#include "http_utils.h"
#include "read_utils.h"
#include "json_utils.h"
#include "Base64.h"
#define PRINT_TIME_TAG
#define DBG_TAG "http_utils"
#define DBG_LVL DBG_INFO
#include "debug_print.h"
typedef struct
{
int status_code; //HTTP/1.1 '200' OK
char content_type[128]; //Content-Type: application/gzip
long content_length; //Content-Length: 11683079
}http_response_t;
int http_parse_url(const char url[1024], char domain[1024], int *port, char file_name[256])
{
char *patterns[] = {"http://", "https://", NULL};
int j = 0, i = 0;
int start = 0;
int ret = 0;
if ((url == NULL)||(domain == NULL)||(port == NULL)||(file_name == NULL)) {
LOG_I("param: NULL\n");
ret = -1;
goto error;
}
for (i = 0; patterns[i]; i++) {
if (strncmp(url, patterns[i], strlen(patterns[i])) == 0) {
start = strlen(patterns[i]);
}
}
//解析域名, 这里处理时域名后面的端口号会保留
for (i = start, j = 0; url[i] != '/' && url[i] != '\0'; i++, j++) {
domain[j] = url[i];
if((i >= (1024 - 1)) || (j >= (1024 - 1))) {
ret = -2;
goto error;
}
}
domain[j] = '\0';
//解析端口号, 如果没有, 那么设置端口为80
char *pos = strstr(domain, ":");
if (pos) {
sscanf(pos, ":%d", port);
} else {
*port = 80;
}
//删除域名端口号
for (i = 0; i < strlen(domain); i++) {
if (domain[i] == ':') {
domain[i] = '\0';
break;
}
}
//获取下载文件名
for (i = start, j = 0; url[i] != '\0'; i++) {
if (url[i] == '/') {
if (i != strlen(url) - 1) {
j = 0;
}
continue;
} else {
file_name[j++] = url[i];
if(j >= (256 - 1)) {
ret = -3;
goto error;
}
}
}
file_name[j] = '\0';
error:
return ret;
}
int is_ip_legal(const char *ip)
{
char str_ip[30] = "";
regex_t reg;
const char *pattern = "[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}";
int cflags = REG_EXTENDED;
const size_t nmatch = 1;
regmatch_t pmatch[1];
int ret = 0;
if (ip == NULL) {
LOG_I("param: NULL\n");
ret = -1;
goto error;
}
strcpy(str_ip, ip);
regcomp(&reg, pattern, cflags);
ret = regexec(&reg, str_ip, nmatch, pmatch, 0);
if(ret == REG_NOMATCH)
{
LOG_I("IP not match\n");
ret = -2;
goto error;
} else if(ret == REG_NOERROR) {
ret = 0;
}
regfree(&reg);
error:
return ret;
}
int get_ip_by_domain(char *domain, char dest[16], int dest_len)
{
struct hostent *host;
int ret = 0;
if ((domain == NULL)||(dest == NULL)) {
LOG_I("param: NULL\n");
ret = -1;
goto error;
}
host = gethostbyname(domain);
if (host == NULL) {
LOG_I("gethostbyname error\n");
ret = -2;
goto error;
} else {
if (dest_len >= 16 && dest != NULL) {
char **phe = NULL;
for ( phe=host->h_addr_list ; NULL != *phe ; ++phe) {
inet_ntop(host->h_addrtype, *phe, dest, dest_len);
}
}
}
error:
return ret;
}
int socket_client_connect(int socketfd, char ip[INET_ADDRSTRLEN], int port)
{
struct sockaddr_in addr;
int flag = 1;
fd_set fds;
struct timeval tv;
int ret = 0;
int len = sizeof(ret);
if (ip == NULL) {
LOG_I("param: NULL\n");
ret = -1;
goto error;
}
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
inet_pton(AF_INET, ip, &addr.sin_addr);
//当socket进行TCP连接的时候也就是调用connect时一旦网络不通或者是ip地址无效就可能使整个线程阻塞
//设置为非阻塞模式
ioctl(socketfd, FIONBIO, &flag);
ret = connect(socketfd, (struct sockaddr*)&addr, sizeof(addr));
if (ret < 0) {
tv.tv_sec = 1;
tv.tv_usec = 500*1000;
FD_ZERO(&fds);
FD_SET(socketfd, &fds);
ret = select(FD_SETSIZE, NULL, &fds, NULL, &tv);
if(ret < 0){
LOG_I("seclect error\n");
ret = -2;
goto error;
}else if(ret > 0){
if(FD_ISSET(socketfd, &fds)){
getsockopt(socketfd, SOL_SOCKET, SO_ERROR, &ret, (socklen_t *)&len);
if(ret != 0){
ret = -3;
goto error;
}
}
}else{//time out
ret = -4;
goto error;
}
}
flag = 0;
ioctl(socketfd, FIONBIO, &flag); //设置为阻塞模式
ret = socketfd;
error:
return ret;
}
int socket_client_open(void)
{
int socketfd;
socketfd = socket(AF_INET, SOCK_STREAM, 0);
if(socketfd < 0){
LOG_I("socket error\n");
}
return socketfd;
}
int socket_client_open_connect(char ip[INET_ADDRSTRLEN], int port)
{
int socketfd;
int ret = 0;
socketfd = socket_client_open();
ret = socket_client_connect(socketfd, ip, port);
if(ret < 0){
LOG_I("socket_client_connect error: %d\n", ret);
close(socketfd);
socketfd = -1;
}
return socketfd;
}
int get_http_response(const char *response, http_response_t *resp)
{
int ret = 0;
if ((response == NULL)||(resp == NULL)) {
LOG_I("param: NULL\n");
ret = -1;
goto error;
}
//LOG_I("response:%s\n",response);
char *pos = strstr(response, "HTTP/");
if (pos) {
sscanf(pos, "%*s %d", &resp->status_code); //返回状态码
} else {
ret = -2;
goto error;
}
pos = strstr(response, "Content-Type:"); //返回内容类型
if (pos) {
sscanf(pos, "%*s %s", resp->content_type);
} else {
ret = -3;
goto error;
}
pos = strstr(response, "Content-Length:"); //内容的长度(字节)
if (pos) {
sscanf(pos, "%*s %ld", &resp->content_length);
} else {
ret = -4;
goto error;
}
error:
return ret;
}
int http_response_debug(http_response_t *resp)
{
int ret = 0;
if (resp == NULL) {
LOG_I("param: NULL\n");
ret = -1;
goto error;
}
LOG_I("status_code = %d\n", resp->status_code);
LOG_I("content_type = %s\n", resp->content_type);
LOG_I("content_length = %ld\n", resp->content_length);
error:
return ret;
}
void progress_bar(long cur_size, long total_size)
{
/*用于显示下载进度条*/
float percent = cur_size*1.0 / total_size;
const int numTotal = 50;
int numShow = (int)(numTotal * percent);
if (numShow == 0)
numShow = 1;
if (numShow > numTotal)
numShow = numTotal;
char sign[51] = {0};
memset(sign, '=', numTotal);
LOG_I("\r%.2f%%\t[%-*.*s] %ld/%ld", percent * 100, numTotal, numShow, sign, cur_size, total_size);
fflush(stdout);
if (numShow == numTotal)
LOG_I("\n");
}
#if 0
int http_download(int client_socket, char path[256], char file_name[256], http_response_t *http_response)
{
int length = 0;
int written_len = 0;
char receive[2048] = "";
char path_name[512] = {0};
int ret = 0;
if ((path == NULL)||(file_name == NULL)) {
LOG_I("param: NULL\n");
ret = -3;
goto error;
}
//创建文件描述符
snprintf(path_name, sizeof(path_name), "%s/%s", path, file_name);
int fd = open(path_name, O_CREAT | O_WRONLY | O_TRUNC, S_IRWXG | S_IRWXO | S_IRWXU);
if (fd < 0) {
LOG_I("Create file failed\n");
ret = -1;
goto error;
}
//从套接字中读取文件流
while(1) {
length = read_data_until_time(client_socket, receive, sizeof(receive), 3000, 50);
if(length < 0){
LOG_I("read_data_until_str error\n");
ret = -2;
goto error;
}else if(length == 0){
LOG_I("read_data_until_str end\n");
break;
}
write(fd, receive, length);
written_len += length;
progress_bar(written_len, http_response->content_length);
if(written_len >= http_response->content_length) {
break;
}
}
if (written_len == http_response->content_length) {
LOG_I("Download %s successed\n", file_name);
ret = 0;
} else {
LOG_I("Download %s failed\n", file_name);
ret = -3;
}
close(fd);
error:
return ret;
}
int http_get(const char url[1024], const char path[256], char file_dest[512], int file_dest_len)
{
char domain[1024] = {0};
char server_ip[20] = {0};
int server_port = 80;
char file_name[256] = {0};
char request[2048] = {0};
char response[2048] = {0};
int length = 0;
int ret = 0;
int client_socket;
#if 0
if ((url == NULL)||(path == NULL)) {
LOG_I("param: NULL\n");
ret = -7;
goto error;
}
#endif
http_parse_url(url, domain, &server_port, file_name);
LOG_I("url:%s\n", url);
LOG_I("domain:%s\n", domain);
get_ip_by_domain(domain, server_ip, sizeof(server_ip));
if(is_ip_legal(server_ip)) {
ret = -1;
goto error;
}
LOG_I("server_ip:%s, port:%d\n", server_ip, server_port);
LOG_I("file_name:%s\n", file_name);
//设置http请求头信息
length = snprintf(request, sizeof(request),
"GET %s HTTP/1.1\r\n"
"User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537(KHTML, like Gecko) Chrome/47.0.2526Safari/537.36\r\n"
"Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n"
"Host:%s\r\n"
"Connection:close\r\n"
"\r\n",
url, domain);
client_socket = socket_client_open_connect(server_ip, server_port);
if(client_socket < 0){
close(client_socket);
ret = -2;
goto error;
}
//发送请求消息
write(client_socket, request, strlen(request));
length = read_data_until_str(client_socket, response, sizeof(response), "\r\n\r\n", strlen("\r\n\r\n"), 3000, 50);
if(length < 0){
LOG_I("read_data_until_str error\n");
ret = -3;
goto error;
}else if(length == 0){
LOG_I("read_data_until_str end\n");
ret = -4;
goto error;
}
//print_buffer("\n>>>>response<<<<\n", response, length);
//print_buffer_char("\n>>>>response<<<<\n", response, length);
http_response_t http_response;
get_http_response(response, &http_response);
http_response_debug(&http_response);
#if 0
if(http_response.status_code == 200) {
if (file_dest != NULL) {
memset(file_dest, 0, file_dest_len);
LOG_I("path:[%s]\n", path);
LOG_I("file_name:[%s]\n", file_name);
snprintf(file_dest, file_dest_len, "%s/%s", path, file_name);
}
ret = http_down(client_socket, (char *)path, file_name, &http_response);
if(ret < 0){
LOG_I("http_down error\n");
ret = -5;
goto error;
}
} else {
ret = -6;
goto error;
}
#endif
error:
return ret;
}
#endif
#define UPLOAD_REQUEST "--myfengefu\r\n"\
"Content-Disposition: form-data; name=\"file\"; filename=%s\r\n"\
"Content-Type: application/octet-stream\r\n\r\n"
#define HTTP_HEAD "POST %s HTTP/1.1\r\n"\
"Host: %s\r\n"\
"key: device\r\n"\
"nonce: %s\r\n"\
"timestamp: %s\r\n"\
"sign: %s\r\n"\
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)\r\n"\
"Content-Type: multipart/form-data; boundary=myfengefu\r\n"\
"Content-Length: %ld\r\n"\
"Connection: keep-alive\r\n\r\n"
#define HTTP_HEAD_GETDEVINFO "POST %s HTTP/1.1\r\n"\
"Host: %s\r\n"\
"key: device\r\n"\
"nonce: %s\r\n"\
"timestamp: %s\r\n"\
"sign: %s\r\n"\
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)\r\n"\
"Content-Type: application/json\r\n"\
"Content-Length: %ld\r\n"\
"Connection: keep-alive\r\n\r\n"
#define HTTP_HEAD_GETDEVINFO_J "POST %s HTTP/1.1\r\n"\
"Host: %s\r\n"\
"x-appKey: d577e7b5024ad20446e10\r\n"\
"x-datadigest: %s\r\n"\
"Content-Type: application/json\r\n"\
"Content-Length: %ld\r\n"\
"Connection: keep-alive\r\n\r\n"
#define HTTP_HEAD_GETDEVINFO_T "POST %s HTTP/1.1\r\n"\
"Host: %s\r\n\r\n"
#define HTTP_HEAD_GETDEVREGISTERSTATUS "GET %s HTTP/1.1\r\n"\
"Host: %s\r\n"\
"key: device\r\n"\
"nonce: %s\r\n"\
"timestamp: %s\r\n"\
"sign: %s\r\n"\
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)\r\n"\
"Content-Type: application/json\r\n"\
"Content-Length: %ld\r\n"\
"Connection: keep-alive\r\n\r\n"
unsigned long get_file_size(const char *path)
{
unsigned long filesize = -1;
struct stat statbuff;
if(stat(path, &statbuff) < 0){
return filesize;
}else{
filesize = statbuff.st_size;
}
return filesize;
}
void get_rand_str(char s[],int num)
{
//定义随机生成字符串表
char *str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
int i,lstr;
char ss[2] = {0};
lstr = strlen(str);//计算字符串长度
srand((unsigned int)time((time_t *)NULL));//使用系统时间来初始化随机数发生器
for(i = 1; i <= num; i++){//按指定大小返回相应的字符串
sprintf(ss,"%c",str[(rand()%lstr)]);//rand()%lstr 可随机返回0-71之间的整数, str[0-71]可随机得到其中的字符
strcat(s,ss);//将随机生成的字符串连接到指定数组后面
}
}
int http_post_uploadlog(char *url, char *msg_id,char *logfilename)
{
char domain[1024] = {0};
char server_ip[20] = {0};
int server_port = 80;
char file_name[256] = {0};
char response[2048] = {0};
char fileurl[2048] = {0};
int sendsuccess = 0;
int length = 0;
int ret = 0;
int client_socket;
int readbyte=0;
unsigned char header[1024]={0};
unsigned char send_request[1024]={0};
unsigned char send_end[1024]={0};
unsigned char http_boundary[64]={0};
unsigned char nonce[32]={0};
unsigned char timestamp[64]={0};
unsigned char sign[256]={0};
unsigned char signtmp[256]={0};
get_rand_str(nonce,6);
//LOG_I("nonce:%s\n",nonce);
struct timeval begin;
gettimeofday(&begin,NULL);
long long beginTime = (long long)begin.tv_sec * 1000 + (long long)begin.tv_usec / 1000;
sprintf(timestamp,"%lld",beginTime);
//LOG_I("timestamp:%s\n",timestamp);
snprintf(signtmp, sizeof(sign), "device|%s|%s|wdewdilpvy",nonce,timestamp);
//LOG_I("signtmp:%s\n",signtmp);
get_md5_from_string(sign, sizeof(sign), signtmp, strlen(signtmp));
//LOG_I("sign:%s\n",sign);
#if 0
if ((url == NULL)||(path == NULL)) {
LOG_I("param: NULL\n");
ret = -7;
goto error;
}
#endif
//LOG_I("POST\n");
http_parse_url(url, domain, &server_port, file_name);
//LOG_I("url:%s\n", url);
//LOG_I("domain:%s\n", domain);
get_ip_by_domain(domain, server_ip, sizeof(server_ip));
if(is_ip_legal(server_ip)) {
ret = -1;
goto error;
}
//LOG_I("server_ip:%s, port:%d\n", server_ip, server_port);
//LOG_I("file_name:%s\n", file_name);
unsigned long totalsize = 0;
unsigned long filesize = get_file_size(logfilename); //文件大小
unsigned long request_len = snprintf(send_request,1024,UPLOAD_REQUEST,logfilename); //请求信息
unsigned long end_len = snprintf(send_end,1024,"\r\n--myfengefu--\r\n"); //结束信息
totalsize = filesize + request_len + end_len;
//unsigned long head_len = snprintf(header,1024,HTTP_HEAD,"/open/api/device/log/upload",domain,nonce,timestamp,sign,totalsize); //头信息
unsigned long head_len = snprintf(header,1024,HTTP_HEAD,url,domain,nonce,timestamp,sign,totalsize); //头信息
totalsize += head_len;
//LOG_I("filesize:%d,request_len:%d,end_len:%d,head_len:%d,totalsize:%d\n",filesize,request_len,end_len,head_len,totalsize);
char* request = (char*)malloc(totalsize); //申请内存用于存放要发送的数据
if (request == NULL){
printf("malloc request fail !\r\n");
return -1;
}
request[0] = '\0';
strcat(request,header); //http头信息
strcat(request,send_request); //文件请求信息
FILE* fp = fopen(logfilename, "rb+");//打开要上传的文件
if (fp == NULL){
LOG_I("open file fail!\r\n");
return -1;
}
readbyte = fread(request+head_len+request_len, 1, filesize, fp);//读取上传的文件信息
LOG_I("logfile %s size:%d\n",logfilename,readbyte);
memcpy(request+head_len+request_len+filesize,send_end,end_len); //http结束信息
//LOG_I("request:%s\n",request);
client_socket = socket_client_open_connect(server_ip, server_port);
if(client_socket < 0){
close(client_socket);
ret = -2;
goto error;
}
if(write(client_socket, request, totalsize)==-1){
LOG_I("write fail\r\n");
}
if((readbyte = read(client_socket,response,2048))==-1){
LOG_I("read http ACK fail !\r\n");
return -1;
}
//LOG_I("ACK readbyte:%d\n",readbyte);
response[readbyte]='\0';
//LOG_I("response:%s\n",response);
int index = 0,start_flag = 0;
int ack_json_len = 0;
char ack_json[256]={0};
for(index = 0; index<readbyte; index++){
if(response[index] == '{'){
start_flag = 1;
}
if(start_flag)
ack_json[ack_json_len++] = response[index]; //遇到左大括号则开始拷贝
}
//LOG_I("Receive:%s\n",ack_json);
if(ack_json_len > 0){
get_string_from_json_string_by_key_unescape(ack_json, "data", fileurl, sizeof(fileurl));
//LOG_I("data:%s\n",fileurl);
get_int_from_json_string_by_key(ack_json, "code", &sendsuccess);
//LOG_I("code:%d\n",sendsuccess);
}else{
ack_json[0] = '\0';
LOG_I("Receive http ACK fail!!\n");
//LOG_I("--- ack_json_len = %d\n",ack_json_len);
}
error:
return ret;
}
int http_get_getdevregisterstatus(char *url)
{
char domain[1024] = {0};
char server_ip[20] = {0};
int server_port = 80;
char file_name[256] = {0};
char response[3072] = {0};
int sendsuccess = 0;
int length = 0;
int ret = 0;
int client_socket;
int readbyte=0;
unsigned char header[1024]={0};
unsigned char send_request[1024]={0};
unsigned char send_end[1024]={0};
unsigned char http_boundary[64]={0};
unsigned char nonce[32]={0};
unsigned char timestamp[64]={0};
unsigned char sign[256]={0};
unsigned char signtmp[256]={0};
get_rand_str(nonce,6);
//LOG_I("nonce:%s\n",nonce);
struct timeval begin;
gettimeofday(&begin,NULL);
long long beginTime = (long long)begin.tv_sec * 1000 + (long long)begin.tv_usec / 1000;
sprintf(timestamp,"%lld",beginTime);
//LOG_I("timestamp:%s\n",timestamp);
snprintf(signtmp, sizeof(sign), "device|%s|%s|wdewdilpvy",nonce,timestamp);
//LOG_I("signtmp:%s\n",signtmp);
get_md5_from_string(sign, sizeof(sign), signtmp, strlen(signtmp));
http_parse_url(url, domain, &server_port, file_name);
//LOG_I("url:%s\n", url);
//LOG_I("domain:%s\n", domain);
get_ip_by_domain(domain, server_ip, sizeof(server_ip));
if(is_ip_legal(server_ip)) {
ret = -1;
goto error;
}
//LOG_I("server_ip:%s, port:%d\n", server_ip, server_port);
//LOG_I("json code:%s\n",devcode);
unsigned long totalsize = 0;
unsigned long head_len = snprintf(header,1024,HTTP_HEAD_GETDEVREGISTERSTATUS,url,domain,nonce,timestamp,sign,totalsize); //头信息
totalsize+=head_len;
char* request = (char*)malloc(totalsize); //申请内存用于存放要发送的数据
if (request == NULL){
printf("malloc request fail !\r\n");
ret= -1;
goto error;
}
request[0] = '\0';
memcpy(request,header,head_len); //http结束信息
//LOG_I("request:%s\n",request);
client_socket = socket_client_open_connect(server_ip, server_port);
if(client_socket < 0){
close(client_socket);
ret = -2;
goto error;
}
if(write(client_socket, request, strlen(request))==-1){
LOG_I("write fail\r\n");
}
if((readbyte = read(client_socket,response,4096))==-1){
LOG_I("read http ACK fail !\r\n");
ret= -1;
goto error;
}
//LOG_I("ACK readbyte:%d\n",readbyte);
response[readbyte]='\0';
//LOG_I("response:%s\n",response);
#if 1
int index = 0,start_flag = 0;
int count=0;
int ack_json_len = 0;
int ack_json_tmplen = 0;
char ack_tmpjson[3072]={0};
char ack_json[3072]={0};
for(index = 0; index<readbyte; index++){
if(response[index] == '{'){
start_flag = 1;
}
if(start_flag)
ack_tmpjson[ack_json_tmplen++] = response[index]; //遇到左大括号则开始拷贝
}
//LOG_I("ack_json_tmplen:%d,ack_tmpjson:%s\n",ack_json_tmplen,ack_tmpjson);
start_flag=0;
for(index = 0; index<ack_json_tmplen; index++){
if(ack_tmpjson[index] == '{'){
count++;
if(ack_json_len>2){
break;
}
if(count>=2){
start_flag = 1;
}
}
if(start_flag)
ack_json[ack_json_len++] = ack_tmpjson[index]; //遇到左大括号则开始拷贝
}
ack_json[ack_json_len]='"';
ack_json[ack_json_len+1]='}';
//LOG_I("Receive len:%d\n",ack_json_len);
//LOG_I("Receive :%s\n",ack_json);
//LOG_I("Receive :%s\n",ack_json+1650);
if(ack_json_len > 0){
//LOG_I("deviceSecret:%s\n",deviceSecrets);
}else{
ack_json[0] = '\0';
LOG_I("Receive http ACK fail!!\n");
//LOG_I("--- ack_json_len = %d\n",ack_json_len);
ret=-1;
goto error;
}
#endif
error:
return ret;
}
int http_post_getdevinfo(char *url, char *devcodetmp,char *devcode)
{
char domain[1024] = {0};
char server_ip[20] = {0};
int server_port = 80;
char file_name[256] = {0};
char response[2048] = {0};
char tmpdata[2048] = {0};
char jsondata[2048] = {0};
int sendsuccess = 0;
int length = 0;
int ret = 0;
int client_socket;
int readbyte=0;
unsigned char header[1024]={0};
unsigned char send_request[1024]={0};
unsigned char send_end[1024]={0};
unsigned char http_boundary[64]={0};
unsigned char nonce[32]={0};
unsigned char timestamp[64]={0};
char signbase64[256]={0};
char signtmp[256]={0};
get_rand_str(nonce,6);
//LOG_I("nonce:%s\n",nonce);
struct timeval begin;
gettimeofday(&begin,NULL);
long long beginTime = (long long)begin.tv_sec * 1000 + (long long)begin.tv_usec / 1000;
sprintf(timestamp,"%lld",beginTime);
//LOG_I("timestamp:%s\n",timestamp);
strcpy(signtmp,devcodetmp);
strcat(signtmp,"0e8e9457d493666ee2f5adb783e69abb");
//strcpy(signtmp,"0e8e9457d493666ee2f5adb783e69abb");
LOG_I("signtmp:%s\n",signtmp);
get_base64_md5_from_string(signbase64, sizeof(signbase64), signtmp, strlen(signtmp));
LOG_I("signbase64:%s\n",signbase64);
sprintf(send_request,"curl -X POST -H 'x-appKey:d577e7b5024ad20446e10' -H 'x-datadigest:%s' -H 'Content-Type: application/json' -d '%s' %s",signbase64,devcodetmp,url);
LOG_I("send_request:%s\n",send_request);
//system(send_request);
FILE *fp;
char buffer[128];
fp=popen(send_request,"r");
fgets(buffer,sizeof(buffer),fp);
get_string_from_json_string_by_key_unescape(buffer, "message", tmpdata, sizeof(tmpdata));
LOG_I("hyx %s\n",tmpdata);
#if 0
http_parse_url(url, domain, &server_port, file_name);
LOG_I("url:%s\n", url);
LOG_I("domain:%s\n", domain);
get_ip_by_domain(domain, server_ip, sizeof(server_ip));
if(is_ip_legal(server_ip)) {
playAudio(SND_DEVSNGETFAIL);
ret = -1;
goto error;
}
LOG_I("server_ip:%s, port:%d\n", server_ip, server_port);
LOG_I("json code:%s\n",devcode);
unsigned long totalsize = 0;
unsigned long jsonsize = strlen(devcode);
totalsize = jsonsize;
LOG_I("totalsize1:%d\n",totalsize);
unsigned long head_len = snprintf(header,1024,HTTP_HEAD_GETDEVINFO_J,"/device/modifyRegisterInfo",domain,signbase64); //头信息
totalsize += head_len;
LOG_I("totalsize2:%d\n",totalsize);
char* request = (char*)malloc(totalsize); //申请内存用于存放要发送的数据
if (request == NULL){
printf("malloc request fail !\r\n");
ret= -1;
goto error;
}
request[0] = '\0';
memcpy(request,header,head_len); //http结束信息
memcpy(request+head_len,devcode,jsonsize); //http结束信息
LOG_I("request:%s\n",request);
client_socket = socket_client_open_connect(server_ip, server_port);
if(client_socket < 0){
LOG_I("socket error\r\n");
close(client_socket);
//playAudio(SND_DEVSNGETFAIL);
ret = -2;
goto error;
}
if(write(client_socket, request, strlen(request))==-1){
LOG_I("write fail\r\n");
}
if((readbyte = read(client_socket,response,2048))==-1){
LOG_I("read http ACK fail !\r\n");
//playAudio(SND_DEVSNGETFAIL);
ret= -1;
goto error;
}
LOG_I("ACK readbyte:%d\n",readbyte);
response[readbyte]='\0';
LOG_I("response:%s\n",response);
#if 1
int index = 0,start_flag = 0;
int ack_json_len = 0;
char ack_json[512]={0};
for(index = 0; index<readbyte; index++){
if(response[index] == '{'){
start_flag = 1;
}
if(start_flag)
ack_json[ack_json_len++] = response[index]; //遇到左大括号则开始拷贝
//if(response[index] == '}'){
// ack_json[ack_json_len] = '\0';
// break;
//}
}
//LOG_I("Receive:%s\n",ack_json);
if(ack_json_len > 0){
get_string_from_json_string_by_key_unescape(ack_json, "data", tmpdata, sizeof(tmpdata));
snprintf(jsondata, sizeof(jsondata), "{%s}", tmpdata);
//LOG_I("jsondata:%s\n",jsondata);
memset(devOwnSn,0,64);
get_string_from_json_string_by_key_unescape(jsondata, "devOwnSn", devOwnSn, sizeof(devOwnSn));
LOG_I("devOwnSn:%s\n",devOwnSn);
if(strcmp(devOwnSn,"")!=0){
memset(devOwnSn_save,0,64);
strcpy(devOwnSn_save,devOwnSn);
LOG_I("devOwnSn_save:%s\n",devOwnSn_save);
if(!hgz_judge_sn_exist_devin(devOwnSn_save)){
if(optBatchIn){
openDoorWaited=false;
playAudio(SND_SCANSUCCESS);
}else{
int len=0;
char *result=NULL;
result=file_to_buffer(devOwnSn,&len);
if(result==NULL){
//LOG_I("devOwnSn file not exist\n");
char openCell[4]={0};
if(hgz_judge_sn_exist_devout(devOwnSn_save,openCell)){
playAudio(SND_SCANSUCCESS);
returnDevs_multy(openCell);
}else{
LOG_I("dev not in\n");
//playAudio(SND_DEVNOTBORROWED);
}
}else{
//LOG_I("devOwnSn file exist:%s\n",result);
playAudio(SND_SCANSUCCESS);
repairReturnDevs_multy(result);
}
}
}else{
playAudio(SND_DEVSNALREADYEXIST);
}
}else{
playAudio(SND_DEVSNGETFAIL);
}
//get_string_from_json_string_by_key_unescape(jsondata, "devPro", devPRO, sizeof(devPRO));
//LOG_I("devPro:%s\n",devPRO);
//get_string_from_json_string_by_key_unescape(jsondata, "devMfg", devMFG, sizeof(devMFG));
//LOG_I("devMfg:%s\n",devMFG);
}else{
ack_json[0] = '\0';
LOG_I("Receive http ACK fail!!\n");
//LOG_I("--- ack_json_len = %d\n",ack_json_len);
//playAudio(SND_DEVSNGETFAIL);
ret=-1;
goto error;
}
#endif
#endif
error:
return ret;
}
int http_download(char *url, char *msg_id,int task_id,char *filepath)
{
int length = 0;
int written_len = 0;
char receive[2048] = "";
char path_name[512] = {0};
int ret = 0;
char domain[1024] = {0};
char server_ip[20] = {0};
int server_port = 80;
int client_socket;
char request[2048] = {0};
char response[2048] = {0};
char file_name[256] = {0};
//创建文件描述符
int fd = open(filepath, O_CREAT | O_WRONLY | O_TRUNC, S_IRWXG | S_IRWXO | S_IRWXU);
if (fd < 0) {
LOG_I("Create file failed\n");
ret = -1;
goto error;
}
sscanf(url, "%*[^//]//%[^/]%s", domain, file_name);
LOG_I("msgid:%s\n", msg_id);
LOG_I("taskid:%d\n", task_id);
LOG_I("filepath:%s\n", filepath);
LOG_I("url:%s\n", url);
LOG_I("domain:%s\n", domain);
LOG_I("file_name:%s\n", file_name);
get_ip_by_domain(domain, server_ip, sizeof(server_ip));
LOG_I("server_ip:%s\n",server_ip);
if(is_ip_legal(server_ip)) {
ret = -1;
goto error;
}
//设置http请求头信息
length = snprintf(request, sizeof(request),
"GET %s HTTP/1.1\r\n"
"HOST: %s\r\n"
"Cache-Control: no-cache\r\n"
"Connection: close\r\n\r\n",
file_name, domain);
client_socket = socket_client_open_connect(server_ip, server_port);
if(client_socket < 0){
close(client_socket);
ret = -2;
goto error;
}
//发送请求消息
write(client_socket, request, strlen(request));
length = read_data_until_str(client_socket, response, sizeof(response), "\r\n\r\n", strlen("\r\n\r\n"), 3000, 50);
if(length < 0){
LOG_I("read_data_until_str error\n");
ret = -3;
goto error;
}else if(length == 0){
LOG_I("read_data_until_str end\n");
ret = -4;
goto error;
}
http_response_t http_response;
get_http_response(response, &http_response);
http_response_debug(&http_response);
if(http_response.status_code == 200){
while(1) {
length = read_data_until_time(client_socket, receive, sizeof(receive), 3000, 50);
if(length < 0){
LOG_I("read_data_until_str error\n");
ret = -2;
goto error;
}else if(length == 0){
LOG_I("read_data_until_str end\n");
break;
}
write(fd, receive, length);
written_len += length;
//progress_bar(written_len, http_response.content_length);
if(written_len >= http_response.content_length) {
break;
}
}
if (written_len == http_response.content_length) {
LOG_I("Download %s successed\n", file_name);
sleep(2);
newappDownloaded=true;
ret = 0;
} else {
LOG_I("Download %s failed\n", file_name);
ret = -3;
}
}else{
LOG_I("code not 200\n");
}
close(fd);
error:
return ret;
}