目录

眼熟 HTTP 协议

它位于 TCP/IP 第四层应用层的协议,HTTP 主要有请求报文、响应报文两种。

HTTP 是无状态(stateless)协议,是说他不像 TCP 一样建立长久连接,而是一来一回后,下次访问还是建立新的请求或响应。

如果用户在登录后,它就那么一刷新不得又得重新登录。照这么一看还挺麻烦,我们的 HTTP 不提供持久状态后来引用cookie这个技术,你登陆后服务器会向你返一个字段 set-cookie ,下次发送请求就会把 set-cookie 的值追加到现有cookie后面,这样程序就能识别用户状态。

cookie 是用户登录的凭证,服务器只认 cookie 不认人。如果盗取了管理员 cookie 就相当于拥有直接操作权限,不用输入密码了直接操作你的账户。

这个 cookie 一般保存在客户端,是一个文本文件。

由于cookie安全性问题现在 Web 应用都采用 session,与 cookie 区别在于存储位置不同,cookie 存在本地 session 存在服务器,用户登录后 session 产生一串随机 id 值,在响应包中写上 set-cookie 字段作为它的值进行返回,客户端收到后将 id 值写入 cookie 文件到本地。

在 HTTP 1.0 中没有持久连接的能力,意思是访问一个网页时有多个请求就会先建立 TCP 三次握手、发送 HTTP 请求、响应请求、断开 TCP 连接;周而复始的重复在现在这样效率蛮低的,因为建立连接需要一定时间。

HTTP 1.1 中提供了一个持久连接的字段 Keep-Alive,双方建立 TCP 连接后只要任意一方不断开就会保持连接状态,但此时传输数据还是一个请求一个响应。不过现在的传输是管线化(并行传输数据),用户可以不用等收到响应内容再去发请求,可一次发送多个请求服务器收到一个就响应一个,这样效率大大提高不少。

什么是 URL

URL 中文是统一资源定位符,是由 Uniform Resource Locator 缩写而来的。

URL 有一个标准格式,由协议、地址、端口、地址路径、发送数据、锚点(fragment)几个内容组成。

URL.png

关于 URI 与 URL 的区别

这个问题让我困扰不少时间,不过有人已经写的挺不错啦,这里就不浪费地方写了。

总结 URI 与 URL:一个 URL 应该是路径,URN 是资源的名字,URI=URL+URN,只要一个资源能够被唯一标识那么它就是 URI。

用户如何访问站点的

用户通过浏览器访问 www 域名浏览器发送请求给 DNS 服务器,此时 DNS 返回一个解析后的域名(正向查找),也就是 IP 啦,通过 IP 找到服务器,Web 容器会查看浏览器发送的 HTTP 请求数据包中资源名字,来确定请求内容,如果有涉及到数据库查询(用户登录等等),则与数据库先进行查询,查询后将结果返回服务器,服务器会把请求的页面返回给浏览器,浏览器通过解析返回的 HTTP 包中的 Content,来呈现一个炫丽的页面。

待补充:DNS 缓存和 TCP 三次握手

请求报文

请求行、请求头、空行(空行前面都是响应头)、请求内容。

GET http://www.relived.net/ HTTP/1.1 #请求方法、请求路径、用的协议(请求行)
Host: www.relived.net #你请求的目标主机  请求头
Connection: keep-alive #持久连接
Cache-Control: max-age=0 #缓存控制,眼熟就行。
Upgrade-Insecure-Requests: 1 #不知道。。。
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0 #浏览器标识
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 #请你优先返回我可以处理的文件
Accept-Encoding: gzip, deflate, sdch #采用什么算法来编码内容
Accept-Language: zh-CN,zh;q=0.8 #使用什么语言

#请求内容

关于上面的报文意思,在下面的表中都有解释。

HTTP1.1请求方法 解释
GET 获取资源。我们通常在浏览器地址栏里看到的就是GET请求。
POST 传输实体主体,比较常见的有表单发送数据。
PUT 传输文件
HEAD 获取报文头部
DELETE 删除文件
OPTIONS 向服务器询问支持什么方法
... ...

