[20] [DFN[[[HTTP/0.9]]]] は、
[TIME[西暦1991年][1991]]以来使われている [[HTTP]] の最初の版です。
極めて単純ですが、あまりに低機能なので、現在ではほとんど使われなくなっています。
それでも [[HTTP]] [[プロトコル]]の一部として依然として広く実装されています。

* 仕様書

[REFS[
- [10] [CITE@en[RFC 1945 - Hypertext Transfer Protocol -- HTTP/1.0]] ([TIME[2014-09-07 13:12:32 +09:00]] 版) <http://tools.ietf.org/html/rfc1945#section-3.1>
- [13] [CITE@en[RFC 1945 - Hypertext Transfer Protocol -- HTTP/1.0]] ([TIME[2014-09-07 13:12:32 +09:00]] 版) <http://tools.ietf.org/html/rfc1945#section-4.1>
- [15] [CITE@en[RFC 1945 - Hypertext Transfer Protocol -- HTTP/1.0]] ([TIME[2014-09-07 13:12:32 +09:00]] 版) <http://tools.ietf.org/html/rfc1945#section-5>
- [18] [CITE@en[RFC 1945 - Hypertext Transfer Protocol -- HTTP/1.0]] ([TIME[2014-09-07 13:12:32 +09:00]] 版) <http://tools.ietf.org/html/rfc1945#section-6.1>
- [21] [CITE@en[RFC 1945 - Hypertext Transfer Protocol -- HTTP/1.0]] ([TIME[2014-09-07 13:12:32 +09:00]] 版) <http://tools.ietf.org/html/rfc1945#section-7.2.1>
]REFS]

* 呼称

[47] 元々は単に「[[HTTP]]」と呼んでいましたが、新しい版 
[WEAK[([[HTTP2]] と呼ばれたり、[[HTTP/1.0]] と呼ばれたりしたもの。後の [[HTTP/2]] とは別。)]]
が開発された時、区別するために
[[HTTP/0.9]] と呼ばれるようになりました。
[WEAK[(新しい版が当初 [[HTTP2]] と呼ばれていたということは、その当時は [[HTTP/0.9]] が [[HTTP]]「1」だという意識があったのでしょう。)]]

[48] 0.9 は 1.0 より前という程度の意味なので、 0.8 や 0.5 や 0.1 はありません。

* プロトコル

[22] [[HTTP/0.9]] の詳細については [[HTTP]] や、各[[プロトコル要素]]の項を参照してください。

[FIG(short list)[
- [[HTTP接続]]
- [[HTTPメッセージ]]
- [[要求]]
-- [[要求行]]
-- [CODE(HTTP)@en[[[GET]]]]
- [[応答]]
]FIG]

[14] [[HTTP/0.9]] [[応答]]は [[MIME型]]を示せないため、
[[HTTP/0.9]] [[要求]]は[[非推奨]] [SRC[>>13]] とされています。

[25] [[HTTP/0.9]] には[[ヘッダー]]はありません。 [CODE(HTTP)@en[[[Host:]]]]
[[ヘッダー]]も含められないため、 ([[要求URL]]に[[絶対URL]]を指定して無理に明示するのでなければ)
[[仮想ホスト]]に対応できません。この意味で [[HTTP/0.9]] は最早 [[Web互換]]とはいえません。

[24] [[状態符号]]はありません。

;; [30] [[Chrome]] で [[XHR]] で取得すると、 [CODE(HTTP)[[[200]]]] 扱いになっているようです。

[26] [[HTTP/0.9]] [[応答]]は[[キャッシュ不可能]]なものとして処理するべきと思われます。

;; [38] [[IE]] は[[キャッシュ]]するようです。 [TIME[2015-06-14T09:10:28.700Z]]

* HTTP/1.0 との関係

[12] [[HTTP/1.0]] [[鯖]]は [[HTTP/0.9]] [[要求]]を処理できなければなりません [SRC[>>10]]。
[[HTTP/1.0]] [[鯖]]は [[HTTP/0.9]] [[要求]]を受信したら、
[[HTTP/0.9]] [[応答]]を返さなければなりません [SRC[>>10, >>15]]。

[11] [[HTTP/1.0]] [[クライアント]]は [[HTTP/0.9]] [[応答]]を処理できなければなりません [SRC[>>10]]。

;; [17] [[HTTP/0.9]] [[鯖]]だった場合、 [[HTTP/1.0]] [[要求]]に [[HTTP/0.9]] 
[[応答]]が返されることとなります [SRC[>>18]] から、 [[HTTP/0.9]] [[要求]]でなくても 
[[HTTP/0.9]] [[応答]]に対応できる必要があるようです。

