30

双剑合璧——掌握 cURL 和 Dig 走天涯

 4 years ago
source link: https://www.tuicool.com/articles/AZrqyqe
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

如今随着大量的应用转移到网络,作为开发者,会经常做一些通讯测试,例如从网站获取信息、模拟用户向网站提交或者上传数据,查看应用通讯情况等等,现在变成了非常重要的任务。

一起来认识 cURL

cURL 是一个非常有用的工具,能够进行各种 URL 操作和数据的传输,通过它发出网络请求,然后得到和提取数据,显示在"标准输出"(stdout)上面。

IfaeayF.jpg!web

本文只关注如何进行 HTTP 请求,如果你有对 cURL 进行更深入了解的想法的话,可以使用下面的命令:curl –help 或 curl –manual,或者参阅 cURL 的官方文档中心[1]。

cURL 的安装

目前主流的操作系统都已经内置了 cURL 命令,无需额外安装。如果有需要,可以参考以下文档。

cURL 下载中心 [2]

Windows 安装[3]

Linux 安装[4]

cURL 查看网页源码

直接在 cURL 命令后加上网址,就可以看到网页源码。我们以网址 upyun.com 为例(选择该网址,主要因为它的网页代码较短):

mark@Mark-Li:~$ curl upyun.com
<html><head><title>302 Found</title></head><body bgcolor="white"><center><h1>302 Found</h1></center><hr><center>openresty/1.13.6.2</center></body></html>

默认 cURL 会把结果输出到 STDOUT,可以使用 -o,-o 或 重定向 将返回结果保存到文件中:

curl -o [文件名] upyun.comcurl -O [文件保存路径] upyun.comcurl upyun.com > upyun.html
mark@Mark-Li:~$ curl -o upyun.html upyun.com  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                 Dload  Upload   Total   Spent    Left  Speed100   167  100   167    0     0    107      0  0:00:01  0:00:01 --:--:--   107mark@Mark-Li:~$ lsupyun.html

HTTP 协议

HTTP 协议 用于从 WEB 服务器上读取数据,它是基于 TCP/IP 协议上的一个简单的协议。该协议同时也能够让你通过使用一些不同的方法向服务器提交数据。

HTTP 协议是向服务器发送的要进行一个特殊操作的 ACSII 文本,随后在要求的内容发送给客户端之前,服务器会向客户端发送几行回应的数据。

客户端 cURL 向服务器发送一项请求,请求通常包括 方法(比如 GET、POST、HEAD 等等)、一些 请求头、有时还有 请求正文。接到请求后,服务器返回 状态行(表明访回是否顺利)、响应头 和 内容正文。正文是客户要求的数据,通常是一些 HTML 资源、图片等等。

对 HTTP 还不够了解?可参考 HTTP 协议讲解 这篇文章。

使用 cURL 观察 HTTP 协议

使用 cURL 的参数 -v,–verbose,会显示出 cURL 向服务器发送的命令和其它的一些信息。–verbose 是一个非常有用的命令,尤其是当你想调试或者了解 cURL 和服务器交互过程的时候。

curl –v upyun.com

随后我们就可以观察服务器返回的结果:

mark@Mark-Li:~$ curl -v upyun.com* Rebuilt URL to: upyun.com/*   Trying 115.231.97.2...* TCP_NODELAY set* Connected to upyun.com (115.231.97.2) port 80 (#0)> GET / HTTP/1.1> Host: upyun.com> User-Agent: curl/7.58.0> Accept: */*>< HTTP/1.1 302 Moved Temporarily< Date: Wed, 13 Mar 2019 05:28:53 GMT< Content-Type: text/html< Content-Length: 167< Connection: keep-alive< Location: https://www.upyun.com/<<html><head><title>302 Found</title></head><body bgcolor="white"><center><h1>302 Found</h1></center><hr><center>openresty/1.13.6.2</center></body></html>* Connection #0 to host upyun.com left intact