请求有 GET、POST 等等,这是打交道最多的两种。

请求头内的首部字段表,这个表有些内容很复杂需要掌握加粗的内容。

字段名 说明
Accept 客户端可处理的类型文件。
值:text/html;q=0.9,image/webp;q=0.8
q代表权值最大1优先返回权值高的类型,用分号分隔。
Accept-Charset 客户端可处理的字符集。值:也有q来表示优先级与Accept一致不写了。
Accept-Encoding 客户端可支持的内容编码。值:gzip,compress,deflate,identity(不压缩)。可用*表示任意编码格式,也用q调整优先级。
Accept-Language 优先使用的语言。值:zh-cn,zh;q=0.7,en-us,en;q=0.3
也用q表示优先级。
Authorization Web认证信息。
Expect 期待服务器的特定行为。仅做了解
From 用户的电子邮箱地址
Host 请求资源所在服务器(你请求的那个地址IP或域名)
If-Match 比较实体标记(ETag)。If-xxx是条件请求只有服务器判断为真时才执行请求,服务器判断请求的ETage值与服务器是否一致,不一致范围 412 P热conditionFailed,一致则接受请求
If-Modified-Since 比较资源的更新时间。用于判断资源是否更新,服务器将这个值与自己文件的值进行比对如果服务器更新了,就处理这个请求将文件返回过去,否则返回304 Not Modified
If-None-Match 比较实体标记(与If-Match相反),当ETag不一致时处理请求。
If-Range 资源未更新时发送实体Byte的范围请求,仅做了解。
If-Unmodified-Since 比较资源的更新时间(与If-Modified-Since相反),仅做了解。
Max-Forwards 最大传输逐跳数,仅做了解。
Proxy-Authorization 代理服务器要求客户端的认证信息,仅做了解。
Range 实体的字节范围请求(请求数据的范围),获取指定范围的数据。
Referer 对请求中URI的原始获取方,是从哪个页面发起的请求,有些写程序的依照这个数据进行限制登录,别忘了包可以修改。这个字段的应写做Referrer,由于错误一直延续至今。
TE 传输编码的优先级,仅做了解
User-Agent HTTP客户端浏览器程序信息(你用的什么浏览器)
Cookie 客户端返回给服务器证明用户状态的信息(头:值;成对出现)
DNT(非标RFC定义的字段) 拒绝个人信息被收集(Do Not Track)主要针避免广告追踪。值:0同意,1拒绝。

响应报文

响应行、响应头、空行(空行前面都是响应头)、内容

HTTP/1.1 200 OK #状态行(协议 状态码 对状态码的解释)
Date: Sat, 19 May 2018 07:34:24 GMT #响应报文的时间
Server: Apache #服务器信息
X-Frame-Options: SAMEORIGIN #预防点击劫持
Vary: Accept-Encoding #缓存管理信息
Content-Length: 12237 #响应内容的字节
Keep-Alive: timeout=5, max=100 # 5秒内没请求就关闭连接,最多请求100次每请求一次-1为0就断开连接
Connection: Keep-Alive #持久连接
Content-Type: text/html; charset=UTF-8 #内容什么类型的数据采用什么编码

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="x-dns-prefetch-control" .............................................

响应头内的首部字段表,这个表有些内容很复杂,需要掌握加粗的内容。

字段名 说明
Accept-Ranges 是否接受自检范围请求
Age 推算资源创建经过时间
ETag 资源匹配信息
Location 将用户重定向到指定的URI(3xx重定向)
Proxy-Authenticate 代理服务器对客户端的认证信息
Retry-After 对再次发起请求的时机要求
Server HTTP服务器的安装信息(Web服务器的名称,这个在服务端可修改。)
Vary 代理服务器缓存的管理信息
WWW-Authenticate 服务器对客户端的认证信息
X-Frame-Options(非标RFC定义的字段) 主要终于防止点击劫持(clickjacking)。值:SAMEORIGIN仅同域名的frame才可加载该链接,DENY拒绝。这个首部字段IE8以下不支持,主流浏览器都支持。
X-XSS-Protection(非标RFC定义的字段) 用于控制浏览器过滤XSS。值:1过滤,0不过滤。
P3P(非标RFC定义的字段) 用于将网站网的个人隐私转换成程序能懂的格式