[16] [[HTTP/1.0]] [[応答]]を処理できる[[クライアント]]は [[HTTP/0.9]] [[要求]]を送信するべきではありません [SRC[>>15]]。

* 要求の解釈

[32] [[nginx]] は、[CODE(HTTP)@en[[[GET]]]]、1文字[[以上]]の[[空白]]、
[[絶対パス]]か[[絶対URL]]、[[改行]]となっていなければ、 [CODE(HTTP)[[[400]]]]
[[応答]]に相当する[[応答本体]]を返します。[[要求メソッド]]は[[大文字]]でなければなりません。
[TIME[2015-06-14T08:52:57.800Z]]

[49] [[nginx]] は、 [CODE[HEAD]] や [CODE[POST]] や未知の[[要求メソッド]]のときも、
[CODE[400]] を返します。 [TIME[2016-08-26T15:40:45.300Z]]

[33] [[Apache]] は、任意の[[要求メソッド]]を認めています。 (もちろん当該[[資源]]で対応していなければ、
[CODE(HTTP)[[[405]]]] や [CODE(HTTP)[[[501]]]] が返されたり
(ただし[[応答本体]]のみ)、 [CODE(HTTP)@en[[[GET]]]] にフォールバックしたりします。
[CODE(HTTP)@en[[[HEAD]]]] では [CODE(HTTP)[[[400]]]] となります。
[TIME[2015-06-14T08:55:02.000Z]]

;; [34] [[Apache]] は [CODE(HTTP)@en[[[TRACE]]]] にも対応しているので、
[CODE(HTTP)@en[[[TRACE]]]] CRLF と書くと [CODE(HTTP)[[[TRACE]]]] が帰ってきます。

[64] 
[[HTTP/0.9要求]]に対応できない[[HTTPサーバー]]もあるようです。
[SEE[ [[426]] ]]

* 応答の解釈

[19] [[HTTP/1.0]] や [[HTTP/1.1]] の[[要求]]であっても、[[応答]]の先頭を[[状態行]]として解釈できなければ、
[[HTTP/0.9]] [[応答]]と解釈することとなります。

[28] [[応答]]の最初の行に、 [[Chrome]] と [[IE]] は [CODE[HTTP]]、
[[Firefox]] は [CODE[HTTP/1.]] が含まれていれば、 [[HTTP/0.9]] では無いとみなすようです。
[[HTTP]] は大文字でも小文字でも構いません。行頭でなくても構いません。
[[行]]は、 [[LF]] までです。 [TIME[2015-06-13T14:21:44.300Z]]

[39] 正確には、 [[Chrome]] と [[Firefox]] は最初の8バイトに [CODE[HTTP]]
が含まれていなければなりません。 ([[Firefox]] はその後に更に [CODE[/1.]] が必要ですが、
そこまで最初の8バイトに無くても良いようです。) その8バイトに[[改行]]が含まれていても構いません。
[[IE]] はもっと緩くて十数バイトあっても良いようですが (どこまでいけるかは不明)、
[CODE[HTTP]] の直後が[[改行]]であってはならないようです。 [TIME[2015-06-14T12:21:45.500Z]]

[7] [[Firefox]] と [[Chrome]] は [CODE(HTTP)@en[[[PUT]]]] への[[応答]]が
[[HTTP/0.9]] だと、エラーとみなすようです。
[[IE]] は通常の[[応答]]として扱うようです。
それ以外の[[要求メソッド]]は通常の[[応答]]として扱うようです。 [TIME[2015-08-01T12:15:28.700Z]]

[45] [[Firefox]] と [[Chrome]] は [CODE(HTTP)@en[[[CONNECT]]]] への[[応答]]が
[[HTTP/0.9]] だと、エラーとみなすようです。 [[IE]]
は正しく扱えず[[応答]]を待つように見えます。 [TIME[2015-09-14T02:30:12.400Z]]

[31] [[応答]]として何も返さないと (長さが0だと) [[ネットワークエラー]]とみなされるようです。
[[Firefox]] と [[Chrome]] では ([[XHR]] の) [[状態符号]] 0、
[[理由句]]が[[空文字列]]となります。 [[IE]] では [CODE[[[12152]]]]、
[CODE[[[Unknown]]]] となります。 [TIME[2015-06-14T08:46:47.800Z]]

[43] [[Chrome]] も [[Firefox]] も [[IE]] も、 [[プロキシ]]として指定された[[サーバー]]が
[[HTTP/0.9]] [[応答]]を返すと、それを通常通り[[応答]]として使います。 [TIME[2015-08-04T10:35:01.800Z]]

[44] [[Chrome]] は [[HTTP/0.9]] over [[TLS]] を[[ネットワークエラー]]とみなすようです。
[[Firefox]] と [[IE]] では通常通り扱われます。 [TIME[2015-08-13T14:26:17.300Z]]

[69] 
[[curl]] はあるときから
[[HTTP/0.9]] 
[[応答]]を受け取った時
[DFN[[CODE[Received HTTP/0.9 when not allowed]]]]
というエラーメッセージを表示するように[[非互換変更]]されました。

[70] 
それまでちゃんと動いていたものが突然動かなくなったと困っている人がままいるっぽいです。
[SRC[>>65, >>66, >>67]]
それだけ [[HTTP/0.9]] の挙動に依存したシステムが存在しているということでしょう。
(意図したものか、たまたま動いていたのかはともかく。)

[71] 
[[コマンドラインオプション]]に 
[DFN[[CODE[--http0.9]]]]
を付けると、
[[HTTP/0.9]]
を扱えるようになります。
[[PHP]]
には
[DFN[[CODE[CURLOPT_HTTP09_ALLOWED]]]]
というオプションがあります [SRC[>>68]]。










[REFS[
- [5] [CITE@en[193921 – unable to http publish because not prompted for a password]]
( ([TIME[2014-07-15 07:03:01 +09:00]] 版))
<https://bugzilla.mozilla.org/show_bug.cgi?id=193921>
- [6] [CITE[chromium chromium/src/net/http/http_network_transaction.cc]]
( ([TIME[2014-07-14 05:04:37 +09:00]] 版))
<http://mxr.mozilla.org/chromium/source/src/net/http/http_network_transaction.cc#1028>
]REFS]

* 応答の MIME 型

[23] [[MIME型]]は [CODE(HTTP)@en[[[Content-Type:]]]] [[ヘッダー]]が無い場合のように
[[Content-Type sniffing]] によって決定されるものと思われます。
元々は [[HTML]] のみが使われることが想定されていました。

;; [37] [[平文]]の転送のために [[HTML]] の [CODE(HTMLre)@en[[[plaintext]]]]
[[タグ]]が用意されています。

;; [29] [[Chrome]] と [[IE]] は [[sniffing]] しているようですが、
[[Firefox]] は [CODE(MIME)@en[[[text/plain]]]] として扱っているようです。 [TIME[2015-06-13T14:23:50.00Z]]

* 歴史

[59] [[HTTP/0.9]] は [[HTTP]] の最初の版であり、当初は単に [[HTTP]]
と呼ばれていました。

[60] 当時は [[TimBL]] が配布していた文書 ([[テキストファイル]]) や [[CERN]]
の [[Webサイト]]にあった [[HTML文書]]という形の[[仕様書]]が存在していました。

[61] 後に、 [[HTTP/1.0]] を定義する [[RFC 1945]] の一部として、
改めて[[仕様書]]の形にまとめられました。

[2] [CITE[HTTP0.9 Summary -- /DesignIssues]]
([TIME[2009-08-28 06:38:06 +09:00]] 版)
<http://www.w3.org/DesignIssues/HTTP0.9Summary.html>

[73] 
[CITE[(No title)]], [TIME[1992-06-10T08:03:38.000Z]], [TIME[2024-08-31T09:06:37.673Z]] <https://www.w3.org/History/19921103-hypertext/hypertext/WWW/Protocols/HTTP.html>

[36] [CITE[The HTTP Protocol As Implemented In W3]]
([TIME[1999-10-27 03:45:32 +09:00]] 版)
<http://www.w3.org/Protocols/HTTP/AsImplemented.html>

[40] [CITE[HTTP0.9 Summary -- /DesignIssues]]
([TIME[2009-08-28 06:38:06 +09:00]] 版)
<http://www.w3.org/DesignIssues/HTTP0.9Summary.html>

[41] [CITE[ProtocolVersions -- Design Issues]]
([TIME[2009-08-28 06:38:06 +09:00]] 版)
<http://www.w3.org/DesignIssues/ProtocolVersions.html>

[42] [CITE[CompatibleProof -- /DesignIssues]]
([TIME[2009-08-28 06:38:06 +09:00]] 版)
<http://www.w3.org/DesignIssues/CompatibleProof>

[1] [[Apache]] に [KBD[[[GET]] / HTTP/0.9]] とかやってみたら、ほんとに HTTP/0.9 になりましたよ:−)

