您当前的位置: 首页 >  ar

libcurl-上传文件API-http工作原理-curl_mime_init-curl_mime_addpart-curl_mime_name-curl_mime_data

发布时间:2022-06-18 08:00:00 ,浏览量:6

文章目录
    • 1.上传文件工作原理
      • 1.1.Content-Type 请求头报头域
      • 1.2.application/x-www-form-urlencoded
      • 1.3.multipart/form-data
      • 1.4.application/json
      • 1.5.上传文件报文范例
    • 2.curl_mime_init - 创建一个 mime 句柄
      • 2.1.原理解析
      • 2.2.简单范例
    • 3.curl_mime_addpart - 将新的空白部分附加到 mime 结构
      • 3.1.原理解析
      • 3.2.简单范例
    • 4.curl_mime_name - 设置 mime 部分的名称
    • 5.curl_mime_data - 从内存中设置 mime 部分的主体数据
    • 6.curl_mime_filename - 设置 mime 部分的远程文件名
      • 6.1.原理解析
      • 6.2.简单范例
    • 7.curl_mime_filedata - 从文件内容中设置 mime 部分的主体数据
      • 7.1.原理解析
      • 7.2.简单范例
    • 8.curl_mime_type - 设置 mime 部分的内容类型
      • 8.1.原理解析
      • 8.2.简单范例
    • 9.curl_mime_filedata - 从文件内容中设置 mime 部分的主体数据
    • 10.作者答疑
1.上传文件工作原理

http协议是应用层规范。http请求分为3个部分:状态行,请求头,请求体。所有的方法、实现,都是围绕 “如何运用和组织这三部分” 来完成的。http里没有专门用于文件上传的请求方式,文件上传请求是在post请求基础之上定义出来的一种方式。http协议规定 POST 请求提交的数据,必须放在请求体(entity-body)中,但协议并没有规定编码方式 。开发者可以自己决定编码格式,只要最后发送的 HTTP 请求,满足上面的格式就可以。

1.1.Content-Type 请求头报头域

Content-Type(MediaType),即是Internet Media Type,互联网媒体类型,也叫做MIME类型。在互联网中有成百上千中不同的数据类型,HTTP在传输数据对象时会为他们打上称为MIME的数据格式标签,用于区分数据类型。最初MIME是用于电子邮件系统的,后来HTTP也采用了这一方案。在HTTP协议消息头中,使用Content-Type来表示请求和响应中的媒体类型信息。它用来告诉服务端如何处理请求的数据,以及告诉客户端(一般是浏览器)如何解析响应的数据,比如显示图片,解析并展示html等等。

Content-Type的格式:Content-Type:type/subtype ;parameter type:主类型,任意的字符串,如text,如果是号代表所有; subtype:子类型,任意的字符串,如html,如果是号代表所有,用“/”与主类型隔开; parameter:可选参数,如charset,boundary等。 例如: Content-Type: text/html; Content-Type: application/json;charset:utf-8;

1.2.application/x-www-form-urlencoded

HTTP会将请求参数用key1=val1&key2=val2的方式进行组织,并放到请求实体里面,注意如果是中文或特殊字符如"/“、”,“、“:” 等会自动进行URL转码。不支持文件,一般用于表单提交。

1.3.multipart/form-data

与application/x-www-form-urlencoded不同,这是一个多部分多媒体类型。首先生成了一个 boundary 用于分割不同的字段,在请求实体里每个参数以------boundary开始,然后是附加信息和参数名,然后是空行,最后是参数内容。多个参数将会有多个boundary块。如果参数是文件会有特别的文件域。最后以------boundary–为结束标识。multipart/form-data支持文件上传的格式,一般需要上传文件的表单则用该类型。 下面是一个例子: 在这里插入图片描述

1.4.application/json

JSON 是一种轻量级的数据格式,以“键-值”对的方式组织的数据。这个使用这个类型,需要参数本身就是json格式的数据,参数会被直接放到请求实体里,不进行任何处理。服务端/客户端会按json格式解析数据(约定好的情况下)。 在这里插入图片描述

1.5.上传文件报文范例
POST /xxx HTTP/1.1
Host: hello.app
Connection: keep-alive
Content-Length: 3695 Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Origin: http://hello.app
Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36
Content-Type: multipart/form-data;boundary=----WebKitFormBoundaryIZDrYHwuf2VJdpHw
Referer: http://hello.app/formtest.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6 ------WebKitFormBoundaryIZDrYHwuf2VJdpHw
Content-Disposition: form-data; name="name" "hello world" ------WebKitFormBoundaryIZDrYHwuf2VJdpHw
Content-Disposition: form-data; name="file"; filename="temp.png" Content-Type: image/png