在HTTP等多种协议中给加前缀X-来标识非标准字段已经被RFC 6648废除。

还有一些不在 RFC 文档内定义的首部字段如:set-Cookie 是服务器发给客户端(响应字段),cookie 是客户端向服务器发送(请求字段)

Set-Cookie: BDRCVFR[x4e6higC8W6]=mk3SLVN4HKm; path=/; domain=.baidu.com
cookie字段 说明
name=value 键值成对出现,用分号分隔。
expires=data cookie过期时间,不指定关闭浏览器就过期
path=path 限制cookie的作用范围
domain=domain 适用这个cookie的域名,不指定就默认当前域名
Secure 在HTTPS通信是才发送cookie
HttpOnly 让cookie不能被JavaScript读取到(防XSS)

响应状态码

分为五大类,有 50 多个具体响应码。

响应状态码 解释
1xx(Informational) 服务器响应的信息,通常表示服务器还有后续处理,很少出现
2xx(Success) 请求被服务器成功接收冰处理后返回的响应结果
3xx(Redirection) 重定向,通常在身份认证成功后重定向到一个安全页面(301永久重定向/302临时重定向)
4xx(Client Error) 表示客户端请求错误
5xx(Server Error) 服务器内部错误(503:服务不可用)

下面介绍常见的几种状态码:

  • 200,表示请求已成功处理,会根据请求方法的不同返回数据,GET会返回请求资源的实体(实体包含实体首部与实体主体,分别代表的是数据首部与数据),HEAD会返回实体首部没有实体主体。
  • 204(No Content),请求成功处理,但没有任何数据返回。
  • 206(Partial Content),请求部分内容,返回指定范围内的数据Content-Range:xxx。
  • 301(Moved Permanently),将这个页面永久重定向到另外的地方。
  • 302(Found),临时重定向,比如身份验证成功重定向到另一个页面。
  • 400(Bad Request),请求报文有语法错误
  • 401(Unauthorized),需要身份验证
  • 403(Forbidden),禁止访问,请求被拒绝了
  • 404(Not Found),目标未发现未访问到这个资源,服务器在拒绝你的请求也可能使用这个状态码。
  • 500(Internal Server Error),服务器出问题啦
  • 503(Service Unavailable),或许是负载过大无法处理这个请求,也有可能是服务器拒绝请求。

通用首部字段表(请求与响应都会使用)。

字段名 说明
Cache-Control 控制缓存的行为
Date 创建报文的日期时间。值:Sat, 19 May 2018 07:34:24 GMT。有时返回的格式不同日期显示的是格林威治时间
Pragma 报文指令。值:no-cache不返回缓存资源,仅做了解。
Connection 逐跳首部、连接的管理。值:close(响应断开)、Keey-Alive(长期保持连接直到任何一断开)
Trailer 报文末端的首部一览。值:Expires,在报文尾部有字段信息。
Transfer-Encoding 制定报文主体的传输编码方式(仅对分块传输编码有效)。值:chunked使用块编码,仅做了解
Upgrade 升级为其他协议。仅做了解
Via 代理服务器的相关信息。仅做了解
Warning 错误通知。仅做了解

实体首部字段(请求与响应都会使用)。

字段名 说明
Allow 可支持的HTTP方法。值:GET,HEAD
Content-Encoding 实体主体的编码方式,在不丢失实体内容的情况下进行。
Content-Language 实体主体的自然语言(zh-CN)
Content-Length 实体主体的大小(单位:字节)
如果用于爆破,失败的字节基本不变,成功会返回正常页面字节有大变化。
此字段在请求中的意义是告诉 WebServer 传输数据长度,WebServer 会依照此长度来读取数据。
Content-Location 代替对映体资源的URI
Content-MD5 实体主体的报文摘要
Content-Range 实体主体的位置范围(单位:字节)
Content-Type 实体主体的数据类型
Expires 实体主体过期的日期时间
Last-Modified 资源的最后修改日期

