详参libcurl
curl_easy_getinfo
CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ... );
使用此函数从curl会话请求内部信息。第三个参数必须是指向long的指针、指向char*
的指针、指向struct curl_slist*
的指针或指向double的指针(本文档将进一步介绍)。指向的数据将相应地填充,并且仅当函数返回CURLE_OK
时才可以依赖。如果要获取传输相关数据,请在执行传输后使用此函数。
除非下面明确提到,否则不应释放此函数返回的内存。
CURLINFO_EFFECTIVE_URL
CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_EFFECTIVE_URL, char **urlp);
传入指向字符指针的指针,并获取上次使用的有效URL。
在要求libcurl遵循重定向的情况下,它很可能与使用CURLOPT_URL
设置的值不同。
urlp指针将为空或指向您不能释放的私有内存-当您对相应的curl句柄调用curl_easy_cleanup
时,它将被释放。
2. CURLINFO_RESPONSE_CODE
CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_RESPONSE_CODE, long *codep);
将指针传递给long以接收上次接收的HTTP、FTP或SMTP响应代码。这个选项以前在libcurl 7.10.7和更早版本中被称为CURLINFO_HTTP_代码。如果未收到服务器响应代码,则存储的值将为零。请注意,应该使用CURLINFO_HTTP_CONNECTCODE
读取代理的连接响应,而不是这个。
支持7.25.0中添加的SMTP响应。
示例:
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
long response_code;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
}
curl_easy_cleanup(curl);
}
CURLINFO_CONTENT_TYPE
CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_CONTENT_TYPE, char **ct);
传递指向char指针的指针以接收下载对象的内容类型。
这是从Content Type:字段读取的值。如果获得空值,则意味着服务器未发送有效的内容类型头,或者使用的协议不支持此操作。
ct指针将是空的,或者指向私有内存—您不能释放它—当您对相应的curl句柄调用curl_easy_cleanup
时,它将被释放。
curl_easy_perform
CURLcode curl_easy_perform(CURL *easy_handle);
在curl_easy_init
和所有curl_easy_setopt
调用之后调用此函数,并将执行选项中描述的传输。它必须使用与返回的curl_easy_init
调用相同的easy_
句柄作为输入来调用。
curl_easy_perform
以阻塞的方式执行整个请求,并在完成或失败时返回。有关非阻塞行为,请参见curl_multi_perform
。
您可以使用相同的easy_
句柄执行任意数量的curl_easy_
调用。如果您打算传送多个文件,我们甚至鼓励您这样做。然后,libcurl将尝试在以下传输中重新使用相同的连接,从而使操作更快、占用更少的CPU和使用更少的网络资源。请注意,您必须在调用之间使用curl_easy_setopt
来设置以下curl_easy_perform
的选项。
决不能使用同一个简单句柄从两个位置同时调用此函数。让函数在另一次调用之前先返回。如果要并行传输,必须使用多个curl easy_
句柄。
当easy_handle
被添加到多句柄时,curl_easy_perform
不能使用它。
curl_easy_setopt
CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
curl_easy_setopt
用于告诉libcurl如何行为。通过设置适当的选项,应用程序可以更改libcurl的行为。所有选项都是用一个选项后跟一个参数来设置的。该参数可以是long、函数指针、对象指针或curl_off_t
,具体取决于特定选项的期望值。请仔细阅读本手册,因为错误的输入值可能会导致libcurl行为不良!在每个函数调用中只能设置一个选项。典型的应用程序在安装阶段使用许多curl_easy_setopt
调用。
使用此函数调用设置的选项对于使用此句柄执行的所有即将进行的传输都有效。这些选项不会以任何方式在传输之间重置,因此如果希望后续传输具有不同的选项,则必须在传输之间更改它们。可以选择使用curl_easy_reset
将所有选项重置回内部默认值。
作为“char*
”参数传递给libcurl的字符串由库复制;因此,在curl_easy_setopt
返回后,与指针参数关联的字符串存储可能会被覆盖。此规则的唯一例外是CURLOPT_POSTFIELDS
,但是复制字符串CURLOPT_COPYPOSTFIELDS
的另一种方法有一些需要了解的用法特征。
选项的设置顺序无关紧要。
在7.17.0版本之前,没有复制字符串。相反,用户被迫保持它们可用,直到libcurl不再需要它们。
句柄是curl_easy_init
或curl_easy_duphandle
调用的返回代码。
BEHAVIOR OPTIONS:
CURLOPT_HEADER
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HEADER, long onoff);
将long值onoff设置为1,要求libcurl在写回调(CURLOPT_WRITEFUNCTION
)中包含头。此选项与实际具有头或其他元数据(如HTTP和FTP)的协议相关.
当要求将头传递到与主体相同的回调时,如果不详细了解正在使用的协议,就不可能再次准确地将它们分开。
进一步:CURLOPT_WRITEFUNCTION
回调仅限于获得传递给它的最大CURL_MAX_WRITE_大小字节(16KB)
的最大值,而头可以更长,CURLOPT_HEADERFUNCTION
支持使用最大CURL_MAX_HTTP_头字节大(100KB)
的头进行调用。
通常最好使用CURLOPT_HEADERFUNCTION
单独获取头数据。
CURLOPT_HTTPHEADER
用于设置自定义HTTP头!
2.CURLOPT_URL
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_URL, char *URL);
传入指向要使用的URL的指针。参数应该是一个字符*到以零结尾的字符串
,该字符串必须是以下格式的URL编码:
scheme://host:端口/路径
有关格式的详细说明,请参见RFC 3986。
在发出传输之前,libcurl不会验证语法或使用此变量。即使你在这里设置了一个疯狂的值,CURLE_easy_setopt
仍然会返回CURLE_OK
。
如果给定的URL缺少一个方案名(例如“http://”或“ftp://”等),那么libcurl将根据主机进行猜测。如果最外面的子域名与DICT、FTP、IMAP、LDAP、POP3或SMTP匹配,则将使用该协议,否则将使用HTTP。由于可以通过设置默认协议禁用7.45.0猜测,有关详细信息,请参见CURLOPT_default_protocol
。
如果libcurl不支持由方案指定的协议或由libcurl从主机名推断的协议,则在调用curl-easy-perform
或curl-multi-perform
函数时,CURLE-unupported-protocol
将从curl-easy-perform
或curl-multi-perform
函数返回。使用curl_version_info
可获得您正在使用的libcurl构建所支持的协议的详细信息。
CURLOPT_协议
可用于限制libcurl将用于此传输的协议,而与libcurl已编译为支持的协议无关。如果您接受来自外部源的URL并希望限制可访问性,则这可能很有用。
如果设置了CURLOPT_CURLU,则将忽略CURLOPT_URL
字符串。
开始传输之前,必须设置CURLOPT_URL
或CURLOPT_CURLU
。
URL的主机部分包含要连接到的服务器的地址。这可以是服务器的完全限定域名、网络上计算机的本地网络名称或由IPv4或IPv6地址表示的服务器或计算机的IP地址。例如:
http://www.example.com网站/
http://hostname/主机名/
http://192.168.0.1/
http://[2001:1890:1112:1::20]/
当连接到需要身份验证的服务器时,还可以为以下协议指定用户名、密码和作为主机一部分的任何支持的登录选项:
http://user:[email protected]
ftp://user:[email protected]
smb://domain%2fuser:[email protected]
imap://user:password;[email protected]
pop3://user:password;[email protected]
smtp://user:password;[email protected]
目前,只有IMAP、POP3和SMTP支持作为主机一部分的登录选项。有关URL语法中登录选项的更多信息,请参见RFC 2384、RFC 5092和IETF draft-earhart-URL-smtp-00.txt(在7.31.0中添加)。
端口是可选的,如果未指定,libcurl将根据已确定或指定的协议使用默认端口:HTTP为80,FTP为21,SMTP为25,等等。以下示例说明如何指定端口:
http://www.example.com:8080/—这将使用端口8080而不是80连接到web服务器。
smtp://mail.example.com:587/-这将连接到另一个邮件端口上的smtp服务器。
URL的路径部分是特定于协议的,虽然下面给出了一些示例,但此列表并不确定:
超文本传输协议
HTTP请求的路径部分指定要从哪个目录检索的文件。如果未指定目录,则使用web服务器的根目录。如果省略该文件,则将检索指定目录或根目录的默认文档。为每个URL返回的确切资源完全取决于服务器的配置。
http://www.example.com-从web服务器获取主页。
http://www.example.com/index.html-通过显式请求返回主页面。
http://www.example.com/contactus/-这将从contactus目录返回默认文档。
CURLOPT_URL
参数中指向的字符串通常是使用ASCII兼容编码的字符序列。
如果libcurl是使用IDN支持构建的,那么URL的服务器名部分可以通过使用当前编码(根据语言环境)或UTF-8(使用winidn时)使用“国际名称”。
如果libcurl是在不支持IDN的情况下生成的,那么在传递给名称解析器函数时,服务器名称将完全按照指定的方式使用。
CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
curl_easy_perform(curl);
}
CURLOPT_POST
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_POST, long post);
设置为1的参数告诉libcurl执行常规的HTTP post。这还将使库使用“Content Type:application/x-www-form-urlencoded”头。(这是目前最常用的POST方法)。
使用CURLOPT_POSTFIELDS
或CURLOPT_COPYPOSTFIELDS
选项之一指定要发布的数据,并使用CURLOPT_POSTFIELDSIZE
或CURLOPT_POSTFIELDSIZE_LARGE
设置数据大小。
或者,您可以使用CURLOPT_READFUNCTION
和CURLOPT_READDATA
选项提供要发布的数据,但是您必须确保不将CURLOPT_POSTFIELDS
设置为空。在为数据提供回调时,必须使用分块传输编码传输数据,或者必须使用CURLOPT_POSTFIELDSIZE
或CURLOPT_POSTFIELDSIZE
选项设置数据大小。要启用分块编码,只需传入适当的传输编码头,请参阅post callback.c示例。
您可以通过使用CURLOPT_HTTPHEADER
设置自己的POST-Content-Type:header来覆盖默认的POST-Content。
对HTTP 1.1使用POST意味着使用“Expect:100continue”头。您可以像往常一样使用CURLOPT_HTTPHEADER
禁用此头文件。
如果使用POST到HTTP 1.1服务器,如果使用分块编码,则可以在启动POST之前不知道大小就发送数据。您可以通过添加带有CURLOPT_HTTPHEADER
的类似“Transfer Encoding:chunked”的头来实现这一点。使用HTTP 1.0或不使用分块传输时,必须在请求中指定大小。(从7.66.0开始,如果大小未知,libcurl将自动对POSTs使用分块编码。)
将CURLOPT_POST
设置为1时,libcurl将自动将CURLOPT_NOBODY
和CURLOPT_HTTPGET
设置为0。
如果您发出POST请求,然后希望使用相同的重用句柄生成HEAD或GET,则必须使用CURLOPT_NOBODY
或CURLOPT_HTTPGET
或类似工具显式设置新的请求类型。
CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_POST, 1L);
/* set up the read callback with CURLOPT_READFUNCTION */
ret = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
CURLOPT_POSTFIELDS
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_POSTFIELDS, char *postdata);
将char*
作为参数传递,指向要在HTTP POST操作中发送的完整数据。必须确保数据的格式符合服务器接收数据的方式。libcurl不会以任何方式为您转换或编码它。例如,web服务器可以假设这些数据是url编码的。
指向的数据不是由库复制的:因此,调用应用程序必须保留它,直到相关的传输完成。通过设置CURLOPT_COPYPOSTFIELDS
选项,可以更改此行为(因此libcurl会复制数据)。
本文是一个普通的application/x-www-form-urlencoded类型(使用此选项时,libcurl将默认设置该内容类型),HTML表单通常使用该类型。使用CURLOPT_HTTPHEADER
更改内容类型。
如果需要,可以使用curl_easy_escape
对数据进行url编码。它返回一个指向可作为postdata传递的编码字符串的指针。
使用CURLOPT_POSTFIELDS
意味着将CURLOPT_POST
设置为1。
如果CURLOPT_POSTFIELDS
显式设置为空,那么libcurl将从read回调获取POST数据。如果要发送零字节POST,请将CURLOPT_POSTFIELDS
设置为空字符串,或将CURLOPT_POST
设置为1,将CURLOPT_POSTFIELDSIZE
设置为0。
对HTTP 1.1使用POST意味着使用“Expect:100continue”头,如果已知POST大于1MB或预期大小未知,libcurl将自动添加该头。您可以像往常一样使用CURLOPT_HTTPHEADER
禁用此头文件。
要制作多部分/formdata posts(aka RFC 2388 posts),请查看CURLOPT_HTTPPOST
选项和curl_formadd
。
CURL *curl = curl_easy_init();
if(curl) {
const char *data = "data to send";
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
/* size of the POST data */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 12L);
/* pass in a pointer to the data - libcurl will not copy */
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
curl_easy_perform(curl);
}
5.CURLOPT_COPYPOSTFIELDS
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_COPYPOSTFIELDS, char *data);
传递一个char*
作为参数,它应该是要在HTTP post操作中发布的完整数据。它的行为类似于CURLOPT_POSTFIELDS
选项,但原始数据由库复制,允许应用程序在设置此选项后覆盖原始数据。
由于数据是复制的,因此在将此选项与CURLOPT_POSTFIELDSIZE
或CURLOPT_POSTFIELDSIZE_LARGE
一起使用时必须小心:如果在CURLOPT_COPYPOSTFIELDS
之前未设置大小,则假定数据是以零结尾的字符串;否则,存储的大小将通知库要复制的字节数。在任何情况下,在CURLOPT_COPYPOSTFIELDS
之后都不能更改大小,除非发出另一个CURLOPT_POSTFIELDS
或CURLOPT_COPYPOSTFIELDS
选项。
CURL *curl = curl_easy_init();
if(curl) {
char local_buffer[1024]="data to send";
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
/* size of the data to copy from the buffer and send in the request */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 12L);
/* send data from the local stack */
curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, local_buffer);
curl_easy_perform(curl);
}
CURLOPT_HTTPPOST
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HTTPPOST,struct curl_httppost *formpost);
告诉libcurl您希望创建多部分/formdata HTTP POST,并在formpost参数中指示将哪些数据传递给服务器。将指针作为参数传递给curl_httppost
结构的链接列表。创建这样一个列表的最简单方法是使用curl-formadd
。只要curl传输是活动的并且正在使用它,这个列表中的数据就必须保持完整。
对HTTP 1.1使用POST意味着使用“Expect:100continue”头。可以使用CURLOPT_HTTPHEADER
禁用此头。
当设置CURLOPT_HTTPPOST
时,它会自动将CURLOPT_NOBODY
设置为0。
/* Fill in the file upload field. This makes libcurl load data from
the given file name when curl_easy_perform() is called. */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "sendfile",
CURLFORM_FILE, "postit2.c",
CURLFORM_END);
/* Fill in the filename field */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "filename",
CURLFORM_COPYCONTENTS, "postit2.c",
CURLFORM_END);
/* Fill in the submit field too, even if this is rarely needed */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "submit",
CURLFORM_COPYCONTENTS, "send",
CURLFORM_END);
7.CURLOPT_HTTPHEADER
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HTTPHEADER, struct curl_slist *headers);
将指针传递到要传递到HTTP请求中的服务器和/或代理的HTTP头的链接列表。同一列表可用于主机和代理请求!
链表应该是正确填充的结构curl_slist
结构的完全有效的列表。使用curl_slist_append
创建列表,使用curl_slist_free_all
清理整个列表。如果添加libcurl在内部生成并使用的头,则将使用添加的头。如果添加的头没有“Accept:”中的内容(冒号右侧没有数据),则内部使用的头将被禁用。使用此选项,可以添加新标题、替换内部标题和删除内部标题。要添加没有内容(冒号右侧没有内容)的标题,请使用“MyHeader;”格式(注意结尾分号)。
链接列表中包含的头不能以CRLF结尾,因为libcurl会在每个头项之后添加CRLF。不遵守这一点将导致奇怪的错误,因为服务器很可能会忽略您指定的部分头。
请求中的第一行(包含方法,通常是GET或POST)不是头,不能使用此选项替换。只有请求行后面的行是头。在头列表中添加此方法行只会导致您的请求发送无效的头。使用CURLOPT_CUSTOMREQUEST
更改方法。
将此选项传递给curl_easy_setopt
时,libcurl不会复制整个列表,因此在调用列表中的curl_slist_free_all
之前,必须保留它,直到不再使用此句柄进行传输。
将空值传递给此选项以重置回无自定义头。
最常用的替换标题在CURLOPT_COOKIE
、CURLOPT_USERAGENT
和CURLOPT_REFERER
选项中有“快捷方式”。我们建议使用这些。
有一个替代选项,它只为通过连接到代理发送的请求设置或替换头:CURLOPT_PROXYHEADER
。使用CURLOPT_HEADEROPT
来控制行为。
CURL *curl = curl_easy_init();
struct curl_slist *list = NULL;
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
list = curl_slist_append(list, "Shoesize: 10");
list = curl_slist_append(list, "Accept:");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
curl_easy_perform(curl);
curl_slist_free_all(list); /* free the list again */
}