从输出结果我们可以看到,cURL 命令发起请求所使用的请求方法、请求资源、请求协议版本以及一些请求头。服务器接收到请求后则返回状态码、一些响应头以及网页正文。

如果我们只需要服务器的响应信息的话,可以使用 -i、--include 命令。

curl –i upyun.com
mark@Mark-Li:~$ curl -i upyun.comHTTP/1.1 302 Moved TemporarilyDate: Wed, 13 Mar 2019 05:37:57 GMTContent-Type: text/htmlContent-Length: 167Connection: keep-aliveLocation: https://www.upyun.com/
<html><head><title>302 Found</title></head><body bgcolor="white"><center><h1>302 Found</h1></center><hr><center>openresty/1.13.6.2</center></body></html>

如果你觉得上面的信息还不够,那么下面的命令可以查看更详细的通信过程。curl --trace [结果输出保存文件名] upyun.com

从上面的例子中,我们可以看到,当我们请求 upyun.com 成功之后,服务器会返回一个 302 跳转码,并在响应头中通过 Location 告诉访问者应该跳转到哪里去。

cURL 提供了重定向跟随的功能,通过 -L 参数就可以响应服务器返回的跳转指令了。

curl –L upyun.com
mark@Mark-Li:~$ curl -v upyun.com -Lo /dev/null* Rebuilt URL to: upyun.com/  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                 Dload  Upload   Total   Spent    Left  Speed  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 115.231.97.2...* TCP_NODELAY set  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0* Connected to upyun.com (115.231.97.2) port 80 (#0)> GET / HTTP/1.1> Host: upyun.com> User-Agent: curl/7.58.0> Accept: */*>< HTTP/1.1 302 Moved Temporarily< Date: Wed, 13 Mar 2019 06:00:50 GMT< Content-Type: text/html< Content-Length: 167< Connection: keep-alive< Location: https://www.upyun.com/<* Ignoring the response-body{ [167 bytes data]100   167  100   167    0     0    104      0  0:00:01  0:00:01 --:--:--   104* Connection #0 to host upyun.com left intact* Issue another request to this URL: 'https://www.upyun.com/'*   Trying 115.231.97.2...* TCP_NODELAY set  0     0    0     0    0     0      0      0 --:--:--  0:00:02 --:--:--     0* Connected to www.upyun.com (115.231.97.2) port 443 (#1)* ALPN, offering h2* ALPN, offering http/1.1* successfully set certificate verify locations:*   CAfile: /etc/ssl/certs/ca-certificates.crt  CApath: /etc/ssl/certs} [5 bytes data]* TLSv1.2 (OUT), TLS handshake, Client hello (1):} [211 bytes data]* TLSv1.2 (IN), TLS handshake, Server hello (2):{ [104 bytes data]* TLSv1.2 (IN), TLS handshake, Certificate (11):{ [2751 bytes data]* TLSv1.2 (IN), TLS handshake, Server key exchange (12):{ [333 bytes data]* TLSv1.2 (IN), TLS handshake, Server finished (14):{ [4 bytes data]* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):} [70 bytes data]* TLSv1.2 (OUT), TLS change cipher, Client hello (1):} [1 bytes data]* TLSv1.2 (OUT), TLS handshake, Finished (20):} [16 bytes data]* TLSv1.2 (IN), TLS handshake, Finished (20):{ [16 bytes data]* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256* ALPN, server accepted to use http/1.1* Server certificate:*  subject: C=CN; ST=\U6D59\U6C5F\U7701; L=\U676D\U5DDE\U5E02; O=\U676D\U5DDE\U7EAC\U97F3\U667A\U7F51\U7EDC\U6709\U9650\U516C\U53F8; OU=\U6280\U672F\U90E8; CN=*.upyun.com*  start date: Feb 15 00:00:00 2019 GMT*  expire date: Apr 15 12:00:00 2020 GMT*  subjectAltName: host "www.upyun.com" matched cert's "*.upyun.com"*  issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=GeoTrust RSA CA 2018*  SSL certificate verify ok.} [5 bytes data]> GET / HTTP/1.1> Host: www.upyun.com> User-Agent: curl/7.58.0> Accept: */*>{ [5 bytes data]< HTTP/1.1 200 OK< Content-Type: text/html; charset=utf-8< Content-Length: 225608< Connection: keep-alive< Vary: Accept-Encoding< Server: openresty/1.13.6.2< Date: Wed, 13 Mar 2019 06:00:51 GMT< X-DNS-Prefetch-Control: off< X-Frame-Options: SAMEORIGIN< X-Download-Options: noopen< X-Content-Type-Options: nosniff< X-XSS-Protection: 1; mode=block< ETag: W/"37148-Mygdw8NXtImEEqWHGE0/u6E0RM8"< Vary: Accept-Encoding< X-Kong-Upstream-Latency: 152< X-Kong-Proxy-Latency: 1<{ [15914 bytes data]100  220k  100  220k    0     0  76841      0  0:00:02  0:00:02 --:--:--  692k* Connection #1 to host www.upyun.com left intact

可以看到 cURL 自动跳转访问  https://www.upyun.com/  去了。

使用 cURL 向服务器发送数据

向服务器提交数据的方法有两种:GET 和 POST 两种方法。

GET 方式比较简单,需要传递的参数直接在 URL 地址中进行传递即可。

例如,向百度提交搜索 curl 的任务,cURL 命令就可以这么发送:

curl -vo /dev/null http://www.baidu.com/s?wd=curl

其中 wd 就是百度服务器接收搜索关键字的参数名。

POST 方法必须把数据和网址分开,我们就需要使用 -X 参数来指定请求方法,-F 参数来传递表单数据。

例如,我想通过又拍云的 FROM API,向自己的存储空间上传一张图片。cURL 命令就可以这么写:

curl -X POST \  http://v0.api.upyun.com/iamge-blog \  -H 'Date: Wed, 13 Mar 2019 06:21:31 GMT' \  -F 'authorization=UPYUN mark:aIa6b0qwnHCffK0NxqPG0U2uBMg=' \  -F policy=eyJidWNrZXQiOiJpYW1nZS1ibG9nIiwic2F2ZS1rZXkiOiIvdGVzdF9jdXJsLmpwZyIsImV4cGlyYXRpb24iOiIxNTYwNDA2ODkyIiwiZGF0ZSI6IldlZCwgMTMgTWFyIDIwMTkgMDY6MjE6MzEgR01UIiwicmV0dXJuLXVybCI6Imh0dHBzOi8vaG9va3MudXB5dW4uY29tL1Nrd0xaN0x2TiJ9 \  -F 'file=@/home/mark/duck.jpg'
Note: Unnecessary use of -X or --request, POST is already inferred.*   Trying 58.222.52.249...* TCP_NODELAY set* Connected to v0.api.upyun.com (58.222.52.249) port 80 (#0)> POST /iamge-blog HTTP/1.1> Host: v0.api.upyun.com> User-Agent: curl/7.58.0> Accept: */*> Date: Wed, 13 Mar 2019 06:21:31 GMT> Content-Length: 35317> Content-Type: multipart/form-data; boundary=------------------------a38355798f264d25> Expect: 100-continue>< HTTP/1.1 100 Continue< HTTP/1.1 302 Moved Temporarily< Server: marco/2.8< Content-Type: text/html< Connection: keep-alive< X-Request-Id: d6046ac4c1834027d5ddba6becd020e1< Date: Wed, 13 Mar 2019 06:34:14 GMT< x-upyun-height: 339< Content-Length: 157< X-Request-Path: 403-zj-fud-209< Location: https://hooks.upyun.com/SkwLZ7LvN?code=200ℑ-frames=1&file_size=34675ℑ-width=604&message=okℑ-type=JPEG&url=%2Ftest_curl.jpg&time=1552458854ℑ-height=339&mimetype=image%2Fjpeg< x-upyun-width: 604< Access-Control-Allow-Origin: *< x-upyun-frames: 1* HTTP error before end of send, stop sending

又拍云的 FORM API 上传可 参阅 [5]。

使用 cURL 测试代理访问

使用 CDN 有时候会发现请求异常,为了确定是 CDN 平台的故障还是源站出现了问题,我们就需要依次来排查。cURL 工具可以使用 -x 参数来指定代理主机端口来访问。

curl -x [protocol://]host[:port] url

例如,我的 CDN 加速域名为 test.mark.com,我的源站地址为 1.2.4.8,服务端口为 8080,那么就可以通过 cURL 直接来测试源站响应。

mark@Mark-Li:~$ curl -vo /dev/null test.mark.com -x 1.2.4.8:8080* Rebuilt URL to: test.mark.com/*   Trying 1.2.4.8...* TCP_NODELAY set  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                 Dload  Upload   Total   Spent    Left  Speed  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 1.2.4.8 (1.2.4.8) port 8080 (#0)> GET http://test.mark.com/ HTTP/1.1> Host: test.mark.com> User-Agent: curl/7.58.0> Accept: */*> Proxy-Connection: Keep-Alive>< HTTP/1.1 200 OK< Server: nginx/1.12.1< Date: Wed, 13 Mar 2019 08:14:26 GMT< Content-Type: text/html< Content-Length: 12569< Last-Modified: Wed, 13 Mar 2019 07:05:56 GMT< Connection: keep-alive< ETag: "5c88abd4-3119"< Accept-Ranges: bytes<{ [12569 bytes data]100 12569  100 12569    0     0   211k      0 --:--:-- --:--:-- --:--:--  223k* Connection #0 to host 1.2.4.8 left intact

这样的话,我们就绕过了 CDN 层,直接去访问源站获取信息了。

使用 cURL 增加或修改请求头

有的时候需要测试网站设置的防盗链有无生效,例如判断 Referer 头、UA 标志或需要携带自定义的请求头,就可以通过 -H 这个参数来实现。

curl -H header:value

例如,test.mark.com 开启了 Referer 防盗链,我们现在需要测试防盗链是否生效,就可以这么发送命令:

mark@Mark-Li:~$ curl -vo /dev/null http://test.mark.com/a/meta.jpg -H "Referer:www.baidu.com"  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                 Dload  Upload   Total   Spent    Left  Speed  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 183.131.200.86...* TCP_NODELAY set* Connected to test.mark.com (183.131.200.86) port 80 (#0)> GET /a/meta.jpg HTTP/1.1> Host: test.mark.com> User-Agent: curl/7.58.0> Accept: */*> Referer:www.baidu.com>< HTTP/1.1 200 OK< Server: marco/2.8< Date: Wed, 13 Mar 2019 08:35:26 GMT< Content-Type: image/jpeg< Content-Length: 965071< Connection: keep-alive< X-Request-Id: e9718d0f066330f2a7c580c332492e1a; db9beca89abeb7dfd848d0cee9540dcb< X-Source: C/200< X-Upyun-Content-Length: 965071< Last-Modified: Thu, 29 Nov 2018 03:13:12 GMT< X-Upyun-Content-Type: image/jpeg< ETag: "ec185b942ad06c895935fd75e44076f3"< Expires: Thu, 21 Mar 2019 07:31:17 GMT< Cache-Control: max-age=691200< Accept-Ranges: bytes< Age: 3849< Via: T.81.M, V.mix-sd-dst1-082, T.75.H, M.ctn-zj-jgh1-086<{ [86016 bytes data]100  942k  100  942k    0     0  2692k      0 --:--:-- --:--:-- --:--:-- 2692k* Connection #0 to host test.mark.com left intact

测试跨域请求:

mark@Mark-Li:~$ curl -i http://iamge-blog.test.upcdn.net/a/meta.jpg -H "Origin:www.baidu.com"HTTP/1.1 200 OKServer: marco/2.8Date: Wed, 13 Mar 2019 08:39:20 GMTContent-Type: image/jpegContent-Length: 965071Connection: keep-aliveAccess-Control-Allow-Origin: *Access-Control-Allow-Methods: GET, PUT, OPTIONS, PATCH, DELETE, POST, HEADAccess-Control-Max-Age: 86400Access-Control-Allow-Headers: X-MARKX-Request-Id: e9718d0f066330f2a7c580c332492e1a; fbbbd43db05fc2fb4ba3e994c5d5eec2X-Source: U/200X-Upyun-Content-Length: 965071Last-Modified: Thu, 29 Nov 2018 03:13:12 GMTX-Upyun-Content-Type: image/jpegETag: "ec185b942ad06c895935fd75e44076f3"Expires: Thu, 21 Mar 2019 07:31:17 GMTCache-Control: max-age=691200Accept-Ranges: bytesAge: 4083Via: T.81.M, V.mix-sd-dst1-082, T.75.H, M.ctn-zj-jgh1-086access-control-allow-credentials: true

以上就是 cURL 命令工具行的一些常用命令。

接下来我们再来介绍一位网络测试老大哥,dig。

优秀辅助手 DIG

Dig 是 Linux 中的域名解析工具,功能比 Windows 平台上的nslookup 强很多,使用也很方便,Dig 是 Domain Information Groper 的缩写,知道了来源想必大家也就容易记住这条命令了。

Dig 配置

Dig 预装在所有 Linux 发行版和 MacOS 系统中,目前也有大神将 Dig 移植到了 Wndows 平台。大家可以参考这篇安装文档[6]来进行操作。

Dig 调用

一个典型的 dig 调用类似:

dig @server name type

其中:server 待查询名称服务器的名称或 IP 地址,一般指定为 DNS 服务器 name 将要查询的资源记录的名称 type 显示所需的查询类型 - ANY、A、TXT、MX、SIG,以及任何有效查询类型等。如果不提供任何类型参数,dig 将对记录 A 执行查询。

查询 DNS 配置信息

mark@Mark-Li:~$ dig -t NS .

查询域名对应 IP

mark@Mark-Li:~$ dig www.baidu.com

指定 DNS 服务器进行查询

mark@Mark-Li:~$ dig www.baidu.com @9.9.9.9

指定查询 TYPE

例如申请证书的时候,需要在域名解析的地方添加 TXT 记录,这时候就可以通过 dig 来查询。

dig txt test.mark.com
mark@Mark-Li:~$ dig txt test.mark.com
; <<>> DiG 9.11.3-1ubuntu1.1-Ubuntu <<>> txt test.mark.com;; global options: +cmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39566;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:; EDNS: version: 0, flags:; udp: 4096;; QUESTION SECTION:;test.mark.com. IN TXT
;; ANSWER SECTION:test.mark.com. 1780 IN TXT "2019031100000065jk97bbbpuq25wlofojds65ldv7w186idsq00ju"
;; Query time: 1 msec;; SERVER: 10.0.6.30#53(10.0.6.30);; WHEN: Wed Mar 13 17:45:03 DST 2019;; MSG SIZE rcvd: 121

[1] 官方文档中心:  https://curl.haxx.se/docs/

[2] cURL 下载中心:  https://curl.haxx.se/download.html

[3] Windows 安装:  https://blog.51cto.com/9410445/1763891

[4] Linux 安装:  https://blog.csdn.net/ivan_ljf/article/details/53966655

[5]  又拍云的 FORM API: https://help.upyun.com/knowledge-base/form_api/

[6] 安装文档:  https://blog.51cto.com/5001660/2152132


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK