zoukankan      html  css  js  c++  java
  • 双剑合璧——掌握 cURL 和 Dig 走天涯

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

     

    一起来认识 cURL

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

     

     

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

    cURL 的安装

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

    • cURL 下载中心[2]
    • Windows 安装[3]
    • Linux 安装[4]

    cURL 查看网页源码

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

    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.com
    curl -O [文件保存路径] upyun.com
    curl 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  Speed
    100   167  100   167    0     0    107      0  0:00:01  0:00:01 --:--:--   107
    mark@Mark-Li:~$ ls
    upyun.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.com
    HTTP/1.1 302 Moved Temporarily
    Date: Wed, 13 Mar 2019 05:37:57 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>

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

    从上面的例子中,我们可以看到,当我们请求  成功之后,服务器会返回一个 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=U6D59U6C5FU7701; L=U676DU5DDEU5E02; O=U676DU5DDEU7EACU97F3U667AU7F51U7EDCU6709U9650U516CU53F8; OU=U6280U672FU90E8; 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 自动跳转访问  去了。

    使用 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&image-frames=1&file_size=34675&image-width=604&message=ok&image-type=JPEG&url=%2Ftest_curl.jpg&time=1552458854&image-height=339&mimetype=image%2Fjpeg
    < x-upyun- 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 加速域名为 ,我的源站地址为 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

    例如, 开启了 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 OK
    Server: marco/2.8
    Date: Wed, 13 Mar 2019 08:39:20 GMT
    Content-Type: image/jpeg
    Content-Length: 965071
    Connection: keep-alive
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Methods: GET, PUT, OPTIONS, PATCH, DELETE, POST, HEAD
    Access-Control-Max-Age: 86400
    Access-Control-Allow-Headers: X-MARK
    X-Request-Id: e9718d0f066330f2a7c580c332492e1a; fbbbd43db05fc2fb4ba3e994c5d5eec2
    X-Source: U/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: 4083
    Via: T.81.M, V.mix-sd-dst1-082, T.75.H, M.ctn-zj-jgh1-086
    access-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] 官方文档中心: 

    [2] cURL 下载中心: 

    [3] Windows 安装: 

    [4] Linux 安装: 

    [5] 又拍云的 FORM API:

    [6] 安装文档: 

  • 相关阅读:
    NOIP提高组2004 合并果子题解
    RMQ问题之ST算法
    7.18考试
    7.18
    7.17
    7.16
    7.15
    7.14
    7.13考试
    7.13
  • 原文地址:https://www.cnblogs.com/upyun/p/11212397.html
Copyright © 2011-2022 走看看