telnetでHTTP GETリクエストを送ってみる

```
$ sudo apt-get purge apache2
```

インストール後、最初からApacheは起動されている。自動起動もON

```
$ systemctl status apache2
● apache2.service - The Apache HTTP Server
   Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
  Drop-In: /lib/systemd/system/apache2.service.d
           mqapache2-systemd.conf
   Active: active (running) since Thu 2018-01-11 11:07:01 JST; 8s ago

$ systemctl is-enabled apache2
enabled
```

デフォルトでインストールされてるFirefoxでlocalhostにつないでテストページを表示する

![image.png](https://qiita-image-store.s3.amazonaws.com/0/212124/35c78733-be61-c7bf-aceb-1caffd7b9480.png)

テストページを右クリックしてソースを表示。
このソースの内容をtelnetで取得するのが目的。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/212124/f58e713e-a56f-e797-cf5d-a79543372902.png)

Ubuntu17.04ではtelnetはデフォルトでインストールされている
telnetでApacheに接続

```
$ telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
```

HTTPリクエストをおくってみる。
フォーマットはWikipediaがくわしい。
https://ja.wikipedia.org/wiki/Hypertext_Transfer_Protocol

```
HTTP/0.9
GET /index.html

HTTP/1.0
GET /index.html HTTP/1.0

HTTP/1.1
GET /index.html HTTP/1.1
Host: foo.example.com

HTTP/2
*HTTP/1.1と同じ
```

HTTP/1.1しか使わないけど、0.9ではプロトコルバージョンの指定がいらないし、1.0まではFQDNなしでもOKだったんですね。へ～知らなかった。

以下を入力して実行する

```
GET / HTTP/1.1
host: localhost
```

とれた。Firefoxで見たソースと同じですね。

```
HTTP/1.1 200 OK
Date: Thu, 11 Jan 2018 02:34:23 GMT
Server: Apache/2.4.25 (Ubuntu)
Last-Modified: Thu, 11 Jan 2018 02:07:00 GMT
ETag: "2aa6-562769a6d0c39"
Accept-Ranges: bytes
Content-Length: 10918
Vary: Accept-Encoding
Content-Type: text/html

<!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">
  <!--
    Modified from the Debian original for Ubuntu
    Last updated: 2016-11-16
    See: https://launchpad.net/bugs/1288690
  -->
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Apache2 Ubuntu Default Page: It works</title>
    <style type="text/css" media="screen">
  * {
    margin: 0px 0px 0px 0px;
    padding: 0px 0px 0px 0px;
  }
...
```

リクエストメソッドのフォーマットを間違えてみる。

- 1. GETが小文字

```
get / HTTP/1.1
host: localhost

HTTP/1.1 501 Not Implemented
Date: Thu, 11 Jan 2018 02:20:08 GMT
Server: Apache/2.4.25 (Ubuntu)
Allow: POST,OPTIONS,HEAD,HEAD,GET,HEAD
Content-Length: 276
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>501 Not Implemented</title>
</head><body>
<h1>Not Implemented</h1>
<p>get to /index.html not supported.<br />
</p>
<hr>
<address>Apache/2.4.25 (Ubuntu) Server at localhost Port 80</address>
</body></html>
Connection closed by foreign host.
```

- 2. HTTP/0.9のフォーマットで指定

```
GET /
```

StatusCode200で正常にレスポンス返ってきた
きっと最近のApacheだとプロトコルバージョンの指定がなければHTTP/1.1と解釈するとか、Host指定も省略が可能(localhostと解釈)とかなってるんだろうと勝手に想像。

- 3. HTTP/0.9を明示的に指定してみる

```
GET / HTTP/0.9

HTTP/1.1 400 Bad Request
Date: Thu, 11 Jan 2018 02:28:50 GMT
Server: Apache/2.4.25 (Ubuntu)
Content-Length: 301
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
<hr>
<address>Apache/2.4.25 (Ubuntu) Server at 127.0.1.1 Port 80</address>
</body></html>
Connection closed by foreign host.
```

ちゃんとBad Requestになる

- 4. HTTP/1.0を明示的に指定する

```
GET / HTTP/1.0
```

StatusCode200で正常にレスポンス返ってきた

ここでtelnet前に間違ってGET / HTTP/1.0をターミナルに貼り付けて実行したら、なんかレスポンスが返ってきた
なんとubuntuにはHTTPリクエスト送るGETってコマンドが用意されてる模様。

ここからちょっとGETコマンドの説明。

```
$ GET --help
Unknown option: help
Usage: GET [-options] <url>...
    -m <method>   use method for the request (default is 'GET')
    -f            make request even if GET believes method is illegal
    -b <base>     Use the specified URL as base
    -t <timeout>  Set timeout value
    -i <time>     Set the If-Modified-Since header on the request
    -c <conttype> use this content-type for POST, PUT, CHECKIN
    -a            Use text mode for content I/O
    -p <proxyurl> use this as a proxy
    -P            don't load proxy settings from environment
    -H <header>   send this HTTP header (you can specify several)
    -C <username>:<password>
                  provide credentials for basic authentication

    -u            Display method and URL before any response
    -U            Display request headers (implies -u)
    -s            Display response status code
    -S            Display response status chain (implies -u)
    -e            Display response headers (implies -s)
    -E            Display whole chain of headers (implies -S and -U)
    -d            Do not display content
    -o <format>   Process HTML content in various ways

    -v            Show program version
    -h            Print this message
```

ただページ取得したければ```$ GET localhost``` でOK。
ステータスコード、レスポンスヘッダーは出力されない。

GETの説明終わり。
あとでPOSTリクエストも試してみる。
(テストページではできないのでフォームページとか作らないと)