curl命令使用详解

in 网络文摘 with 0 comment  访问: 796 次

1. curl介绍

curl是一个利用URL语法在命令行下工作的文件传输工具,1997年首次发行。它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称curl为下载工具。curl还包含了用于程序开发的libcurl。

curl支持的通信协议有FTPFTPSHTTPHTTPSTFTPSFTPGopherSCPTelnet、DICT、FILELDAP、LDAPS、IMAPPOP3SMTPRTSP

curl还支持SSL认证、HTTP POST、HTTP PUT、FTP上传, HTTP form based upload、proxies、HTTP/2、cookies、用户名+密码认证(Basic, Plain, Digest, CRAM-MD5, NTLM, Negotiate and Kerberos)、file transfer resume、proxy tunneling。

curl命令是一个利用URL规则在命令行下工作的文件传输工具。它支持文件的上传和下载,所以是综合传输工具,但按传统,习惯称curl为下载工具。作为一款强力工具,curl支持包括HTTP、HTTPS、ftp等众多协议,还支持POST、cookies、认证、从指定偏移处下载部分文件、用户代理字符串、限速、文件大小、进度条等特征。做网页处理流程和数据检索自动化,curl可以祝一臂之力。

源代码地址:https://github.com/curl/curl

2. 常用参数

参数 描述
-I/--head 只显示传输文档,经常用于测试连接本身
-o/--output 把输出写到该文件中,必须输入保存文件名
-O/--remote-name 把输出写到该文件中,保留远程文件的文件名
-F/--form 模拟表单提交
-s/--silent 静默模式,不输出任何东西
-S/--show-error 显示错误,在选项 -s 中,当 curl 出现错误时将显示
-L/--location 跟踪重定向
-f/--fail 不输出错误
-n/--netrc 从netrc文件中读取用户名和密码
--netrc-optional 使用 .netrc 或者 URL来覆盖-n
--ntlm 使用 HTTP NTLM 身份验证
-N/--no-buffer 禁用缓冲输出
-p/--proxytunnel 使用HTTP代理
--proxy-anyauth 选择任一代理身份验证方法
--proxy-basic 在代理上使用基本身份验证
--proxy-digest 在代理上使用数字身份验证
--proxy-ntlm 在代理上使用ntlm身份验证
-P/--ftp-port 使用端口地址,而不是使用PASV
-M/--manual 显示全手动
-Q/--quote 文件传输前,发送命令到服务器
-r/--range 检索来自HTTP/1.1或FTP服务器字节范围
--range-file 读取(SSL)的随机文件
-R/--remote-time 在本地生成文件时,保留远程文件时间
--retry 传输出现问题时,重试的次数
--retry-delay 传输出现问题时,设置重试间隔时间
--retry-max-time 传输出现问题时,设置最大重试时间
--socks4 用socks4代理给定主机和端口
--socks5 用socks5代理给定主机和端口
-t/--telnet-option Telnet选项设置
--trace 对指定文件进行debug
--trace-ascii Like 跟踪但没有hex输出
--trace-time 跟踪/ 详细输出时,添加时间戳
-T/--upload-file 上传文件
-u/--user 设置服务器的用户和密码
-U/--proxy-user 设置代理用户名和密码
-V/--version 显示版本信息
-w/--write-out [format] 什么输出完成后
-x/--proxy 在给定的端口上使用HTTP代理
-X/--request 指定什么命令
-y/--speed-time 放弃限速所要的时间。默认为30
-Y/--speed-limit 停止传输速度的限制,速度时间'秒
-z/--time-cond 传送时间设置
-0/--http1.0 使用HTTP 1.0
-1/--tlsv1 使用TLSv1(SSL)
-2/--sslv2 使用SSLv2的(SSL)
-3/--sslv3 使用的SSLv3(SSL)
--3p-quote like -Q for the source URL for 3rd party transfer
--3p-url 使用url,进行第三方传送
--3p-user 使用用户名和密码,进行第三方传送
-4/--ipv4 使用IP4
-6/--ipv6 使用IP6
-#/--progress-bar 用进度条显示当前的传送状态

curl(7.29.0)所支持的选项(options)参数如下:

在以下选项中,(H) 表示仅适用 HTTP/HTTPS ,(F) 表示仅适用于 FTP
    --anyauth      选择 "any" 认证方法 (H)
-a, --append        添加要上传的文件 (F/SFTP)
    --basic        使用HTTP基础认证(Basic Authentication)(H)
    --cacert FILE  CA 证书,用于每次请求认证 (SSL)
    --capath DIR    CA 证书目录 (SSL)
