分类 Web 相关 下的文章

HTTP post/put 的 payload 的内容(content-type)类型

虽然看过几遍 HTTP 权威指南, 可是每次遇到 post 上传文件或者看到 Postman 的 form-data, x-www-form-urlencoded 的时候, 还是有点迷糊. 今天看 everything about curl 的时候, 又谈到了 post 的 payload 内容类型. 索性把它理清楚, 方便自己以后查找.

关于 POST 和 PUT 区别

有 ID, 每次根据 ID 去创建/更新, 就用 PUT, 具有幂等性, 多次提交不影响结果.
没有 ID, 每次都创建, 就用 POST, 不具有幂等性, 多次提交产生多次内容.

网页表单(FORM)提交

网页表单提交时, 若 method 为 POST, 表单的 enctype 属性决定了提交的负载内容(payload)的 MIME(网络多媒体类型)类型. enctype 是 encoding type 的缩写, 表示了内容的编码类型, 相当于告诉接受请求的服务器: 我这边把发送的内容经过了某种编码类型A 编码, 你收到之后也用同样的类型解码一下. 现在(20220102)enctype 可能的值(反映到 Content-Type)只有3种:

  1. application/x-www-form-urlencoded 只支持键值对,键值对中间用&分隔开, 比如 name=eric&gender=1&age=50
  2. multipart/form-data 如果表单的某个值为文件时(上传文件), 使用这种方式, 否则使用上面编码方式(简单).
  3. text/plain HTML5 新加的, 主要用于调试.

除去第三种调试用的, 我们在网页上看到的基本就是上面2种, 如果没有文件上传, 基本是第一种, 因为它最简单, 基本就是把 form 的内容根据键值对使用&连接到一起.
multipart/form-data 要对表单内容的每个项目使用分隔符分开, 它的分隔符比较长, 中间还有空行. 比如我上传一个图片文件(sni.png)和另外一个字段(key1=value1), 它的负载的内容是:

------WebKitFormBoundarycsbFnSl9t4kuAjfv
Content-Disposition: form-data; name="a"; filename="sni.png"
Content-Type: image/png

.PNG
.
...
IHDR................e....sRGB........leXIfMM.*.
<<中间省略 png 里面的1000多行二进制内容>>
...adfas
------WebKitFormBoundarycsbFnSl9t4kuAjfv
Content-Disposition: form-data; name="key1"

value1
------WebKitFormBoundarycsbFnSl9t4kuAjfv--

Ajax 请求表单/代码(微服务)提交表单

这种情况下, Content-type 可以是其它类型: application/xml, application/json

关于 HTTP header Content Security Policy (CSP)

为什么需要 CSP

允许用户提交数据的网站总是会遇到跨站脚本(Cross-Site Scripting)和各种数据注入的安全问题, 通常这些脚本都会发送消息给第三方搜集数据或者加载第三方站点的各种资源来进一步扩大攻击面. 那么如何保证我们自己的站点不要加载或使用第三方资源呢?

什么是 CSP

Content Security Policy 就是专门用来发现和缓解上面提到的各种潜在的安全问题的解决方案. 它限制浏览器可以使用的各种资源(JavaScript, css, 图片, video, 字体, frame, audio等)的 URL. 比如只允许使用本站点或信任站点的 JavaScript 或 CSS.

CSP 的实现

服务器端返回的 response 里的 Content-Security-Policy header 用来实现 CSP.
Content-Security-Policy: default-src 'self' trusted.com *.trusted.com
或者通过 HTML 里面的 meta 元素来实现:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' trusted.com *.trusted.com">

Content-Security-Policy 的值称之为 policy. 每个 policy 定义一种或多种资源的这种资源被允许的来源. default-src 用来设置默认的policy, 当没有设置某种资源的限制时, 就使用 default-src的 policy.

一些例子:

Content-Security-Policy: default-src 'self'
Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com
Content-Security-Policy: default-src 'self' *.mailsite.com; img-src *

更多例子参考:
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

当你只是想测试一下你的 policy 时(比如, 你不确定你的站点现在共使用了哪些第三方的资源时), 你可以使用这个 header 去测试, 它只会报告给你, 不会真正限制时候第三方资源:

Content-Security-Policy-Report-Only: policy

如何上报

可以在 policy 里面设置 report-to 或 report-uri (deprecated) 如:

Content-Security-Policy: ...; report-uri https://endpoint.com; report-to groupname

当浏览器不支持 CSP 时, 它会降级到同源策略 (CORS)来保护站点.

当遇到违反 CSP 的情况时候, console 会报错:
sampel.png

HTTP 2 的特性

从 HTTP 2 in action 这本书看的, 发现这个网站总结的不错: https://tools.keycdn.com/http2-test, 就摘抄过来了. 顺便测试了一下 (20191104), taobao, ebay 支持 Http2, jd 和 baidu 主页都不支持 HTTP2

  1. HTTP/2 is binary, instead of textual.
  2. It is fully multiplexed, sending multiple requests in parallel over a single TCP connection.
  3. It uses header compression HPACK to reduce overhead.
  4. It allows servers to “push” responses proactively into client caches instead of waiting for a new request for each resource
  5. It uses the new ALPN extension which allows for faster-encrypted connections since the application protocol is determined during the initial connection.
  6. It reduces additional round trip times (RTT), making your website load faster without any optimization.
  7. Domain sharding and asset concatenation is no longer needed with HTTP/2.
  8. Flow control
  9. Stream prioritization

如何判断一个网站是不是支持 HTTP2? 使用最新的 curl 命令:

LM-SHC-16507776:tmp xiatian$ curl -vvv -s  --http2 https://www.jd.com:443/ 2>&1 | grep ALPN
* ALPN, offering h2
* ALPN, offering http/1.1
* ALPN, server accepted to use http/1.1
LM-SHC-16507776:tmp xiatian$ curl -vvv -s  --http2 https://www.ebay.com:443/ 2>&1 | grep ALPN
* ALPN, offering h2
* ALPN, offering http/1.1
* ALPN, server accepted to use h2

上面的输出中 baidu 首页不支持, ebay 首页支持.


从下面这个问答看:
在 Chrome 里面, 对于 HTTP 2 同一个 origin 不同的 tab 之间共享一个 tcp 连接.
对于 HTTP 1.1:

  1. HTTP/1.1 sockets are stored in a pool when they are not active. A request from any tab may end up using any socket in the pool;
  2. Incognito tabs use their own independent socket pool (All incognito tabs for a profile share just one socket pool, though);
  3. Isolated apps use their own socket pools.
  4. Different profiles and guest mode use their own socket pools.
  5. Global requests not tied to a profile use their own socket pool;

https://stackoverflow.com/questions/51535819/in-http-1-1-are-connections-shared-across-multiple-chrome-tabs-to-the-same-origi
https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/S3TEvmRWcNE

捕获 ssl/tls 版本

tcpdump -i any -s 1500 'tcp port 443 and (tcp[((tcp[12:1] & 0xf0) >> 2)+5:1] = 0x01) and (tcp[((tcp[12:1] & 0xf0) >> 2):1] = 0x16)' -w output.txt

https://serverfault.com/questions/574405/tcpdump-server-hello-certificate-filter
https://networkengineering.stackexchange.com/questions/20227/find-ssl-version-in-tcp-packets-in-established-tcp-connection
http://blog.fourthbit.com/2014/12/23/traffic-analysis-of-an-ssl-slash-tls-session
https://stackoverflow.com/questions/39624745/capture-only-ssl-handshake-with-tcpdump
https://www.cnblogs.com/ggjucheng/archive/2012/01/14/2322659.html