<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Semantics · XB 现场笔记</title><link>https://www.xbcatm.com/zh/tags/semantics/</link><description>基于 HTTP、DNS、TLS、Caddy、SSH、发布与恢复的可复现运维现场笔记。</description><generator>Hugo</generator><language>zh-CN</language><atom:link href="https://www.xbcatm.com/zh/tags/semantics/index.xml" rel="self" type="application/rss+xml"/><item><title>HTTP 方法是对副作用做出的承诺</title><link>https://www.xbcatm.com/zh/notes/http-method-semantics/</link><pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate><guid>https://www.xbcatm.com/zh/notes/http-method-semantics/</guid><description>HTTP 方法说明了请求可能改变什么；静态源站可以在不假装有状态契约的情况下应答其中大多数方法。</description><content:encoded>&lt;p&gt;请求方法说明客户端要求服务器做什么。只读文件源站的契约很窄，但仅凭“静态站点”并不能证明代理或导入的处理器没有暴露写操作。应检查真正服务该资源的路由。&lt;/p&gt;
&lt;h2 id="安全与幂等回答不同的问题"&gt;安全与幂等回答不同的问题&lt;/h2&gt;
&lt;p&gt;GET 与 HEAD 是安全方法：客户端没有请求改变状态的操作。但附带的日志、指标或计费仍可能改变服务器状态。PUT 与 DELETE 按其定义具有幂等语义，却并不安全：重复相同请求的预期效果与执行一次相同。这不要求响应状态码相同，也不意味着每次网络失败后都适合重试。&lt;/p&gt;
&lt;p&gt;对只读静态源站：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GET&lt;/strong&gt; 获取表示。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HEAD&lt;/strong&gt; 描述对应的 GET，但不携带响应内容。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OPTIONS&lt;/strong&gt; 询问目标的通信选项；文件处理器可以拒绝它。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;POST / PUT / DELETE / PATCH&lt;/strong&gt; 不应直接落入成功的文件响应，除非另有明确设计的处理器实现其语义。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="caddy-文件处理器的方法边界"&gt;Caddy 文件处理器的方法边界&lt;/h2&gt;
&lt;p&gt;Caddy v2.10.2 的文件服务路径接受 GET 与 HEAD，并以 &lt;code&gt;405&lt;/code&gt; 和 &lt;code&gt;Allow: GET, HEAD&lt;/code&gt; 拒绝其他方法。重定向、缺失路径、错误处理器与其他配置路由可能更早应答或采取不同处理，因此这不是每个静态网站 URL 的统一响应。&lt;/p&gt;
&lt;p&gt;原笔记记录过：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ curl -s -o /dev/null -w &amp;#39;OPTIONS -&amp;gt; HTTP %{http_code}\n&amp;#39; -X OPTIONS https://www.xbcatm.com/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;OPTIONS -&amp;gt; HTTP 405
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里没有保留原始响应日志，本轮审阅也未重现该在线结果。命令只报告状态码，不能证明必需的 &lt;code&gt;Allow&lt;/code&gt; 字段存在，需另行检查。&lt;code&gt;405&lt;/code&gt; 表示已知方法不被该目标支持；如果服务器根本不识别或未实现该方法，通常应区分为 &lt;code&gt;501 Not Implemented&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="head-一致性允许规范规定的省略"&gt;HEAD 一致性允许规范规定的省略&lt;/h2&gt;
&lt;p&gt;HEAD 应描述与 GET 相同的所选表示，同时省略内容。只有生成内容时才能确定的字段可以省略。如果存在 &lt;code&gt;Content-Length&lt;/code&gt;，它必须描述采用相同内容编码的对应 GET 内容长度。&lt;/p&gt;
&lt;p&gt;原笔记报告过以下比较：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;HEAD content-length: 15890
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET bytes read : 15890
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这些历史数字不是固定的期望大小，也不是当前验证结果。仅缺少 HEAD 长度是合法的，提供了错误长度才需要调查。成对探针可参考 &lt;code&gt;head-request-parity&lt;/code&gt; 笔记；可下载的 &lt;code&gt;check-http-headers.sh&lt;/code&gt; 只检视 GET 响应，并不会自动执行这项比较。&lt;/p&gt;
&lt;h2 id="拒绝意外写入同时说明真实契约"&gt;拒绝意外写入，同时说明真实契约&lt;/h2&gt;
&lt;p&gt;对已识别、但目标不允许的方法，返回 &lt;code&gt;405&lt;/code&gt;，并以 &lt;code&gt;Allow&lt;/code&gt; 列出实际支持的方法。应用路由的这个列表不一定只包含安全方法。不要为被忽略的写请求返回看似合理的 &lt;code&gt;200&lt;/code&gt; 页面。&lt;/p&gt;
&lt;p&gt;如果浏览器客户端需要 CORS 预检，应明确配置相应 OPTIONS 行为；方法支持与 CORS 权限是两项不同决策。写入拒绝测试应在获准使用的可丢弃夹具上进行，不要因为公共端点看起来静态，就假设向它发送写请求没有影响。&lt;/p&gt;
&lt;h2 id="来源"&gt;来源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc9110.html"&gt;RFC 9110 — HTTP Semantics&lt;/a&gt;，安全/幂等方法与 HEAD、405、501 语义，已核验 2026-10-15。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods"&gt;MDN: HTTP 请求方法&lt;/a&gt;，方法概览，已核验 2026-10-15。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://curl.se/docs/manpage.html"&gt;curl 手册&lt;/a&gt;，方法与响应检视选项，已核验 2026-10-15。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/caddyserver/caddy/v2.10.2/modules/caddyhttp/fileserver/staticfiles.go"&gt;Caddy v2.10.2 文件服务器源码&lt;/a&gt;，文件选取后的方法拒绝，已核验 2026-10-15。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fetch.spec.whatwg.org/#cors-preflight-fetch"&gt;WHATWG Fetch 标准&lt;/a&gt;，CORS 预检处理，已核验 2026-10-15。&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>