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); }
相关文章推荐
- 基于HTML5的3D网络拓扑自动布局
- TCP/IP、Http、Socket的区别
- iOS9新框架—Watch Connectivity(详情:http://ios.itcast.cn/subject/ios9/index.shtml )
- IOS 网络请求框架封装
- Linux网络编程:基于TCP的程序开发(1)
- gem install 出现Errno::ECONNRESET: Connection reset by peer - SSL_connect (https://api.rubygems.org
- HttpContext.Current.Cache 过期时间
- HttpContext.Cache和Application的区别
- (转)live555 RTSP Server RTP over TCP BUG
- HTTPRequest Response Session
- ResponseProcessCookies:121 - Cookie rejected问题
- ping检测整个网络的主机是否有响应
- 如何在Linux上使用HAProxy配置HTTP负载均衡系统?
- centos6.6克隆后的网络配置
- TCP与UDP协议
- 《UNIX网络编程》读书笔记3---IO模型与IO复用以及shutdown
- OTN&互换amp; P-OTN有效降低100G 网络成本 (两)
- httpcilent
- TCP/UDP区别、TCP/IP3次握手和4次挥手
- TCP/IP模型的简单解释