您的位置:首页 > 理论基础 > 计算机网络

linux http post的实现 -2

2015-10-16 12:01 211 查看

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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: