いづいづブログ

アジャイルコーチになりたい札幌在住SEです。アジャイル札幌スタッフ&ScrumFestSapporo実行委員。Like:パクチー/激辛/牡蠣/猫/初期仏教

HTTPの基本1 #2 telnetでGETとPOSTを試してみる

はじめてのアドベントカレンダー Advent Calendar 2018 - Adventarの12/24の記事です。 読み物でもないし完全に自分がやったことのメモでしかないんですが、初めてtelnetでHTTPメソッドを実行する、ということをやった結果ほぼ1日を費やす羽目になるくらいはまってしまい、せっかくなのでブログにしました。

mactelnetをインストールする

とりあえずtelnetコマンドを実行してみる。

$ telnet
-bash: telnet: command not found

ないって。telnetを使うには入れないとだめらしい。

ということでtelnetをインストールするんだけど、先にHomebrewを更新して最新にしておく。
何かをインストールする前にはおまじないのようにこの2つのコマンドをセットで実行しておくのがいいと思う。

$ brew update
$ brew upgrade

でインストール実行

$ brew install telnet

telnetを実行する。OK。

$ telnet
telnet> 

GETリクエストを送信

接続先はGET/POST練習用に用意されたサイトを使用した。

telnetでWebサーバーに接続】

telnethttps通信はできずhttp通信になるため、ポート番号は80番を使用する。 (TCP/80 : HTTP、TCP/443 : HTTPS

$ telnet dummy-bootcamp-fjord-jp.herokuapp.com 80
Trying XX.XX.XX.XX...
Connected to XXXXXXX.route.herokuapp.com.
Escape character is '^]'.

telnetの後に接続するホスト名かIPアドレスを指定し、ポート番号の「80」を記述する。 Escape character is '^]'.が出てきたら入力待ち状態になっているのでOK。
telnet」の後ろに「http://dummy-bootcamp-fjord-jp.herokuapp.com」と書くのは間違い。指定するのはホストかIPアドレスなので余計なことを書いちゃだめなのに、なにも考えずURLコピペしていたのでまずここで1ハマり。

【リクエストラインを記述】

GETリクエストを送信する。

GET /articles/1 HTTP/1.1

GETメソッドの後にパスを指定する。トップページにアクセスする場合は「/」だけでOKだけど今回は「articles/1.html」のページに対してGETリクエストを送る。最後にHTTPバージョンを記載(今回は2.0で通信できないため1.1で実行)

【リクエストヘッダを記述】

Host: dummy-bootcamp-fjord-jp.herokuapp.com

HTTP/1.1要求メッセージ送信用のメソッドで唯一必須。ホスト名を指定する(telnetで接続する時に書いたホスト名と同じ。)
まさか必須だと思わなくて、GETだけを一生懸命送信していてエラーになりまくりだった。HTTP/1.1で要求メッセージを投げるときは必ず必要!!ここで2ハマり。

そして3ハマり目が最後にEnterを2回押さないとだめだということ(1回目で空行入力、2回目で実行)。 1回だけしかEnterを押していなかったのでずーーーっと次入力待ち状態だったらしいんだけど、そんなの知らないからこっちもずーーーとまってた。

f:id:izumii-19:20181223001414p:plain:w400

【実行結果】

f:id:izumii-19:20181223001750p:plain:w400

レスポンスのステータスが200なので成功している。

POSTリクエストを送信

【リクエストラインを記述】

POSTリクエストを送信する。

POST /articles HTTP/1.1

POSTメソッドの後にパスを指定する。今回は要求を送って新しくページを1つ作るのでパスの指定は「/articles」までにする。後はGETのときと同じ。*1

【リクエストヘッダを記述】

Host: dummy-bootcamp-fjord-jp.herokuapp.com
Content-Length:48

Hostの指定はGETと同じ。
「Content-Length」はこの後のメッセージボディで記述するクエリの文字の長さを指定する(1byte文字テキストの長さ)。詳しくはこの後のメッセージボディに記述する。

【メッセージボディを記述】

今回は以下のように「Title」に"izumi"、「Body」に"body Comment"と表示されるようにしたい。

f:id:izumii-19:20181223003700p:plain:w400

なのでクエリは以下のように記述する。

(1行空けること)
article[title]=izumi&article[body]=body Comment

アイテム名は既に誰かによって作成済みのサンプルページがあったので、そのページのHTMLコードを表示してTitleに表示しているアイテムは「article[title]」、Bodyに表示しているアイテムは「article[body]」であることを確認した。けどこのアイテム名を探す方法をなかなか思いつくことができなかったせいで4ハマり。

f:id:izumii-19:20181223004029p:plain:w400

そしてこのarticle[title]=izumi&article[body]=body Commentの文字列が1バイト文字48個なのでリクエストヘッダには「Content-Length:48」と書く必要がある。
ここがわからなくて5ハマり…。

最後にEnterを押して実行する。

【実行結果】

f:id:izumii-19:20181223005150p:plain:w400

f:id:izumii-19:20181223005746p:plain:w400

レスポンスのステータスが「302 Found」になっている。どういう意味だろう。 一応思ったとおりのものはできているようだけど、ちゃんと理解できてない気がするなぁ。

*1:正直ちゃんとこの辺理解してない。