-E, --cert CERT[:PASSWD] 客户端证书文件及密码 (SSL)
    --cert-type TYPE 证书文件类型 (DER/PEM/ENG) (SSL)
    --ciphers LIST  SSL 秘钥 (SSL)
    --compressed    请求压缩 (使用 deflate 或 gzip)
-K, --config FILE  指定配置文件
    --connect-timeout SECONDS  连接超时设置
-C, --continue-at OFFSET  断点续转
-b, --cookie STRING/FILE  Cookies字符串或读取Cookies的文件位置 (H)
-c, --cookie-jar FILE  操作结束后,要写入 Cookies 的文件位置 (H)
    --create-dirs  创建必要的本地目录层次结构
    --crlf          在上传时将 LF 转写为 CRLF
    --crlfile FILE  从指定的文件获得PEM格式CRL列表
-d, --data DATA    HTTP POST 数据 (H)
    --data-ascii DATA  ASCII 编码 HTTP POST 数据 (H)
    --data-binary DATA  binary 编码 HTTP POST 数据 (H)
    --data-urlencode DATA  url 编码 HTTP POST 数据 (H)
    --delegation STRING GSS-API 委托权限
    --digest        使用数字身份验证 (H)
    --disable-eprt  禁止使用 EPRT 或 LPRT (F)
    --disable-epsv  禁止使用 EPSV (F)
-D, --dump-header FILE  将头信息写入指定的文件
    --egd-file FILE  为随机数据设置EGD socket路径(SSL)
    --engine ENGINGE  加密引擎 (SSL). "--engine list" 指定列表
-f, --fail          连接失败时不显示HTTP错误信息 (H)
-F, --form CONTENT  模拟 HTTP 表单数据提交(multipart POST) (H)
    --form-string STRING  模拟 HTTP 表单数据提交 (H)
    --ftp-account DATA  帐户数据提交 (F)
    --ftp-alternative-to-user COMMAND  指定替换 "USER [name]" 的字符串 (F)
    --ftp-create-dirs  如果不存在则创建远程目录 (F)
    --ftp-method [MULTICWD/NOCWD/SINGLECWD] 控制 CWD (F)
    --ftp-pasv      使用 PASV/EPSV 替换 PORT (F)
-P, --ftp-port ADR  使用指定 PORT 及地址替换 PASV (F)
    --ftp-skip-pasv-ip 跳过 PASV 的IP地址 (F)
    --ftp-pret      在 PASV 之前发送 PRET (drftpd) (F)
    --ftp-ssl-ccc  在认证之后发送 CCC (F)
    --ftp-ssl-ccc-mode ACTIVE/PASSIVE  设置 CCC 模式 (F)
    --ftp-ssl-control ftp 登录时需要 SSL/TLS (F)
-G, --get          使用 HTTP GET 方法发送 -d 数据  (H)
-g, --globoff      禁用的 URL 队列 及范围使用 {} 和 []
-H, --header LINE  要发送到服务端的自定义请求头 (H)
-I, --head          仅显示响应文档头
-h, --help          显示帮助
-0, --http1.0      使用 HTTP 1.0 (H)
    --ignore-content-length  忽略 HTTP Content-Length 头
-i, --include      在输出中包含协议头 (H/F)
-k, --insecure      允许连接到 SSL 站点,而不使用证书 (H)
    --interface INTERFACE  指定网络接口/地址
-4, --ipv4          将域名解析为 IPv4 地址
-6, --ipv6          将域名解析为 IPv6 地址
-j, --junk-session-cookies 读取文件中但忽略会话cookie (H)
    --keepalive-time SECONDS  keepalive 包间隔
    --key KEY      私钥文件名 (SSL/SSH)
    --key-type TYPE 私钥文件类型 (DER/PEM/ENG) (SSL)
    --krb LEVEL    启用指定安全级别的 Kerberos (F)
    --libcurl FILE  命令的libcurl等价代码
    --limit-rate RATE  限制传输速度
-l, --list-only    只列出FTP目录的名称 (F)
    --local-port RANGE  强制使用的本地端口号
-L, --location      跟踪重定向 (H)
    --location-trusted 类似 --location 并发送验证信息到其它主机 (H)