.PNG . ...
IHDR... ..........Y../..,+|.$aIk.v...G?...P.P,,...m..e.2....v.7.    pHYs...%...%.IR$....|IDAT(.cTT....................:.?.......}.(.Pd`A..V...L...?..#.....4.o..LS.....W.d.?...A8..LS...(.u.......D.b......b.....o&..;..<.1......IEND.B`. ------WebKitFormBoundaryIZDrYHwuf2VJdpHw
Content-Disposition: form-data; name="submit" submit
------WebKitFormBoundaryIZDrYHwuf2VJdpHw--
2.curl_mime_init - 创建一个 mime 句柄 2.1.原理解析
#include   curl_mime *curl_mime_init(CURL *easy_handle); 

curl_mime_init创建一个新的空 mime 结构的句柄,该结构旨在与easy_handle一起使用。随后可以使用 mime API 填充此 mime 结构,然后使用curl_easy_setopt调用 中的选项CURLOPT_MIMEPOST附加到easy_handle 。 使用 mime 句柄是发布 HTTP 表单、格式化并使用 SMTP 发送多部分电子邮件或将此类电子邮件上传到 IMAP 服务器的推荐方法。

2.2.简单范例
CURL *easy = curl_easy_init(); curl_mime *mime; curl_mimepart *part; /* Build an HTTP form with a single field named "data", */ mime = curl_mime_init(easy); part = curl_mime_addpart(mime); curl_mime_data(part, "This is the field data", CURL_ZERO_TERMINATED); curl_mime_name(part, "data"); /* Post and send it. */ curl_easy_setopt(easy, CURLOPT_MIMEPOST, mime); curl_easy_setopt(easy, CURLOPT_URL, "https://example.com"); curl_easy_perform(easy); /* Clean-up. */ curl_easy_cleanup(easy); curl_mime_free(mime); 

返回值:一个 mime 结构句柄,或失败时为 NULL。

3.curl_mime_addpart - 将新的空白部分附加到 mime 结构 3.1.原理解析
#include  curl_mimepart *curl_mime_addpart(curl_mime *mime); 

curl_mime_addpart创建一个新的空白部分并将其附加到给定的 mime 结构并返回一个句柄。随后可以使用 mime API 中的函数填充返回的部件句柄。mime是必须附加新部分的 mime 结构的句柄。

3.2.简单范例
curl_mime *mime; curl_mimepart *part; /* create a mime handle */ mime = curl_mime_init(easy); /* add a part */ part = curl_mime_addpart(mime); /* continue and set name + data to the part */ curl_mime_data(part, "This is the field data", CURL_ZERO_TERMINATED); curl_mime_name(part, "data"); 

只要至少启用了 HTTP、SMTP 或 IMAP 之一。在 7.56.0 中添加。返回值:MIME 部分结构句柄,或失败时为 NULL。

4.curl_mime_name - 设置 mime 部分的名称
#include   CURLcode curl_mime_name(curl_mimepart *part, const char *name); 

curl_mime_name设置 mime 部分的名称。这是 HTTP 表单字段的命名方式。part是要为其分配名称的部件句柄。name指向以 null 结尾的名称字符串。名称字符串被复制到部件中,因此关联的存储可以在调用后安全地释放或重用。多次设置一个部件的名称是有效的:只保留最后一次调用设置的值。可以通过将name设置为 NULL 来“取消命名”零件。

5.curl_mime_data - 从内存中设置 mime 部分的主体数据
#include  CURLcode curl_mime_data(curl_mimepart *part, const char *data, size_t datasize); 

curl_mime_data从内存数据中设置 mime 部分的正文内容。 数据指向数据字节:那些被复制到部分并且它们的存储可以在调用后安全地重复使用。datasize是数据字节数:可以设置为CURL_ZERO_TERMINATED表示数据是一个以空字符结尾的字符串。part是要分配内容的部分。 多次设置一个部件的内容是有效的:只保留最后一次调用设置的值。可以通过将data设置为 NULL 来取消分配部分的内容。 设置大数据会消耗内存:在这种情况下可以考虑使用curl_mime_data_cb 。

6.curl_mime_filename - 设置 mime 部分的远程文件名 6.1.原理解析
#include  CURLcode curl_mime_filename(curl_mimepart *part,const char *filename); 

curl_mime_filename设置 mime 部分的远程文件名。设置远程文件名时,无论部件的内容源是什么,内容数据都会作为文件处理。部件的远程文件名在关联的 Content-Disposition 生成的标头中传输到服务器。 part是分配远程文件名的部件句柄。 filename指向以 null 结尾的文件名字符串;它可以设置为 NULL 以删除以前附加的远程文件名。 远程文件名字符串被复制到部件中,因此关联的存储可以在调用后安全地释放或重用。多次设置零件的文件名是有效的:只保留上次调用设置的值。

6.2.简单范例
curl_mime *mime; curl_mimepart *part; /* create a mime handle */ mime = curl_mime_init(easy); /* add a part */ part = curl_mime_addpart(mime); /* send image data from memory */ curl_mime_data(part, imagebuf, imagebuf_len); /* set a file name to make it look like a file upload */ curl_mime_filename(part, "image.png"); /* set name */ curl_mime_name(part, "data"); 
7.curl_mime_filedata - 从文件内容中设置 mime 部分的主体数据 7.1.原理解析
#include  CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename); 

curl_mime_filedata从命名文件的内容中设置 mime 部分的正文内容。这是curl_mime_data的替代方法,用于将数据设置为 mime 部分。 part是要分配内容的部分。 filename指向以 null 结尾的文件的路径名。指针可以为 NULL 以分离以前的部分内容设置。调用后可以安全地重用文件名存储。 作为一个副作用,如果部件的远程文件名是一个有效的命名文件,它会被设置为给定文件名的基本名称。这可以通过对curl_mime_filename的后续调用来撤消或覆盖。 在文件传输期间以流式方式读取文件的内容,以允许在不使用太多内存的情况下传输大文件。因此,它要求文件在整个请求期间保持完整。 如果在实际读取文件之前无法确定文件大小(例如对于设备或命名管道),则包含该部分的整个 mime 结构将通过 HTTP 作为块传输并被 IMAP 拒绝。 多次设置一个部件的内容是有效的:只保留最后一次调用设置的值。

7.2.简单范例
curl_mime *mime; curl_mimepart *part; /* create a mime handle */ mime = curl_mime_init(easy); /* add a part */ part = curl_mime_addpart(mime); /* send data from this file */ curl_mime_filedata(part, "image.png"); /* set name */ curl_mime_name(part, "data"); 

返回值:CURLE_OK或失败时的 CURL 错误代码。CURLE_READ_ERROR仅表明文件尚不可读:此时可以安全地忽略它,但必须在执行相关的简单句柄之前使文件可读。

8.curl_mime_type - 设置 mime 部分的内容类型 8.1.原理解析
#include  CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype); 

curl_mime_type设置 mime 部分的内容类型。 part是分配内容类型的部件句柄。 mimetype指向以 null 结尾的文件 mime 类型字符串;它可以设置为 NULL 以删除以前附加的 mime 类型。 mime 类型字符串被复制到部分中,因此相关的存储可以在调用后安全地释放或重用。多次设置一个部件的类型是有效的:只保留最后一次调用设置的值。 在没有 mime 类型的情况下,如果协议规范需要,则默认 mime 类型由上下文确定: 1.如果设置为自定义标头,则使用此值。 2.HTTP 表单发布 application/form-data。 3.如果设置了远程文件名,则 mime 类型取自文件扩展名,默认情况下为 application/octet-stream。 4.对于多部分,multipart/mixed。 5.其他情况下的 text/plain。

8.2.简单范例
curl_mime *mime; curl_mimepart *part; /* create a mime handle */ mime = curl_mime_init(easy); /* add a part */ part = curl_mime_addpart(mime); /* get data from this file */ curl_mime_filedata(part, "image.png"); /* content-type for this part */ curl_mime_type(part, "image/png"); /* set name */ curl_mime_name(part, "image"); 

返回值:CURLE_OK或失败时的 CURL 错误代码。

9.curl_mime_filedata - 从文件内容中设置 mime 部分的主体数据
#include  CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts); 
10.作者答疑

如有疑问,敬请留言。

关注
打赏
1688896170
查看更多评论

暂无认证

  • 6浏览

    0关注

    115984博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0410s