发送 HTTP 请求

curl

-v/--verbose

查看整个请求响应。

C:\Users\gbb>curl -v example.com
*   Trying 93.184.216.34:80...
* Connected to example.com (93.184.216.34) port 80 (#0)
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Age: 357555
< Cache-Control: max-age=604800
< Content-Type: text/html; charset=UTF-8
< Date: Mon, 20 Jun 2022 01:41:06 GMT
< Etag: "3147526947+ident"
< Expires: Mon, 27 Jun 2022 01:41:06 GMT
< Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
< Server: ECS (sab/5693)
< Vary: Accept-Encoding
< X-Cache: HIT
< Content-Length: 1256
<
<!doctype html>
<html>
......
* Connection #0 to host example.com left intac

-I/--head

使用 HEAD 方法发送请求。

C:\Users\gbb>curl -I example.com
HTTP/1.1 200 OK
Accept-Ranges: bytes
Age: 549439
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Mon, 20 Jun 2022 01:42:10 GMT
Etag: "3147526947"
Expires: Mon, 27 Jun 2022 01:42:10 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Server: ECS (sab/5708)
X-Cache: HIT
Content-Length: 1256

C:\Users\gbb>curl -Iv example.com
*   Trying 93.184.216.34:80...
* Connected to example.com (93.184.216.34) port 80 (#0)
> HEAD / HTTP/1.1
> Host: example.com
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Accept-Ranges: bytes
Accept-Ranges: bytes
< Age: 126757
Age: 126757
< Cache-Control: max-age=604800
Cache-Control: max-age=604800
< Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8
< Date: Wed, 22 Jun 2022 02:16:25 GMT
Date: Wed, 22 Jun 2022 02:16:25 GMT
< Etag: "3147526947"
Etag: "3147526947"
< Expires: Wed, 29 Jun 2022 02:16:25 GMT
Expires: Wed, 29 Jun 2022 02:16:25 GMT
< Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
< Server: ECS (sab/5750)
Server: ECS (sab/5750)
< X-Cache: HIT
X-Cache: HIT
< Content-Length: 1256
Content-Length: 1256

<
* Connection #0 to host example.com left intact

-i/--include

响应内容中包含响应头。

C:\Users\gbb>curl -i example.com
HTTP/1.1 200 OK
Age: 556342
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Wed, 22 Jun 2022 02:20:52 GMT
Etag: "3147526947+ident"
Expires: Wed, 29 Jun 2022 02:20:52 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Server: ECS (sab/572D)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1256

<!doctype html>
<html>
......

--basic

Basic 认证,-u/--user 指定账户,用户名和密码用冒号分隔。

C:\Users\gbb>curl -v --basic -u admin:public http://example.com:18083/api/v4/
*   Trying 1.1.1.1:18083...
* Connected to example.com (1.1.1.1) port 18083 (#0)
* Server auth using Basic with user 'admin'
> GET /api/v4/ HTTP/1.1
> Host: example.com:18083
> Authorization: Basic YWRtaW46cHVibGlj
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-length: 12247
< content-type: application/json
< date: Wed, 22 Jun 2022 02:18:35 GMT
< server: Cowboy
<
{"data":[{"path":"/auth_clientid","name":"list_clientid","method":"GET","descr":"List available clientid in the cluster"}......
* Connection #0 to host example.com left intact

-A/--user-agent

默认 UA 是 curl 版本信息 curl/x.xx.x,使用 -A 可以更改。

C:\Users\gbb>curl -v -A "Pentester" example.com
*   Trying 93.184.216.34:80...
* Connected to example.com (93.184.216.34) port 80 (#0)
> GET / HTTP/1.1
> Host: example.com
> User-Agent: Pentester
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Age: 556591
< Cache-Control: max-age=604800
< Content-Type: text/html; charset=UTF-8
< Date: Wed, 22 Jun 2022 02:25:01 GMT
< Etag: "3147526947+ident"
< Expires: Wed, 29 Jun 2022 02:25:01 GMT
< Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
< Server: ECS (sab/572B)
< Vary: Accept-Encoding
< X-Cache: HIT
< Content-Length: 1256
<
<!doctype html>
<html>
......

设置 Cookie。

C:\Users\gbb>curl -vb "key=value" example.com
*   Trying 93.184.216.34:80...
* Connected to example.com (93.184.216.34) port 80 (#0)
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/7.79.1
> Accept: */*
> Cookie: key=value
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Age: 517712
< Cache-Control: max-age=604800
< Content-Type: text/html; charset=UTF-8
< Date: Wed, 22 Jun 2022 02:49:49 GMT
< Etag: "3147526947+gzip+ident"
< Expires: Wed, 29 Jun 2022 02:49:49 GMT
< Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
< Server: ECS (sab/56A8)
< Vary: Accept-Encoding
< X-Cache: HIT
< Content-Length: 1256
<
<!doctype html>
<html>
......

-H/--header

重写或新增现有 Header。

C:\Users\gbb>curl -v -H "CustomHeader: value" -H "UserAgent: test" example.com
*   Trying 93.184.216.34:80...
* Connected to example.com (93.184.216.34) port 80 (#0)
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/7.79.1
> Accept: */*
> CustomHeader: value
> UserAgent: test
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Age: 263239
< Cache-Control: max-age=604800
< Content-Type: text/html; charset=UTF-8
< Date: Wed, 22 Jun 2022 03:08:57 GMT
< Etag: "3147526947"
< Expires: Wed, 29 Jun 2022 03:08:57 GMT
< Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
< Server: ECS (sab/56BC)
< Vary: Accept-Encoding
< X-Cache: HIT
< Content-Length: 1256
<
<!doctype html>
<html>
......

-d/--data

CURL 默认是 GET 请求,-d 选项可以指定 POST 参数模拟表单(Content-Type: application/x-www-form-urlencoded)发送 POST 请求,参数使用 & 符号做分隔。

C:\Users\gbb>curl -v -d "key=value" -d "key1=value1" example.com -x 127.0.0.1:8080
*   Trying 127.0.0.1:8080...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> POST http://example.com/ HTTP/1.1
> Host: example.com
> User-Agent: curl/7.79.1
> Accept: */*
> Proxy-Connection: Keep-Alive
> Content-Length: 21
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Cache-Control: max-age=604800
< Content-Type: text/html; charset=UTF-8
< Date: Wed, 22 Jun 2022 03:28:46 GMT
< Etag: "3147526947"
< Expires: Wed, 29 Jun 2022 03:28:46 GMT
< Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
< Server: EOS (vny/0452)
< Content-Length: 1256
< Connection: close
<
<!doctype html>
<html>
......

传递 JSON 需要将 Content-Type 改为 application/json 避免后端不识别。

C:\Users\gbb> curl -v -H "Content-Type: application/json" -d '{"key":1,"key2":"value 1"}' example.com

但 Windows 中这样些就不好使,如果数据中包含空格要将 JSON 放入文件中发送。

C:\Users\gbb> curl -v -H "Content-Type: application/json" -d @desktop/data.txt example.com

所有数据不包含空格,要将双引号转义这样 Key 的双引号才能被当作字符串,Windows 下最好的方式还是通过文件发送。

C:\Users\gbb> curl -v -H "Content-Type: application/json" -d {\"key\":1,\"key2\":\"value1\"} example.com

在发送数据过程中 -v 不能展示包体数据,可以用 --trace ---trace-ascii - 得到整个请求与响应,Send data 部分就是数据。

C:\Users\gbb>curl -v -H "Content-Type: application/json" --trace - -d {\"key\":1,\"key2\":\"value1\"} example.com
Warning: --trace overrides an earlier trace/verbose option
== Info:   Trying 93.184.216.34:80...
== Info: Connected to example.com (93.184.216.34) port 80 (#0)
=> Send header, 128 bytes (0x80)
0000: 50 4f 53 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d POST / HTTP/1.1.
0010: 0a 48 6f 73 74 3a 20 65 78 61 6d 70 6c 65 2e 63 .Host: example.c
0020: 6f 6d 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 om..User-Agent:
0030: 63 75 72 6c 2f 37 2e 37 39 2e 31 0d 0a 41 63 63 curl/7.79.1..Acc
0040: 65 70 74 3a 20 2a 2f 2a 0d 0a 43 6f 6e 74 65 6e ept: */*..Conten
0050: 74 2d 54 79 70 65 3a 20 61 70 70 6c 69 63 61 74 t-Type: applicat
0060: 69 6f 6e 2f 6a 73 6f 6e 0d 0a 43 6f 6e 74 65 6e ion/json..Conten
0070: 74 2d 4c 65 6e 67 74 68 3a 20 32 35 0d 0a 0d 0a t-Length: 25....
=> Send data, 25 bytes (0x19)
0000: 7b 22 6b 65 79 22 3a 31 2c 22 6b 65 79 32 22 3a {"key":1,"key2":
0010: 22 76 61 6c 75 65 31 22 7d                      "value1"}
......

C:\Users\gbb>curl -v -H "Content-Type: application/json" --trace-ascii - -d {\"key\":1,\"key2\":\"value1\"} example.com
Warning: --trace-ascii overrides an earlier trace/verbose option
== Info:   Trying 93.184.216.34:80...
== Info: Connected to example.com (93.184.216.34) port 80 (#0)
=> Send header, 128 bytes (0x80)
0000: POST / HTTP/1.1
0011: Host: example.com
0024: User-Agent: curl/7.79.1
003d: Accept: */*
004a: Content-Type: application/json
006a: Content-Length: 25
007e:
=> Send data, 25 bytes (0x19)
0000: {"key":1,"key2":"value1"}
......

-x/--proxy

用于设置代理,格式是 [protocol://]host[:port],protocol 不填默认为 http,port 省略为 1080。可以传递到 BurpSuite 进一步调试请求。

curl -d test=1 -X PUT example.com -x 127.0.0.1:8080

-X/--request

设置请求方法,其他请求头不会改变。

C:\Users\gbb>curl -v -X OPTIONS example.com -x 127.0.0.1:8080
*   Trying 127.0.0.1:8080...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> OPTIONS http://example.com/ HTTP/1.1
> Host: example.com
> User-Agent: curl/7.79.1
> Accept: */*
> Proxy-Connection: Keep-Alive
> ......

-F/--form

使用 POST 上传文件并指定参数。

C:\Users\gbb>curl --trace-ascii - -F parName=value1 -F parName=value2 -F profile=@desktop/portrait.jpg example.com 
== Info:   Trying 93.184.216.34:80...
== Info: Connected to example.com (93.184.216.34) port 80 (#0)
=> Send header, 184 bytes (0xb8)
0000: POST / HTTP/1.1
0011: Host: example.com
0024: User-Agent: curl/7.79.1
003d: Accept: */*
004a: Content-Length: 3960
0060: Content-Type: multipart/form-data; boundary=--------------------
00a0: ----265c9e27bdb4271a
00b6:
=> Send data, 3960 bytes (0xf78)
0000: --------------------------265c9e27bdb4271a
002c: Content-Disposition: form-data; name="parName"
005c:
005e: value1
0066: --------------------------265c9e27bdb4271a
0092: Content-Disposition: form-data; name="parName"
00c2:
00c4: value2
00cc: --------------------------265c9e27bdb4271a
00f8: Content-Disposition: form-data; name="profile"; filename="portra
0138: it.jpg"
0141: Content-Type: image/jpeg
015b:
015d: ......JFIF.....x.x.....C................................... $.'
019d: ",#..(7),01444.'9=82<.342...C...........2!.!22222222222222222222
01dd: 222222222222222222222222222222........E.."......................
021d: ......................................}........!1A..Qa."q.2....#
025d: B...R..$3br........%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
029d: ................................................................
02dd: ..............................................................w.
031d: ......!1..AQ.aq."2...B.....#3R..br...$4.%.....&'()*56789:CDEFGHI
035d: JSTUVWXYZcdefghijstuvwxyz.......................................
039d: .............................................?...).....R..QE...S
03dd: .(......Q.Z(.(.-%..QK@...R.@.E-.....\P.h....(.....E.%/ZZ(.(...J)
041d: h......JZ(..%..P.QK.Q@.E.P.E.P.IKE..QI@.E.P.E....RR..E.P.IKI@.E.
045d: P.E.P.IKE.%-.P.E%-.%-.P.E....QE..QE....P.E....RQ@.E.P..E.P.IE-..
049d: QE..QE....P.E.P.E.P.E.P.E.P.E.P.E%-..QE.%-%-..QE.%-.P.E.P..E.P.I
04dd: E-..QE..Rf..Z(...(.....(......(...(.....(........(...(...J.Z))h.
051d: ..(............QI@.E.P.E.P.R.E..RR..E%..R.E...Q@.E...R.E.%-.P.Q.
055d: ....Z(....Z.JZ)(.h.....(...(......(.....JZ.JZJZ.JZ(....(.h....Z(
059d: ......(.*.C.B...i(...........fXm.yec.H.......X...8 ...QE.....P..
05dd: E%.-.Q@.KE..QE....RP..E..QE..QE%.-.Q@..Q@.....QE..RR.@.KE..QE...
061d: Q..@.g.ah|+..5E.....?..Q..s.'..b.....g.......I.b.q8...N}........
065d: .c....m,...Q.....U;.Z.x.4#.q..V..o.....=(...OP.S...n.b...Y.F....
069d: ....l..+d..Sk.....).X.}......sU...x...P...H.pC( 8.ua.~..j....C..
06dd: -c.iFg.].L..:g$s@.t...hz...LG.,.}.>f.E.........7....@.R.3.2.{...
071d: ../.sGo%..l........V.....j;.F.O.i.zK...^G.i.Nps.P.]X..o..W.E.B..
075d: 0X..a.#...x..x.[6....e..C.(.rs..?].....B...b..m....l8.6.?.I..tmE
079d:  ....i.......].x'q.....xsN....VG....c..8..F.~..k;.-.#1...u'...'.
07dd: .....E.....c..F.....`I#.#I+...,.rI.&..E.P.R.R..QKE..RR..E.P.IKE.
081d: ...P.IE-..w...;.E..QE%.-.Q@..Q@.E.....Q@..RQ@.Eu:...h....u..S.9.
085d: T......k....M._..-..71@..W..N}..lxCGMGX..K.4.+......L.....x..S..
089d: dI5.k...1.m....I....t...#Evm.m.[.............K..*.QTt.#E........
08dd: MbQ.v.(....c9......5G.k..Z]....]..\E........m.+".....</d.9.....f
091d: ......P.....Qh^...b..'k.R......L..y............!......2..}....H.
095d: ...R..Vb..[8u.e.C!{.6G2........8..$.rOJ*...r........6.C.........
099d: ........$.P.)"...5.x...+(.d...Y|.d..|0....._.......E.......y..'.
09dd: ....I.s@.E.U.................1.:...........y"..x..7).).z^.a..wau
0a1d: n.p.hY.>....|1..D..^O..j......x..*]B.{..6r.M$.h..#.8.{......B..
0a5d: ....x..g..e.s...*.u....x.[...4R..1.N........6.c.....".3..2..)<d.
0a9d: J.........N.n...`.b.F.,G...lV...t.....w..y..I.z)X.=..y..F.._.d.
0add: .."[..........w.....v|;...K...G..4d.....}x...Z.&....-.,"....=B.&
0b1d: ....Pa.C.c<q.y..#G......}^.....N.d./L..>.v..r...?K..|{..z.2.W0..
0b5d: ....*.\.........z...Q.....dd......q.@.1Y\.o5.6.<0.euRBg.Oj...:-
0b9d: >o...as.C40F.1...H....q....M*......<.l..7..T..g..s.=(..........l
0bdd: c......6.m..+......W/.%f,/...X.[$2o..ds(<.8.=.h.....|5...%......
0c1d: ....7....Q............m5(b.b..c....#.H..8...8.7.........g.....YD
0c5d: .H.......@......i...........2. ...........b......L..Y..x@...a..
0c9d: o..9J+....hw.W...Q.".e..|..@?/$m>.E..............f.;=..9`..@=+..
0cdd: ........_.|-.,S.3:.0.....m(..;ha.?.Z....h.).b.....t_...Q..n..0.E
0d1d: .s}.............f.Y...la...g..R.H&.).........(..Y..U.M...<.0y...
0d5d: .{.?.r^%...^.m#..[...3+..NOJ(..>..Q@................_.._..QE.
0d9d: y.j=h..:....;....O.C....'.....<.(....?....gIC{..P.7..........(.
0ddd: ..8#.@..E.YB.O@....;..MV.m...^t.#..l.9...P.Z.G...6.....\..:.5..-
0e1d: N.(..I.Tz.M.P...?....`k.........b8'.$..2.......u..(.o....T. ..l
0e5d: ...VG..X.]...)........E.].....'.....F..C.............(..6'....J
0e9d: ..9R4..|....s.$...^.-#..[...3+..NOJ(..:...<.Mz2X)..... ..G4Q@...
0edd: .W*.{..Pr..`..^..[.........f..-.aL}.....\.(..r..x<-....X.V....].
0f1d: ..8..n..x........\tQ@./....)w..^._...E....
0f4a: --------------------------265c9e27bdb4271a--
......

如果要指定文件的 ContentType,可以在文件名后指定 type=XXX/XXX 之间用分号分隔。

C:\Users\gbb>curl -v -F parName=value1 -F parName=value2 -F "profile=@desktop/portrait.jpg;type=text/html" example.com

上传时也能更改文件名,使用 filename=XXX。在上传文件跳转目录时比较方便。

C:\Users\gbb>curl -v -F parName=value1 -F parName=value2 -F "profile=@desktop/portrait.jpg;type=text/html;filename=../portrait.jpg" example.com

--path-as-is

让 CURL 不处理 ../、/./ 跨目录,就原封不动发送服务器。

默认是 CURL 自动处理 ../ 进行目录跳转。

C:\Users\gbb>curl -v example.com/.././1
*   Trying 93.184.216.34:80...
* Connected to example.com (93.184.216.34) port 80 (#0)
> GET /1 HTTP/1.1
> Host: example.com
> User-Agent: curl/7.79.1
> Accept: */*
> ......

使用选项后不做修正。

C:\Users\gbb>curl -v example.com/.././1 --path-as-is
*   Trying 93.184.216.34:80...
* Connected to example.com (93.184.216.34) port 80 (#0)
> GET /.././1 HTTP/1.1
> Host: example.com
> User-Agent: curl/7.79.1
> Accept: */*
> ......

--request-target

使用此选项提供的路径访问服务器,而不是 URL 中的,这个路径中的任何字符不会被处理,都原封不动发过去。

URL 中的路径会被 CURL 自动处理,锚点消失。

C:\Users\gbb>curl -v example.com/index.html#testaz
*   Trying 93.184.216.34:80...
* Connected to example.com (93.184.216.34) port 80 (#0)
> GET /index.html HTTP/1.1
> Host: example.com
> User-Agent: curl/7.79.1
> Accept: */*
> ......

URL 中的路径全部被忽略,仅使用 --request-target 提供的路径。

C:\Users\gbb>curl -v --request-target /test.html#testaz1 example.com/index.html#testaz
*   Trying 93.184.216.34:80...
* Connected to example.com (93.184.216.34) port 80 (#0)
> GET /test.html#testaz1 HTTP/1.1
> Host: example.com
> User-Agent: curl/7.79.1
> Accept: */*
> ......

参考资料

最近更新:

发布时间:

摆哈儿龙门阵