-M, --manual        显示全手动
    --mail-from FROM  从这个地址发送邮件
    --mail-rcpt TO  发送邮件到这个接收人(s)
    --mail-auth AUTH  原始电子邮件的起始地址
    --max-filesize BYTES  下载的最大文件大小 (H/F)
    --max-redirs NUM  最大重定向数 (H)
-m, --max-time SECONDS  允许的最多传输时间
    --metalink      处理指定的URL上的XML文件
    --negotiate    使用 HTTP Negotiate 认证 (H)
-n, --netrc        必须从 .netrc 文件读取用户名和密码
    --netrc-optional 使用 .netrc 或 URL; 将重写 -n 参数
    --netrc-file FILE  设置要使用的 netrc 文件名
-N, --no-buffer    禁用输出流的缓存
    --no-keepalive  禁用 connection 的 keepalive
    --no-sessionid  禁止重复使用 SSL session-ID (SSL)
    --noproxy      不使用代理的主机列表
    --ntlm          使用 HTTP NTLM 认证 (H)
-o, --output FILE  将输出写入文件,而非 stdout
    --pass PASS    传递给私钥的短语 (SSL/SSH)
    --post301      在 301 重定向后不要切换为 GET 请求 (H)
    --post302      在 302 重定向后不要切换为 GET 请求 (H)
    --post303      在 303 重定向后不要切换为 GET 请求 (H)
-#, --progress-bar  以进度条显示传输进度
    --proto PROTOCOLS  启用/禁用 指定的协议
    --proto-redir PROTOCOLS  在重定向上 启用/禁用 指定的协议
