linux http post的实现 -2

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

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值