Litghttpd で 400 Bad Request エラー
docker-compose
内に立ち上げたLighttpd
の Web サーバーに他のコンテナからhttp://sample_1/
とホスト名(コンテナ名)でcurl
すると400 Bad Request
エラーが返ってくる。
しかし、IP アドレス(http://172.23.0.4/
)だと cURL
できるし、ホスト名の sample_1
には PING は通る。
$ # Localhost で取得 → OK
$ curl http://localhost/
<p>Hello World!</p>
$ # IPアドレス で取得 → OK
$ curl http://172.23.0.4/
<p>Hello World!</p>
$ # ホスト名で取得 → NG
$ curl http://sample_1/
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>400 Bad Request</title>
</head>
<body>
<h1>400 Bad Request</h1>
</body>
</html>
$ # ホスト名宛に PING → OK
$ ping -c 3 sample_1
PING app2-php (172.23.0.4): 56 data bytes
64 bytes from 172.23.0.4: seq=0 ttl=64 time=4.026 ms
64 bytes from 172.23.0.4: seq=1 ttl=64 time=0.206 ms
64 bytes from 172.23.0.4: seq=2 ttl=64 time=0.203 ms
--- sample_1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.203/1.478/4.026 ms
- 「lighttpdとは」の Qiita 記事 @ Google
- 「lighttpd」@ Wikipedia
TL;DR
ホスト名として利用できない文字が使われています。RFC2616 および RFC2396 で定義されている文字である必要があります。
ドットのないホスト名(トップレベル)は [a-zA-Z0-9-]
のみであるため、この場合 _
(アンダースコア/アンダーバー)が使われていることが原因です。
toplabel = alpha | alpha *( alphanum | "-" ) alphanum
TS;DR
docker-compose
で、Hello World
タグを返すだけのコンテナ名に sample_1
と付けて、他のコンテナから cURL
したところ取得できなくなりました。
docker-compose
は、コンテナ名(container_name
ディレクティブ)を指定すると、それをホスト名としても割り当ててくれます。
lighttpd
は起動時にホスト名のチェックを行うらしく、RFC に準拠していないホスト名によるアクセスは CGI に渡さないようです。
コンテナ名(ホスト名)のアンダーバーをハイフンに変え sample-1
に変更すると、他のコンテナからも HTTP リクエストのレスポンスをするようになりました。
こんなことあるのか。。。
参考文献
- Bug #2258 "Bad Request" | チケット | Lighttpd.net
RFC2616
14.23 Host
Host = "Host" ":" host [ ":" port ] ;
3.2.1 General Syntax
RFC 2396 [42] (which replaces RFCs
1738 [4] and RFC 1808 [11]). This specification adopts the
definitions of "URI-reference", "absoluteURI", "relativeURI", "port",
"host","abs_path", "rel_path", and "authority" from that
specification.
RFC2396
3.2.2. Server-based Naming Authority
host = hostname | IPv4address
hostname = *( domainlabel "." ) toplabel [ "." ]
domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
toplabel = alpha | alpha *( alphanum | "-" ) alphanum