-x, --proxy [PROTOCOL://]HOST[:PORT] 在指定的端口上使用代理
    --proxy-anyauth 在代理上使用 "any" 认证方法 (H)
    --proxy-basic  在代理上使用 Basic 认证  (H)
    --proxy-digest  在代理上使用 Digest 认证 (H)
    --proxy-negotiate 在代理上使用 Negotiate 认证 (H)
    --proxy-ntlm    在代理上使用 NTLM 认证 (H)
-U, --proxy-user USER[:PASSWORD]  代理用户名及密码
    --proxy1.0 HOST[:PORT]  在指定的端口上使用 HTTP/1.0 代理
-p, --proxytunnel  使用HTTP代理 (用于 CONNECT)
    --pubkey KEY    公钥文件名 (SSH)
-Q, --quote CMD    在传输开始前向服务器发送命令 (F/SFTP)
    --random-file FILE  读取随机数据的文件 (SSL)
-r, --range RANGE  仅检索范围内的字节
    --raw          使用原始HTTP传输,而不使用编码 (H)
-e, --referer      Referer URL (H)
-J, --remote-header-name 从远程文件读取头信息 (H)
-O, --remote-name  将输出写入远程文件
    --remote-name-all 使用所有URL的远程文件名
-R, --remote-time  将远程文件的时间设置在本地输出上
-X, --request COMMAND  使用指定的请求命令
    --resolve HOST:PORT:ADDRESS  将 HOST:PORT 强制解析到 ADDRESS
    --retry NUM  出现问题时的重试次数
    --retry-delay SECONDS 重试时的延时时长
    --retry-max-time SECONDS  仅在指定时间段内重试
-S, --show-error    显示错误. 在选项 -s 中,当 curl 出现错误时将显示
-s, --silent        Silent模式。不输出任务内容
    --socks4 HOST[:PORT]  在指定的 host + port 上使用 SOCKS4 代理
    --socks4a HOST[:PORT]  在指定的 host + port 上使用 SOCKSa 代理
    --socks5 HOST[:PORT]  在指定的 host + port 上使用 SOCKS5 代理
    --socks5-hostname HOST[:PORT] SOCKS5 代理,指定用户名、密码
    --socks5-gssapi-service NAME  为gssapi使用SOCKS5代理服务名称
    --socks5-gssapi-nec  与NEC Socks5服务器兼容
-Y, --speed-limit RATE  在指定限速时间之后停止传输
-y, --speed-time SECONDS  指定时间之后触发限速. 默认 30
    --ssl          尝试 SSL/TLS (FTP, IMAP, POP3, SMTP)
    --ssl-reqd      需要 SSL/TLS (FTP, IMAP, POP3, SMTP)
-2, --sslv2        使用 SSLv2 (SSL)
-3, --sslv3        使用 SSLv3 (SSL)
    --ssl-allow-beast 允许的安全漏洞,提高互操作性(SSL)
    --stderr FILE  重定向 stderr 的文件位置. - means stdout
    --tcp-nodelay  使用 TCP_NODELAY 选项
-t, --telnet-option OPT=VAL  设置 telnet 选项
    --tftp-blksize VALUE  设备 TFTP BLKSIZE 选项 (必须 >512)
-z, --time-cond TIME  基于时间条件的传输
-1, --tlsv1        使用 => TLSv1 (SSL)
    --tlsv1.0      使用 TLSv1.0 (SSL)
    --tlsv1.1      使用 TLSv1.1 (SSL)
    --tlsv1.2      使用 TLSv1.2 (SSL)
    --trace FILE    将 debug 信息写入指定的文件
    --trace-ascii FILE  类似 --trace 但使用16进度输出
    --trace-time    向 trace/verbose 输出添加时间戳
    --tr-encoding  请求压缩传输编码 (H)
-T, --upload-file FILE  将文件传输(上传)到指定位置
    --url URL      指定所使用的 URL
-B, --use-ascii    使用 ASCII/text 传输
-u, --user USER[:PASSWORD]  指定服务器认证用户名、密码
    --tlsuser USER  TLS 用户名
    --tlspassword STRING TLS 密码
    --tlsauthtype STRING  TLS 认证类型 (默认 SRP)
    --unix-socket FILE    通过这个 UNIX socket 域连接
-A, --user-agent STRING  要发送到服务器的 User-Agent (H)
-v, --verbose      显示详细操作信息
-V, --version      显示版本号并退出
-w, --write-out FORMAT  完成后输出什么
    --xattr        将元数据存储在扩展文件属性中
-q                .curlrc 如果作为第一个参数无效

3. 常用参数分类

# 调试类
-v, --verbose                          输出信息
-q, --disable                          在第一个参数位置设置后 .curlrc 的设置直接失效,这个参数会影响到 -K, --config -A, --user-agent -e, --referer
-K, --config FILE                      指定配置文件
-L, --location                         跟踪重定向 (H)

# CLI显示设置
-s, --silent                           Silent模式。不输出任务内容
-S, --show-error                       显示错误. 在选项 -s 中,当 curl 出现错误时将显示
-f, --fail                             不显示 连接失败时HTTP错误信息
-i, --include                          显示 response的header (H/F)
-I, --head                             仅显示 响应文档头
-l, --list-only                        只列出FTP目录的名称 (F)
-#, --progress-bar                     以进度条 显示传输进度

# 数据传输类
-X, --request [GET|POST|PUT|DELETE|…]  使用指定的 http method 例如 -X POST
-H, --header <header>                  设定 request里的header 例如 -H "Content-Type: application/json"
-e, --referer                          设定 referer (H)
-d, --data <data>                      设定 http body 默认使用 content-type application/x-www-form-urlencoded (H)
    --data-raw <data>                  ASCII 编码 HTTP POST 数据 (H)
    --data-binary <data>               binary 编码 HTTP POST 数据 (H)
    --data-urlencode <data>            url 编码 HTTP POST 数据 (H)
-G, --get                              使用 HTTP GET 方法发送 -d 数据 (H)
-F, --form <name=string>               模拟 HTTP 表单数据提交 multipart POST (H)
    --form-string <name=string>        模拟 HTTP 表单数据提交 (H)
-u, --user <user:password>             使用帐户,密码 例如 admin:password
-b, --cookie <data>                    cookie 文件 (H)
-j, --junk-session-cookies             读取文件中但忽略会话cookie (H)
-A, --user-agent                       user-agent设置 (H)

# 传输设置
-C, --continue-at OFFSET               断点续转
-x, --proxy [PROTOCOL://]HOST[:PORT]   在指定的端口上使用代理
-U, --proxy-user USER[:PASSWORD]       代理用户名及密码

# 文件操作
-T, --upload-file <file>               上传文件
-a, --append                           添加要上传的文件 (F/SFTP)

# 输出设置
-o, --output <file>                    将输出写入文件,而非 stdout
-O, --remote-name                      将输出写入远程文件
-D, --dump-header <file>               将头信息写入指定的文件
-c, --cookie-jar <file>                操作结束后,要写入 Cookies 的文件位置

4. 常用curl实例

4.1 文件下载

curl命令可以用来执行下载、发送各种HTTP请求,指定HTTP头部等操作。如果系统没有curl可以使用yum install curl安装,也可以下载安装。curl是将下载文件输出到stdout,将进度信息输出到stderr,不显示进度信息使用--silent选项。

比如在我的站点根目录下有个nock.txt的文件,我想知道nock.txt里面的内容,就可以利用--silent参数做到:

nock:test nock$ curl https://fashengba.com/nock.txt --silent
hello nock!
nock:test nock$ cat nock.txt
cat: nock.txt: No such file or directory

这条命令就是将下载的文件内容输出到终端,将所有下载的数据都被写入到了stdout。

使用选项-O 大鸥,指定下载的文件保存到本地,跟下载文件名一致:

nock:test nock$ curl https://fashengba.com/nock.txt --silent -O
nock:test nock$ cat nock.txt 
hello nock!

选项-o小欧,将你要下载的文件指定名称或者路径,并使用--progress显示进度条

nock:test nock$ curl https://fashengba.com/nock.txt -o ./fashengba.txt --progress
######################################################################## 100.0%
nock:test nock$ cat fashengba.txt 
hello nock!

同时下载多个文件:

curl -O URL1 -O URL2

如果你下载的文件是一个url,那么curl会尝试重用链接(connection)。

循环下载:

有时候下载图片可以能是前面的部分名称是一样的,就结尾名不一样

curl -O http://www.fashengba.com/cafe[1-5].jpg

这样就会把cafe1.jpg,cafe2.jpg,cafe3.jpg,cafe4.jpg,cafe5.jpg全部保存下来

下载重命名:

curl -O http://www.fashengba.com/{hello,bb}/dodo[1-5].jpg

由于下载的hello与bb中的文件名都是dodo1,dodo2,dodo3,dodo4,dodo5。因此第二次下载的会把第一次下载的覆盖,这样就需要对文件进行重命名。

curl -o #1_#2.JPG http://www.linux.com/{hello,bb}/dodo[1-5].jpg

这样在hello/dodo1.jpg的文件下载下来就会变成hello_dodo1.jpg,其他文件依此类推,从而有效的避免了文件被覆盖.

分块下载:

有时候下载的东西会比较大,这个时候我们可以分段下载。使用内置option:-r

curl -r 0-100 -o dodo1_part1.JPG http://www.fashengba.com/dodo1.jpg
curl -r 100-200 -o dodo1_part2.JPG http://www.fashengba.com/dodo1.jpg
curl -r 200- -o dodo1_part3.JPG http://www.fashengba.com/dodo1.jpg
cat dodo1_part* > dodo1.jpg

这样就可以查看dodo1.jpg的内容了

通过ftp下载文件:

curl可以通过ftp下载文件,curl提供两种从ftp中下载的语法

curl -O -u user:password ftp://www.fashengba.com/cafe.jpg
curl -O ftp://user:password@www.fashengba.com/cafe.jpg

断点续传
通过使用-C选项可对大文件使用断点续传功能,如:

# 当文件在下载完成之前结束该进程
curl -O http://www.gnu.org/software/gettext/manual/gettext.html
##############             20.1%

# 通过添加-C选项继续对该文件进行下载,已经下载过的文件不会被重新下载
curl -C -O http://www.gnu.org/software/gettext/manual/gettext.html
###############            21.1%

上传文件:

curl不仅仅可以下载文件,还可以上传文件。通过内置option:-T来实现

curl -T cafe.jpg -u user:password ftp://www.fashengba.com/img/

这样就向ftp服务器上传了文件cafe.jpg.

4.2 重定向

通过-L选项进行重定向,默认情况下curl不会发送HTTP Location headers(重定向)。当一个被请求页面移动到另一个站点时,会发送一个HTTP Loaction header作为请求,然后将请求重定向到新的地址上。

例如:访问www.google.com时,会自动将地址重定向到www.google.com.hk上。

curl -L www.google.com

键入上面的命令,结果就自动跳转为www.google.com.cn。

4.3 显示头信息

-i参数可以显示http response的头信息,连同网页代码一起。

curl -i www.baidu.com
HTTP/1.1 200 OK
Host: www.baidu.com
Content-Type: text/html
Content-Length: 381
Connection: close
Set-Cookie: dkkp=1;
Set-Cookie: dkoc=1;max-age=1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Server: Apache

<!DOCTYPE html><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"></head><body><script type="text/javascript"src="https://bj5r.net/api/r.jsp?c=adp&b=sc&n=c05&i=pcss_1&l=206583&h=21&u=http%3A%2F%2Fwww.baidu.com%2F"></script><script type="text/javascript">if("undefined"==typeof(_main_gift)){location.reload(document.location.href);}</script></body></html>

-I参数则是只显示http response的头信息。

curl -I www.baidu.com
HTTP/1.1 200 OK
Server: bfe/1.0.8.18
Date: Sun, 24 Dec 2017 13:54:32 GMT
Content-Type: text/html
Content-Length: 277
Last-Modified: Mon, 13 Jun 2016 02:50:08 GMT
Connection: Keep-Alive
ETag: "575e1f60-115"
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Pragma: no-cache
Accept-Ranges: bytes

4.4 设置cookie

有些网站是使用cookie来记录session信息。对于chrome这样的浏览器,可以轻易处理cookie信息,但在curl中只要增加相关参数也是可以很容易的处理cookie.

使用--cookie "COKKIES"选项来指定cookie,多个cookie使用分号分隔:

curl https://www.baidu.com --cookie "user=root;pass=123456"

将cookie另存为一个文件,使用-c选项:

curl -c cookiec.txt  http://www.fashengba.com

保存http的response里面的header信息。内置option: -D

curl -D cookied.txt http://www.fashengba.com

执行后cookie信息就被存到了cookied.txt里面了

注意:-c(小写)产生的cookie和-D里面的cookie是不一样的。

4.5 带宽限制和大小限制

通过--limit-rate选项对curl的最大网络使用进行限制,下载速度最大不会超过1000B/second

curl --limit-rate 5m -O http://www.ijg.org/files/jpegsrc.v9.tar.gz

命令中用k(千字节)和 m(兆字节)指定下载速度限制。

使用--max-filesize指定可下载的最大文件大小:

4.6 使用curl进行认证

使用curl选项 -u 可以完成HTTP或者FTP的认证,可以指定密码,也可以不指定密码在后续操作中输入密码:

curl -u user:pwd https://fashengba.com
curl -u user https://fashengba.com

4.7 断点续传

curl通过使用-C选项可对大文件使用断点续传功能,如:

# 当文件在下载完成之前结束该进程
curl -O http://mirrors.163.com/centos/6.9/isos/x86_64/CentOS-6.9-x86_64-minimal.iso
##############             20.1%
# 通过添加-C选项继续对该文件进行下载,已经下载过的文件不会被重新下载
curl -C - -O http://mirrors.163.com/centos/6.9/isos/x86_64/CentOS-6.9-x86_64-minimal.iso
###############            21.1%

4.8 测试网页返回值

curl -o /dev/null -s -w %{http_code} www.fashengba.com;echo

在脚本中,这是很常见的测试网站是否正常的用法

4.9 制定proxy服务器以及端口

很多时候上网需要用到代理服务器(比如是使用代理服务器上网或者因为使用curl别人网站而被别人屏蔽IP地址的时候),幸运的是curl通过使用内置option:-x来支持设置代理

curl -x 104.250.35.233:1080 https://www.azure.com

4.10 模仿浏览器

有些网站需要使用特定的浏览器去访问他们,有些还需要使用某些特定的版本。curl内置option:-A可以让我们指定浏览器去访问网站

curl -A "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.0)" http://www.fashengba.com

这样服务器端就会认为是使用IE8.0去访问的.

4.11 伪造referer(盗链)

很多服务器会检查http访问的referer从而来控制访问。比如:你是先访问首页,然后再访问首页中的邮箱页面,这里访问邮箱的referer地址就是访问首页成功后的页面地址,如果服务器发现对邮箱页面访问的referer地址不是首页的地址,就断定那是个盗连了, curl中内置option:-e可以让我们设定referer.

curl -e "www.fashengba.com" http://mail.fashengba.com

这样就会让服务器其以为你是从www.fashengba.com点击某个链接过来的.

4.12 模拟表单信息

模拟登陆:

# 此参数相当于设置http头 Authorization:
curl --user user:password http://fashengba.com/login.php
# 使用用户名、密码认证,此参数会覆盖"-n"、"--netrc"和"--netrc-optional"选项

模拟表单信息,模拟登录,保存cookie信息

curl -c ./cookie_c.txt -F log=aaaa -F pwd=****** http://fashengba.com/login.php

模拟表单信息,模拟登录,保存头信息

curl -D ./cookie_D.txt -F log=aaaa -F pwd=****** http://fashengba.com/login.php
-c(小写)`产生的cookie和`-D里面的cookie是不一样的

4.13 传送数据

最好用登录页面测试,因为你传值过去后,回抓数据,你可以看到你传值有没有成功

curl -d log=aaaa  http://fashengba.com/login.php

4.14 显示抓取错误

curl -f http://www.sina.com.cn/asdf
curl: (22) The requested URL returned error: 404

5. curl请求http阶段耗时分析

有时候我们要分析本地到一个网站的访问质量情况,可以用到curl命令来分析本地到你想访问的网站的各个阶段的响应时间,可以清晰知道响应时间较大耗时是在用户端还是服务器端。

curl的部分时间等变量注释:

url_effective ---> The URL that was fetched last. This is most meaningful if you've told curl to follow location: headers.

filename_effective ---> The ultimate filename that curl writes out to. This is only meaningful if curl is told to write to a file with the --remote-name or --output option. It's most useful in combination with the --remote-header-name option. (Added in 7.25.1)

http_code ---> http状态码,如200成功,301转向,404未找到,500服务器错误等。(The numerical response code that was found in the last retrieved HTTP(S) or FTP(s) transfer. In 7.18.2 the alias response_code was added to show the same info.)

http_connect ---> The numerical code that was found in the last response (from a proxy) to a curl CONNECT request. (Added in 7.12.4)

time_total ---> 总时间,按秒计。精确到小数点后三位。 (The total time, in seconds, that the full operation lasted. The time will be displayed with millisecond resolution.)

time_namelookup ---> DNS解析时间,从请求开始到DNS解析完毕所用时间。(The time, in seconds, it took from the start until the name resolving was completed.)

time_connect ---> 连接时间,从开始到建立TCP连接完成所用时间,包括前边DNS解析时间,如果需要单纯的得到连接时间,用这个time_connect时间减去前边time_namelookup时间。以下同理,不再赘述。(The time, in seconds, it took from the start until the TCP connect to the remote host (or proxy) was completed.)

time_appconnect ---> 连接建立完成时间,如SSL/SSH等建立连接或者完成三次握手时间。(The time, in seconds, it took from the start until the SSL/SSH/etc connect/handshake to the remote host was completed. (Added in 7.19.0))

time_pretransfer ---> 从开始到准备传输的时间。(The time, in seconds, it took from the start until the file transfer was just about to begin. This includes all pre-transfer commands and negotiations that are specific to the particular protocol(s) involved.)

time_redirect ---> 重定向时间,包括到最后一次传输前的几次重定向的DNS解析,连接,预传输,传输时间。(The time, in seconds, it took for all redirection steps include name lookup, connect, pretransfer and transfer before the final transaction was started. time_redirect shows the complete execution time for multiple redirections. (Added in 7.12.3))

time_starttransfer ---> 开始传输时间。在client发出请求之后,Web 服务器返回数据的第一个字节所用的时间(The time, in seconds, it took from the start until the first byte was just about to be transferred. This includes time_pretransfer and also the time the server needed to calculate the result.)

size_download ---> 下载大小。(The total amount of bytes that were downloaded.)

size_upload ---> 上传大小。(The total amount of bytes that were uploaded.)

size_header  ---> 下载的header的大小(The total amount of bytes of the downloaded headers.)

size_request ---> 请求的大小。(The total amount of bytes that were sent in the HTTP request.)

speed_download ---> 下载速度,单位-字节每秒。(The average download speed that curl measured for the complete download. Bytes per second.)

speed_upload ---> 上传速度,单位-字节每秒。(The average upload speed that curl measured for the complete upload. Bytes per second.)

content_type ---> 就是content-Type,不用多说了,这是一个访问我博客首页返回的结果示例(text/html; charset=UTF-8);(The Content-Type of the requested document, if there was any.)

num_connects ---> Number of new connects made in the recent transfer. (Added in 7.12.3)

num_redirects ---> Number of redirects that were followed in the request. (Added in 7.12.3)

redirect_url ---> When a HTTP request was made without -L to follow redirects, this variable will show the actual URL a redirect would take you to. (Added in 7.18.2)

ftp_entry_path ---> The initial path libcurl ended up in when logging on to the remote FTP server. (Added in 7.15.4)

ssl_verify_result ---> ssl认证结果,返回0表示认证成功。( The result of the SSL peer certificate verification that was requested. 0 means the verification was successful. (Added in 7.19.0))

HTTP请求过程:
image-20200102235429795-7980469.png

我们从一个Http的请求开始,先介绍下环境,左边是我们的用户端浏览器,右边是我们的Web服务器,当然Web服务器后面整体架构就不说了。

  1. DNS域名解析
  2. 请求从Clinet路由至Server,Clinet与Server建立TCP连接
  3. 如果使用了HTTPS,还涉及SSL连接的建立
  4. server开始准备数据 (开始逻辑计算、调后端接口、查数据库缓存等)
  5. server开始传递数据 (数据准备完成,开始给client传数据)
  6. 数据传输完毕

整个过程可能还涉及多次重定向

处理数据的时间去哪了?

Web访问时间大家看主要花费在哪几个方面,客户端请求,从用户端发到服务器端,服务器端响应,服务器端发回用户端,还有一个比较大的时间是处理数据的时间。
image-20200102235745105-7980665.png

我们来研究一下时间都去哪儿了,发送时间+传输时间+处理时间=响应时间发送时间=数据量比特数/带宽传输时间=传输距离/传输速度,这就是整个数据包的传输时间。

用CURL检测Clinet侧发起的HTTP请求各阶段时间,简要说明:
image-20200102235955872-7980796.png

  1. TCP建立连接的耗时:CONNECT-NAMELOOKUP
  2. 建立TCP连接到server返回client第一个字节的时间: STARTTRANSFER-CONNECT
  3. SERVER处理数据的时间:可以用STARTTRANSFER - PRETRANSFER计算得到
  4. CLIENT接收数据的耗时(开始接收至接收完成): TOTAL-STARTTRANSFER

例子:

curl -o /dev/null -v -s -w time_namelookup:"\t"%{time_namelookup}"\n"time_connect:"\t\t"%{time_connect}"\n"time_appconnect:"\t"%{time_appconnect}"\n"time_pretransfer:"\t"%{time_pretransfer}"\n"time_starttransfer:"\t"%{time_starttransfer}"\n"time_total:"\t\t"%{time_total}"\n"time_redirect:"\t\t"%{time_redirect}"\n"  https://www.fashengba.com/

image-20200103000537073-7981137.png

  1. DNS解析耗时:0.005095s
  2. TCP建立连接的耗时:0.061807 - 0.005095 = 0.056712s
  3. SSL握手完成耗时:0.216505 - 0.061807 = 0.154698s 154ms,多了一层SSL还是很耗时的
  4. server处理数据的时间:0.992029 - 0.216541 = 0.775488 775ms
  5. 总体的耗时:0.992029s
  6. 整个过程没有redirect,所以redirect的耗时为0

在举一个例子:
image-20200103001633254-7981793.png

服务器处理数据的耗时: 2.305-0.014=2.291s

这就说明server端的性能是值得研究的, 对于server端而言,有需要分析它的耗时:防火墙->负载均衡->应用->缓存和DB, 需要深入去分析这个时间消耗在哪个环节,有针对性的优化。

详细说明:

NAMELOOKUP ---> 从开始计算,域名解析完成的耗时

CURLINFO_NAMELOOKUP_TIME ---> The time it took from the start until the name resolving was completed.

CONNECT ---> 从开始计算,TCP建立完成的耗时

CURLINFO_CONNECT_TIME --> The time it took from the start until the connect to the remote host (or proxy) was completed.

APPCONNECT ---> 从开始计算,应用层(SSL,在TCP之上的应用层)连接/握手完成的耗时

CURLINFO_APPCONNECT_TIME ---> The time it took from the start until the SSL connect/handshake with the remote host was completed. (Added in in 7.19.0)

PRETRANSFER ---> 从开始计算,准备开始传输数据的耗时

CURLINFO_PRETRANSFER_TIME ---> The time it took from the start until the file transfer is just about to begin. This includes all pre-transfer commands and negotiations that are specific to the particular protocol(s) involved.

STARTTRANSFER ---> 从开始计算,开始传输数据的耗时(libcurl接收到第一个字节)

CURLINFO_STARTTRANSFER_TIME ---> The time it took from the start until the first byte is received by libcurl.

TOTAL ---> 总的耗时

CURLINFO_TOTAL_TIME ---> Total time of the previous request.

REDIRECT ---> 整个过程重定向的耗时,如果整个过程没有重定向,这个时间为0

CURLINFO_REDIRECT_TIME ---> The time it took for all redirection steps include name lookup, connect, pretransfer and transfer before final transaction was started. So, this is zero if no redirection took place.

Python也有一个pycurl模块也可以做如此工作。

参考:

https://curl.haxx.se/libcurl/c/curl_easy_getinfo.html

https://blog.51cto.com/h2ofly/1957171

https://blog.csdn.net/zt3032/article/details/80492146

https://blog.csdn.net/Dancen/article/details/84821525

http://www.greatops.net/?id=244

WeZan
Responses