分类 Web 相关 下的文章

捕获 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

设置 https proxy

问题:

Java 实现:

参看:
https://stackoverflow.com/questions/516323/https-connections-over-proxy-servers
https://wiki.squid-cache.org/Features/SslBump
https://wiki.squid-cache.org/Features/SslPeekAndSplice
https://www.javaworld.com/article/2077475/core-java/java-tip-111--implement-https-tunneling-with-jsse.html

关于 http 1.1 header Transfer-Encoding 的用法

关于 Transfer-Encoding 在官方文档中有以下几个点要注意:

  1. 它是 Hop to Hop 的 header, 也就是中间代理可以改的, 并不是 end to end 的 header;
  2. 它是传输编码, 并不是 content-encoding, content-encoding 是 end to end;
  3. 可能的值有: chunked, compress, deflate, gzip, identity. 可以是多个, 用逗号隔开;
  4. 如果是 chunked, 因为预先不知道内容长度, 所以 Content-Length 是不需要的;
  5. 如果有 chunked, chunked 必须在逗号隔开的最后一个;
  6. HTTP/1.1 应用程序必须能够编码/解码 chunked;
  7. identity 代表原样传输, 没有编码, 必须永远被接受;
  8. 在 request 的 header 中的 TE, 其实是 Accepted-Transfer-Encoding 的缩写;

比较容易混淆, 官方文档有没有说明的是:
尽管 Transfer-Encoding 是一个 response header, 可是在 request 的 header 中也可以使用这个 header, 并且服务端都能处理. 参考下面这 2 处文章:

  • 在 Wiki https://en.wikipedia.org/wiki/Chunked_transfer_encoding 中的 Format 一节中, 有写到:

If a Transfer-Encoding field with a value of "chunked" is specified in
an HTTP message (either a request sent by a client or the response
from the server)

  • 在 http://www.oracle.com/technetwork/systems/chunking-155634.html 中的写到:

Chunking is most often used by the server for responses, but clients
can also chunk large requests

另外在 Tomcat8 的实现中, org.apache.coyote.http11.Http11Processor 的类的 prepareRequest() 方法中, 我们可以看到具体的对于 Transfer-Encoding 的处理方法. 其中包含对于 request 使用 chunked 处理.

使用 Curl 测试 content-length 和 payload 的数据量不一致的问题:

curl -X POST http://localhost:8080/post --header "Content-Type:application/json" --header "content-length: 2" --header "transfer-encoding:abc" --data "{"

更多内容, 参考: rfc7230, RFC2616
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding

HSTS (HTTP Strict-Transport-Security) 笔记

HSTS 是 HTTP Strict-Transport-Security 的缩写,是浏览器的一个功能. 它告诉浏览器对于某些站点只能用 HTTPS 访问, 不能用 http.

它通过服务器返回的 response 的 header 中的 Strict-Transport-Security 这一项来设置.
语法: Strict-Transport-Security: max-age=<expire-time>; includeSubDomains; preload.

当用户当前访问的是 HTTPS 站点,并且证书是合法有效的, 如果 response header 中包含 Strict-Transport-Security 做个 header, 那么浏览器就会知道: 这个站点在某个时间点之前都要使用 https 访问,如果用户输入 http 的协议, 自动转换为 https. 如果没到期, 后续的浏览又带来这个 header 会自动更新终止时间. 如果到期, 这个规则自动失效.
如果用户当前访问的是 http 站点, 并且这个站点之前还没有使用 HSTS, 那么浏览器会忽略这个 header, 因为没有使用 https, 这个回话可能会被拦截篡改.

参见: Strict-Transport-Security wiki

Unicode 字符集 和 UTF 编码

  1. Unicode 是字符集, 类似ASCII 码有127字符, Unicode 已经包含17个planes, 每个plane包含65536个代码点(code point)
  2. UTF 是Unicode字符集的编码, 就是Unicode 字符集在磁盘的表示, 参考这篇很不错的文章 十分钟搞清字符集和字符编码
  3. Windows 和 Java 默认使用 UTF-16, Web 默认使用 UTF-8
  4. UTF-8 兼容ASCII
  5. 非英文域名 即 IDNs 要使用 Punycode 去转. 尽管你的URL的域名部分是 新华网.中国 或 %E6%96%B0%E5%8D%8E%E7%BD%91.%E4%B8%AD%E5%9B%BD (encodeURI("新华网.中国")的结果) 在去到DNS 解析的时候, 都是翻译为 Punycode 去做DNS 查询的
  6. Unicode 要区分 字符, codepoint, UTF 编码后的值 如 : 田 的codepoint 是30000 (0x7530), UTF-8 编码后是: E794B0 (使用 encodeURI("田") 得到)