[8] >>1 現在の [[Apache]] は[[プロトコルの版]]に [[HTTP/0.9]]
を指定しても、 [[HTTP/1.0]] のように処理するようです。
[TIME[2014-08-28T12:55:31.400Z]]

[9] [[nginx]] は[[プロトコルの版]]に [[HTTP/0.9]] を指定すると、
[[要求行]]を受信した段階で [CODE(HTTP)[[[400]]]] を返します。

[27] [[nginx]] は [[HTTP/0.9]] [[応答]]に対して[[状態符号]]によらず[[応答本体]]のみ返しますが、
[[リダイレクト]]の場合 [[URL]] を[[応答本体]]には含めないため、
[[HTTP/0.9]] [[クライアント]]は[[リダイレクト]]先 [[URL]] を知ることができません。

[79] 
[CITE@en[728236 - HTML Pages are shown as text when served on nonstandard port with an HTTP status line starting "HTTP/0.9"]], [TIME[2025-09-11T15:41:30.000Z]] <https://bugzilla.mozilla.org/show_bug.cgi?id=728236>


[3] [CITE[IRC logs: freenode / #whatwg / 20140107]]
( ([TIME[2014-01-08 20:47:22 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20140107#l-537>


[4] [CITE@en[RFC 7230 - Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing]]
( ([TIME[2014-06-07 01:59:35 +09:00]] 版))
<https://tools.ietf.org/html/rfc7230#page-82>

[FIG(quote)[
[FIGCAPTION[
[35] [CITE@ja[HTTP/0.9にハマル | Livingdeadの日記 | スラド]]
([TIME[2015-06-14 18:02:16 +09:00]] 版)
<http://srad.jp/~Livingdead/journal/492941/>
]FIGCAPTION]

> ライブドア・データホテル・パトロールというサービスを使っている.これはなかなかのすぐれもので,ウェブサーバの監視をはじめ証明書の期限切れ検知などにも使えるのだが,最近lighttpdを使っているウェブサービスの死活監視に使ってみてHTTP/0.9のリクエストになっているのかなと思った.
> というのはlighttpdにtelnetで接続して「GET / 」と打つと400 Bad Requestになるのだが,データホテル・パトロールでも確かに400を検出して異常が検知されたことになる.

]FIG]



[FIG(quote)[
[FIGCAPTION[
[46] [CITE[Issue 517106 - chromium - Chrome refuses to accept HTTP/0.9 responses over SSL that are less than 8 bytes long. - An open-source project to help move the web forward. - Google Project Hosting]]
([TIME[2015-09-26 20:34:29 +09:00]] 版)
<https://code.google.com/p/chromium/issues/detail?id=517106>
]FIGCAPTION]

> Re-disable support for HTTP/0.9 responses < 8 bytes over SSL.
This allows an MITM to make the firs byte of a valid HTTP/1.x response
look like a valid HTTP/0.9 reponses, so best to be safe.

]FIG]


[FIG(quote)[
[FIGCAPTION[
[50] [CITE@en[Chromium Blog: Chrome 53 Beta: Shadow DOM, PaymentRequest, and Android autoplay]]
( ([TIME[2016-09-17 08:54:54 +09:00]]))
<http://blog.chromium.org/2016/08/chrome-53-beta-shadow-dom.html>
]FIGCAPTION]

> HTTP/0.9 has been deprecated in favor of HTTP/1.0, which adds response header support.

]FIG]


[51] [CITE@en[HTTP - WHATWG Wiki]]
([TIME[2017-01-21 22:03:05 +09:00]])
<https://wiki.whatwg.org/wiki/HTTP#HTTP_0.9_.28and_Legacy_Shoutcast_support.29>

[52] [CITE[Intent to implement and Ship: Shoutcast support - Google グループ]]
([TIME[2017-01-22 13:05:47 +09:00]])
<https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/qS63pYso4P0/FP6xymqNAwAJ>

[82] 
[CITE@en[632524 - End support for HTTP/0.9]], [TIME[2025-09-11T15:49:02.000Z]] <https://bugzilla.mozilla.org/show_bug.cgi?id=632524>

[83] [CITE@en[1262128 - Cross-Protocol Theft from non-HTTP services via DNS rebinding + "HTTP/0.9"]], [TIME[2025-09-11T15:49:44.000Z]] <https://bugzilla.mozilla.org/show_bug.cgi?id=1262128>


[54] [CITE[Intent to Deprecate and Remove: HTTP/0.9 Support - Google グループ]]
([TIME[2017-01-22 13:06:45 +09:00]])
<https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/OdKnpLlvVUo>

[55] [CITE@en[624462 - Reduce cases where HTTP/0.9 is supported - chromium - Monorail]]
([TIME[2017-01-22 13:08:55 +09:00]])
<https://bugs.chromium.org/p/chromium/issues/detail?id=624462>

[81] [CITE@en[Can't access router config on chromium based browser anymore '''['''40480313''']''' - Chromium]], [TIME[2025-09-11T15:46:40.000Z]] <https://issues.chromium.org/issues/40480313>

[57] [CITE[Intent to implement and Ship: Shoutcast support - Google グループ]]
([TIME[2017-01-22 13:16:33 +09:00]])
<https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/qS63pYso4P0/FP6xymqNAwAJ>

[53] [[Shoutcast]]

[56] [CITE@en[667907 – (CVE-2011-3656) Possible XSS via HTTP 0.9 errors and content-sniffing]]
([TIME[2017-01-22 13:29:25 +09:00]])
<https://bugzilla.mozilla.org/show_bug.cgi?id=667907>

[58] [CITE@en[21467 - Cross site scripting through non-http servers - chromium - Monorail]]
([TIME[2017-01-22 13:37:06 +09:00]])
<https://bugs.chromium.org/p/chromium/issues/detail?id=21467>

[62] [CITE[HTTP/0.9は今でも使われている? - Qiita]]
(@hakatashi 2017年12月10日に更新 [TIME[2019-04-23 20:43:54 +09:00]])
<https://qiita.com/hakatashi/items/7bdbcab2067406003866>

[63] [CITE@en[669800 - Shoutcast streams on non-standard port would no longer play - chromium - Monorail]]
([TIME[2019-08-14 15:56:11 +09:00]])
<https://bugs.chromium.org/p/chromium/issues/detail?id=669800>

[80] [CITE@en[869725 - support shoutcast streams]], [TIME[2025-09-11T15:43:59.000Z]] <https://bugzilla.mozilla.org/show_bug.cgi?id=869725>


- [65] [CITE@en[<6 bytes HTTP responses "vanish" · Issue #2420 · curl/curl · GitHub]], [TIME[2021-02-08T09:30:44.000Z]] <https://github.com/curl/curl/issues/2420>
- [66] [CITE@en[http: fix for tiny "HTTP/0.9" response by bagder · Pull Request #2872 · curl/curl · GitHub]], [TIME[2021-02-08T09:31:03.000Z]] <https://github.com/curl/curl/pull/2872>

[67] [CITE@en[Make HTTP/0.9 opt-in · Issue #2873 · curl/curl · GitHub]], [TIME[2021-02-08T09:31:24.000Z]] <https://github.com/curl/curl/issues/2873>

[68] [CITE@en[PHP: curl_setopt - Manual]], [TIME[2021-02-08T05:01:06.000Z]], [TIME[2021-02-08T09:31:43.219Z]] <https://www.php.net/manual/en/function.curl-setopt.php>

[72] [CITE@ja[MiyahanさんはTwitterを使っています: 「2022年に HTTP/0.9 しか喋れない謎サーバーの監視依頼が来て泡吹いて倒れてる。 現代の主要な監視システムではHTTP監視できないので、curl --http0.9 コマンドを叩くカスタム監視を実装するしかない?」 / Twitter]], [TIME[午後2:23 · 2022年11月18日][2022-11-18T05:23:58.000Z]], [TIME[2022-11-20T14:26:17.000Z]] <https://twitter.com/miyahancom/status/1593475079069138944>



[74] 最近インストールした nginx : [[HTTP/0.9]] 要求に [[HTTP/0.9]] [[応答]]を返しました [TIME[2025-09-11T15:33:40.759Z]]

[75] [[Cloudflare]] port 80 : Bad request とかかれた [[HTTP/0.9]] [[応答]]を返しました。 [TIME[2025-09-11T15:34:26.078Z]]

[76] [CODE[google.com]] port 80 : [[HTTP/1.0]] 応答を返しました。 [TIME[2025-09-11T15:34:43.704Z]]

[77] [[CloudFront]] port 80 : [CODE[505]] エラー[[応答]]の [[HTTP/0.9]] [[応答]]を返しました。  [TIME[2025-09-11T15:36:14.471Z]]

[78] [[AWS]] [[ALB]] port 80 : [[HTTP/0.9]] 応答を返しました。 (通常の[[応答]]のうち[[本体]]部分のみで[[状態符号]]や[[ヘッダー]]はなし) [TIME[2025-09-11T15:39:22.534Z]]