linux http post的实现 -2
修改的问题:
1、最后一个boundary应该在后面补上两个’-‘,再加\r\n,这样就会被认为是内容的结束。
2、Content-Disposition
有些对端程序如果是自己写的,可能会识别不了attachment,那么就写为form-data就可以了。
进一步参考:
http://www.iana.org/assignments/cont-disp/cont-disp.xhtml
http://tools.ietf.org/html/rfc7578
3、做了一些封装。
int http_post_file_data(tcpclient *pclient,char *page,char *filepath,char *filename,char *data,int file_len,char *httpfilekey,char **response){
char content_type[2048];
memset(content_type, 0, 2048);
char post[300],host[100],content_len[100];
char *lpbuf,*ptmp;
lpbuf = NULL;
const char *header2="User-Agent: Is Http 1.1\r\nCache-Control: no-cache\r\nAccept: */*\r\n";
sprintf(post,"POST %s HTTP/1.1\r\n",page);
sprintf(host,"HOST: %s:%d\r\n",pclient->remote_ip,pclient->remote_port);
strcpy(content_type,post);
strcat(content_type,host);
strcat(content_type,"Connection: keep-alive");
strcat(content_type, "\r\n");
strcat(content_type,"User-Agent: http client\r\n");
strcat(content_type,"Accept-Language: en-US,en;q=0.5\r\n");
strcat(content_type,"Accept-Encoding: gzip, deflate\r\n");
char *boundary = (char *)"---------------------------1920694316951020321464559648";
strcat(content_type, "Content-Type: multipart/form-data; boundary=");
strcat(content_type, boundary);
strcat(content_type, "\r\n");
//--Construct request data {filePath, file}
char content_before[4096];
memset(content_before, 0, 4096);
strcat(content_before, "--");
strcat(content_before, boundary);
strcat(content_before, "\r\n");
// strcat(content_before, "Content-Disposition: form-data; name=\"filePath\"\r\n\r\n");
// strcat(content_before, filepath==NULL?"anyfilepath":filepath);
// strcat(content_before, "\r\n");
// strcat(content_before, "--");
// strcat(content_before, boundary);
// strcat(content_before, "\r\n");
strcat(content_before, "Content-Disposition: form-data; name=\"");
strcat(content_before,httpfilekey);
strcat(content_before,"\"; filename=\"");
strcat(content_before, filename==NULL?"anyfilename":filename);
strcat(content_before, "\"\r\n");
strcat(content_before, "Content-Type: image/jpeg\r\n\r\n");
// strcat(content_before, "Content-Type: image/jpeg\r\n\r\n");
char content_end[1024];
memset(content_end, 0, 1024);
strcat(content_end, "\r\n");
strcat(content_end, "--");
strcat(content_end, boundary);
strcat(content_end, "--\r\n");
char lenstr[128];
sprintf(lenstr, "%d", (strlen(content_before)+file_len+strlen(content_end)));
strcat(content_type, "Content-Length: ");
strcat(content_type, lenstr);
strcat(content_type, "\r\n\r\n");
//send
if(!pclient->connected){
tcpclient_conn(pclient);
}
int ctype_len=strlen(content_type);
int cbef_len=strlen(content_before);
int cend_len=strlen(content_end);
int totallen=ctype_len+cbef_len+file_len+cend_len;
char *buf=malloc(totallen);
memcpy(buf,content_type,ctype_len);
memcpy(buf+ctype_len,content_before,cbef_len);
memcpy(buf+ctype_len+cbef_len,data,file_len);
memcpy(buf+ctype_len+cbef_len+file_len,content_end,cend_len);
tcpclient_send(pclient,buf,totallen);
free(buf);
/*it's time to recv from server*/
if(tcpclient_recv(pclient,&lpbuf,0) <= 0){
if(lpbuf) free(lpbuf);
return -2;
}
int len=0;
/*响应代码,|HTTP/1.0 200 OK|
*从第10个字符开始,第3位
* */
memset(post,0,sizeof(post));
strncpy(post,lpbuf+9,3);
if(atoi(post)!=200){
if(lpbuf) free(lpbuf);
return atoi(post);
}
ptmp = (char*)strstr(lpbuf,"\r\n\r\n");
if(ptmp == NULL){
free(lpbuf);
return -3;
}
ptmp += 4;/*跳过\r\n*/
len = strlen(ptmp)+1;
*response=(char*)malloc(len);
if(*response == NULL){
if(lpbuf) free(lpbuf);
return -1;
}
memset(*response,0,len);
memcpy(*response,ptmp,len-1);
/*从头域找到内容长度,如果没有找到则不处理*/
ptmp = (char*)strstr(lpbuf,"Content-Length:");
if(ptmp != NULL){
char *ptmp2;
ptmp += 15;
ptmp2 = (char*)strstr(ptmp,"\r\n");
if(ptmp2 != NULL){
memset(post,0,sizeof(post));
strncpy(post,ptmp,ptmp2-ptmp);
if(atoi(post)<len)
(*response)[atoi(post)] = '\0';
}
}
if(lpbuf) free(lpbuf);
return 0;
}
int http_post_file_path(tcpclient *pclient,char *page,char *filepath,char *httpfilekey,char **response){
//check if the file is valid or not
struct stat stat_buf;
if(lstat(filepath,&stat_buf)<0){
ERROR("lstat %s fail\n",filepath);
return -1;
}
if(!S_ISREG(stat_buf.st_mode)){
ERROR("%s is not a regular file!\n",filepath);
return -1;
}
char *filename;
filename=strrchr(filepath,'/');
if(filename==NULL){
ERROR("%s should have full path!\n",filepath);
return -2;
}
filename+=1;
if(filename>=filepath+strlen(filepath)){
//'/' is the last character
ERROR("%s is not a correct file!\n",filepath);
return -1;
}
INFO("filepath=%s,filename=%s\n",filepath,filename);
//open the file
int fd;
int file_len;
fd=open(filepath,O_RDONLY,0666);
if(!fd){
ERROR("fail to open file : %s\n",filepath);
return -2;
}
int max_cont_len=5*1024*1024;
char content[max_cont_len];
file_len=read(fd,content,max_cont_len);
close(fd);
return http_post_file_data(pclient,page,filepath,filename,content,file_len,httpfilekey,response);
}