LoginSignup
1
0

CodeCraftersで「Build your own HTTP server」を(無料の範囲で)やってみよう

Posted at

CodeCraftersで「HTTPサーバー」を作ってみたくなったのでやっていきます。


CodeCraftersの各webページ

CodeCraftersの主要ページは以下のような構成になっているようです。


GitHubアカウントと連携

CodeCraftersを利用するにはGitHubアカウントでログインする必要があるので、その対応を行っていきます。

まずは、製品紹介ページにアクセスします。

Screenshot from 2024-02-24 11-14-47.png

画面右上の「Try now」をクリックします。

image.png

「Challenges」の画面に切り替わります。

image.png

画面右上の「Sign in with GitHub」をクリックします。

Screenshot from 2024-02-21 13-38-08.png

権限を確認して問題なければ「Authorize codecrafters-io」をクリックします。

Screenshot from 2024-02-21 13-38-48.png

いくつかアンケートが表示されるので適宜答えましょう。

Screenshot from 2024-02-21 13-40-12.png

私は「PHPerKaigi 2023」のげんえいさんの登壇で知ったので、「How did you hear about CodeCrafters?」の質問には「Friend」、「Conference」と回答しました。

Screenshot from 2024-02-21 13-41-19.png


「Introduction」のステップで利用言語やアンケートに回答

アンケートに回答すると「Challenges」の画面に戻ってくるので、「Build your own HTTP server」を選択して、「Start Building」をクリックします。

Screenshot from 2024-02-21 13-43-42.png

「Introduction」の画面に遷移し、どの言語を利用したいか選択肢が表示されます。
image.png

PHPで解くつもりだったのですが、未実装のようなので今回は「Java」を選択しました。
image.png

次に言語の習熟度についての質問が表示されます。
image.png

「Javaなんもわからん」なので「Beginner」を選択しました。
image.png

次に言語の利用状況についての質問が表示されます。
image.png

仕事で週に数回程度は触っているので「Few times a week」を選択しました。
image.png

最後にメールのオプトインに関する質問が表示されます。
image.png

今回は不要なので「I'll pass」を選択しました。すると、画面下段に「Continue →」のボタンが表示されます。
image.png

「Introduction」の質問にすべて回答すると画面上段に「Completed」と表示され、「View next step →」のボタンが表示されます。
image.png

画面左側のメニューの「Introduction」に✅が表示されます。
Screenshot from 2024-02-24 15-48-14.png

画面上段の「View next step →」もしくは画面下段の「Continue →」をクリックします。


「Repository Setup」のステップでリポジトリのcloneとpushを実行

「Repository Setup」の画面に遷移し、ここから以降の作業で必要となるGitリポジトリのURLが表示されます。
Screenshot from 2024-02-24 15-51-36.png

「Step 1」としてリポジトリをcloneするように指示されていますので、表示されているコマンドを実行します。

$ git clone https://git.codecrafters.io/XXXXXXXXXXXXXXXX codecrafters-http-server-java && cd codecrafters-http-server-java
Cloning into 'codecrafters-http-server-java'...
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 12 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (12/12), 2.78 KiB | 712.00 KiB/s, done.

「Step 2」では --allow-empty を使って空コミットを行うように指示されていますので、表示されているコマンドを実行します。

$ git commit --allow-empty -m 'test' && git push origin master
[master 8367fc1] test
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 172 bytes | 172.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
remote: ------------------------------------------------------------------------
remote: 
remote: 
remote:      ___            _          ___              __  _                   
remote:     / __\ ___    __| |  ___   / __\_ __  __ _  / _|| |_  ___  _ __  ___ 
remote:    / /   / _ \  / _` | / _ \ / /  | '__|/ _` || |_ | __|/ _ \| '__|/ __|
remote:   / /___| (_) || (_| ||  __// /___| |  | (_| ||  _|| |_|  __/| |   \__ 
remote:   \____/ \___/  \__,_| \___|\____/|_|   \__,_||_|   \__|\___||_|   |___/
remote: 
remote: 
remote:    Welcome to CodeCrafters! Your commit was received successfully.
remote: 
remote: ------------------------------------------------------------------------
remote: 
remote: Running tests on your codebase. Streaming logs...
remote: 
remote: [compile] [INFO] Scanning for projects...
remote: [compile] [INFO] 
remote: [compile] [INFO] ----------------< io.codecrafters:build-your-own-http >-----------------
remote: [compile] [INFO] Building build-your-own-http 1.0
remote: [compile] [INFO]   from pom.xml
remote: [compile] [INFO] --------------------------------[ jar ]---------------------------------
remote: [compile] [INFO] 
remote: [compile] [INFO] --- resources:3.3.1:resources (default-resources) @ build-your-own-http ---
remote: [compile] [INFO] skip non existing resourceDirectory /app/src/main/resources
remote: [compile] [INFO] 
remote: [compile] [INFO] --- compiler:3.11.0:compile (default-compile) @ build-your-own-http ---
remote: [compile] [INFO] Changes detected - recompiling the module! :source
remote: [compile] [INFO] Compiling 1 source file with javac [debug target 21] to target/classes
remote: [compile] [INFO] 
remote: [compile] [INFO] --- resources:3.3.1:testResources (default-testResources) @ build-your-own-http ---
remote: [compile] [INFO] skip non existing resourceDirectory /app/src/test/resources
remote: [compile] [INFO] 
remote: [compile] [INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ build-your-own-http ---
remote: [compile] [INFO] No sources to compile
remote: [compile] [INFO] 
remote: [compile] [INFO] --- surefire:3.1.2:test (default-test) @ build-your-own-http ---
remote: [compile] [INFO] No tests to run.
remote: [compile] [INFO] 
remote: [compile] [INFO] --- jar:3.3.0:jar (default-jar) @ build-your-own-http ---
remote: [compile] [INFO] Building jar: /app/target/build-your-own-http-1.0.jar
remote: [compile] [INFO] 
remote: [compile] [INFO] --- assembly:3.6.0:single (make-assembly) @ build-your-own-http ---
remote: [compile] [INFO] Building jar: /tmp/codecrafters-http-target/java_http.jar
remote: [compile] [WARNING] Configuration option 'appendAssemblyId' is set to false.
remote: [compile] Instead of attaching the assembly file: /tmp/codecrafters-http-target/java_http.jar, it will become the file for main project artifact.
remote: [compile] NOTE: If multiple descriptors or descriptor-formats are provided for this project, the value of this file will be non-deterministic!
remote: [compile] [WARNING] Replacing pre-existing project main-artifact file: /app/target/build-your-own-http-1.0.jar
remote: [compile] with assembly file: /tmp/codecrafters-http-target/java_http.jar
remote: [compile] [INFO] ------------------------------------------------------------------------
remote: [compile] [INFO] BUILD SUCCESS
remote: [compile] [INFO] ------------------------------------------------------------------------
remote: [compile] [INFO] Total time:  2.197 s
remote: [compile] [INFO] Finished at: 2024-02-24T08:16:50Z
remote: [compile] [INFO] ------------------------------------------------------------------------
remote: [compile] Compilation successful.
remote: 
remote: [stage-1] Running tests for Stage #1: Bind to a port
remote: [stage-1] Connecting to localhost:4221 using TCP
remote: [your_program] Logs from your program will appear here!
remote: [stage-1] Looks like your program has terminated. A HTTP server is expected to be a long-running process.
remote: [stage-1] Test failed (try setting 'debug: true' in your codecrafters.yml to see more details)
remote: 
remote: View stage instructions: https://app.codecrafters.io/courses/http-server.
remote: 
To https://git.codecrafters.io/XXXXXXXXXXXXXXXX
   c4bb38d..8367fc1  master -> master

pushが成功すると「Listening for a git push...」というメッセージが「🎉 Git push received! The first stage is now activated.」に切り替わり、画面下段に「Continue →」のボタンが表示されます。
image.png

「Repository Setup」のすべてのステップの対応が完了すると画面上段に「Completed」と表示され、「View next stage →」のボタンが表示されます。
image.png

画面左側のメニューの「Repository Setup」に✅が表示されます。
image.png

画面上段の「View next stage →」もしくは画面下段の「Continue →」をクリックします。


「Bind to a port」のタスク

「Bind to a port」の画面に遷移するので、「Your Task」を参照します。
※テストの失敗については先程のpush実行時のログにも表示されていましたが、画面上にも表示されています。
image.png

このステージで行うべきタスクの内容は以下のとおりです。

  • 4221番ポートでTCPサーバーを起動すること。

「How to pass this stage」の「Step 1」にヒントというか答えが書いてあります。

image.png

ヒントのとおりプログラムを修正して、「Step 2」の指示のとおりpushを実行します。
image.png

$ git add .
$ git commit -m "pass 1st stage"
[master 8489766] pass 1st stage
 1 file changed, 12 insertions(+), 12 deletions(-)
$ git push origin master
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (6/6), 483 bytes | 483.00 KiB/s, done.
Total 6 (delta 2), reused 0 (delta 0), pack-reused 0
remote: ------------------------------------------------------------------------
remote: 
remote: 
remote:      ___            _          ___              __  _                   
remote:     / __\ ___    __| |  ___   / __\_ __  __ _  / _|| |_  ___  _ __  ___ 
remote:    / /   / _ \  / _` | / _ \ / /  | '__|/ _` || |_ | __|/ _ \| '__|/ __|
remote:   / /___| (_) || (_| ||  __// /___| |  | (_| ||  _|| |_|  __/| |   \__ 
remote:   \____/ \___/  \__,_| \___|\____/|_|   \__,_||_|   \__|\___||_|   |___/
remote: 
remote: 
remote:    Welcome to CodeCrafters! Your commit was received successfully.
remote: 
remote: ------------------------------------------------------------------------
remote: 
remote: Running tests on your codebase. Streaming logs...
remote: 
remote: [compile] [INFO] Scanning for projects...
remote: [compile] [INFO] 
remote: [compile] [INFO] ----------------< io.codecrafters:build-your-own-http >-----------------
remote: [compile] [INFO] Building build-your-own-http 1.0
remote: [compile] [INFO]   from pom.xml
remote: [compile] [INFO] --------------------------------[ jar ]---------------------------------
remote: [compile] [INFO] 
remote: [compile] [INFO] --- resources:3.3.1:resources (default-resources) @ build-your-own-http ---
remote: [compile] [INFO] skip non existing resourceDirectory /app/src/main/resources
remote: [compile] [INFO] 
remote: [compile] [INFO] --- compiler:3.11.0:compile (default-compile) @ build-your-own-http ---
remote: [compile] [INFO] Changes detected - recompiling the module! :source
remote: [compile] [INFO] Compiling 1 source file with javac [debug target 21] to target/classes
remote: [compile] [INFO] 
remote: [compile] [INFO] --- resources:3.3.1:testResources (default-testResources) @ build-your-own-http ---
remote: [compile] [INFO] skip non existing resourceDirectory /app/src/test/resources
remote: [compile] [INFO] 
remote: [compile] [INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ build-your-own-http ---
remote: [compile] [INFO] No sources to compile
remote: [compile] [INFO] 
remote: [compile] [INFO] --- surefire:3.1.2:test (default-test) @ build-your-own-http ---
remote: [compile] [INFO] No tests to run.
remote: [compile] [INFO] 
remote: [compile] [INFO] --- jar:3.3.0:jar (default-jar) @ build-your-own-http ---
remote: [compile] [INFO] Building jar: /app/target/build-your-own-http-1.0.jar
remote: [compile] [INFO] 
remote: [compile] [INFO] --- assembly:3.6.0:single (make-assembly) @ build-your-own-http ---
remote: [compile] [INFO] Building jar: /tmp/codecrafters-http-target/java_http.jar
remote: [compile] [WARNING] Configuration option 'appendAssemblyId' is set to false.
remote: [compile] Instead of attaching the assembly file: /tmp/codecrafters-http-target/java_http.jar, it will become the file for main project artifact.
remote: [compile] NOTE: If multiple descriptors or descriptor-formats are provided for this project, the value of this file will be non-deterministic!
remote: [compile] [WARNING] Replacing pre-existing project main-artifact file: /app/target/build-your-own-http-1.0.jar
remote: [compile] with assembly file: /tmp/codecrafters-http-target/java_http.jar
remote: [compile] [INFO] ------------------------------------------------------------------------
remote: [compile] [INFO] BUILD SUCCESS
remote: [compile] [INFO] ------------------------------------------------------------------------
remote: [compile] [INFO] Total time:  2.186 s
remote: [compile] [INFO] Finished at: 2024-02-24T08:46:44Z
remote: [compile] [INFO] ------------------------------------------------------------------------
remote: [compile] Compilation successful.
remote: 
remote: [stage-1] Running tests for Stage #1: Bind to a port
remote: [stage-1] Connecting to localhost:4221 using TCP
remote: [your_program] Logs from your program will appear here!
remote: [stage-1] Success! Closing connection
remote: [stage-1] Test passed.
remote: [your_program] accepted new connection
remote: 
remote: All tests ran successfully. Congrats!
remote: 
remote: View instructions for the next stage: https://app.codecrafters.io/courses/http-server
remote: 
To https://git.codecrafters.io/XXXXXXXXXXXXXXXX
   8367fc1..8489766  master -> master

pushを実行すると、以下のようなメッセージからビルドとテストが実行されていることがわかります。
つまり、各ステージで提示されているタスク内容を元にプログラムの修正を行い、テストをパスすることで次のステージに進める仕組みのようです。

remote: [compile] [INFO] Building build-your-own-http 1.0
・
・
remote: [compile] [INFO] BUILD SUCCESS
・
・
remote: [compile] Compilation successful.
remote: [stage-1] Running tests for Stage #1: Bind to a port
remote: [stage-1] Connecting to localhost:4221 using TCP
・
・
remote: [stage-1] Test passed.
・
・
remote: All tests ran successfully. Congrats!

テストをパスすると「Your Task」の欄に「Completed」と表示され、「View Next Stage →」のボタンが表示されます。

image.png

「Bind to a port」のすべてのステップの対応が完了すると画面上段に「Completed」と表示され、「View next stage →」のボタンが表示されます。
image.png

画面左側のメニューの「Bind to a port」に✅が表示されます。
image.png

画面上段もしくは「Your Task」の欄の「View Next Stage →」をクリックします。


「Respond with 200」のタスク

「Respond with 200」の画面に遷移するので、「Your Task」を参照します。
image.png

このステージで行うべきタスクの内容は以下のとおりです。

  • TCP接続を受け付けます。
  • TCP接続の受信内容を読み取ります。(読み取った内容の解析は後のステージで行います)
  • HTTPレスポンスとして以下を返します。
    • ステータスライン( HTTP/1.1 200 OK\r\n\r\n )
  • 受信した他の内容は無視して構いません。(「Parse headers」というステージが控えているので、あとでこのあたりは対応することになると思われます)

解き方がわからなければ「Code Examples」のタブを参考にしましょう。

image.png

プログラムを修正して、「Step 2」の指示のとおりpushを実行します。
image.png

$ git add .
$ git commit -m "pass 2nd stage"
[master cbaf07a] pass 2nd stage
 1 file changed, 14 insertions(+), 4 deletions(-)
$ git push origin master
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (6/6), 674 bytes | 674.00 KiB/s, done.
Total 6 (delta 2), reused 0 (delta 0), pack-reused 0
remote: ------------------------------------------------------------------------
remote: 
remote: 
remote:      ___            _          ___              __  _                   
remote:     / __\ ___    __| |  ___   / __\_ __  __ _  / _|| |_  ___  _ __  ___ 
remote:    / /   / _ \  / _` | / _ \ / /  | '__|/ _` || |_ | __|/ _ \| '__|/ __|
remote:   / /___| (_) || (_| ||  __// /___| |  | (_| ||  _|| |_|  __/| |   \__ 
remote:   \____/ \___/  \__,_| \___|\____/|_|   \__,_||_|   \__|\___||_|   |___/
remote: 
remote: 
remote:    Welcome to CodeCrafters! Your commit was received successfully.
remote: 
remote: ------------------------------------------------------------------------
remote: 
remote: Running tests on your codebase. Streaming logs...
remote: 
remote: [compile] [INFO] Scanning for projects...
remote: [compile] [INFO] 
remote: [compile] [INFO] ----------------< io.codecrafters:build-your-own-http >-----------------
remote: [compile] [INFO] Building build-your-own-http 1.0
remote: [compile] [INFO]   from pom.xml
remote: [compile] [INFO] --------------------------------[ jar ]---------------------------------
remote: [compile] [INFO] 
remote: [compile] [INFO] --- resources:3.3.1:resources (default-resources) @ build-your-own-http ---
remote: [compile] [INFO] skip non existing resourceDirectory /app/src/main/resources
remote: [compile] [INFO] 
remote: [compile] [INFO] --- compiler:3.11.0:compile (default-compile) @ build-your-own-http ---
remote: [compile] [INFO] Changes detected - recompiling the module! :source
remote: [compile] [INFO] Compiling 1 source file with javac [debug target 21] to target/classes
remote: [compile] [INFO] 
remote: [compile] [INFO] --- resources:3.3.1:testResources (default-testResources) @ build-your-own-http ---
remote: [compile] [INFO] skip non existing resourceDirectory /app/src/test/resources
remote: [compile] [INFO] 
remote: [compile] [INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ build-your-own-http ---
remote: [compile] [INFO] No sources to compile
remote: [compile] [INFO] 
remote: [compile] [INFO] --- surefire:3.1.2:test (default-test) @ build-your-own-http ---
remote: [compile] [INFO] No tests to run.
remote: [compile] [INFO] 
remote: [compile] [INFO] --- jar:3.3.0:jar (default-jar) @ build-your-own-http ---
remote: [compile] [INFO] Building jar: /app/target/build-your-own-http-1.0.jar
remote: [compile] [INFO] 
remote: [compile] [INFO] --- assembly:3.6.0:single (make-assembly) @ build-your-own-http ---
remote: [compile] [INFO] Building jar: /tmp/codecrafters-http-target/java_http.jar
remote: [compile] [WARNING] Configuration option 'appendAssemblyId' is set to false.
remote: [compile] Instead of attaching the assembly file: /tmp/codecrafters-http-target/java_http.jar, it will become the file for main project artifact.
remote: [compile] NOTE: If multiple descriptors or descriptor-formats are provided for this project, the value of this file will be non-deterministic!
remote: [compile] [WARNING] Replacing pre-existing project main-artifact file: /app/target/build-your-own-http-1.0.jar
remote: [compile] with assembly file: /tmp/codecrafters-http-target/java_http.jar
remote: [compile] [INFO] ------------------------------------------------------------------------
remote: [compile] [INFO] BUILD SUCCESS
remote: [compile] [INFO] ------------------------------------------------------------------------
remote: [compile] [INFO] Total time:  2.214 s
remote: [compile] [INFO] Finished at: 2024-02-24T10:13:50Z
remote: [compile] [INFO] ------------------------------------------------------------------------
remote: [compile] Compilation successful.
remote: 
remote: [stage-1] Running tests for Stage #1: Bind to a port
remote: [stage-1] Connecting to localhost:4221 using TCP
remote: [your_program] Logs from your program will appear here!
remote: [stage-1] Success! Closing connection
remote: [stage-1] Test passed.
remote: 
remote: [stage-2] Running tests for Stage #2: Respond with 200
remote: [stage-2] You can use the following curl command to test this locally
remote: [stage-2] $ curl -v -X GET http://localhost:4221/
remote: [stage-2] Sending request (status line): GET / HTTP/1.1
remote: [your_program] Logs from your program will appear here!
remote: [stage-2] Test passed.
remote: 
remote: All tests ran successfully. Congrats!
remote: 
remote: View instructions for the next stage: https://app.codecrafters.io/courses/http-server
remote: 
To https://git.codecrafters.io/XXXXXXXXXXXXXXXX
   8489766..cbaf07a  master -> master

テストをパスすると「Your Task」の欄に「Completed」と表示され、「View Next Stage →」のボタンが表示されます。
image.png

「Respond with 200」のすべてのステップの対応が完了すると画面上段に「Completed」と表示され、「View next stage →」のボタンが表示されます。

image.png

画面左側のメニューの「Respond with 200」に✅が表示されます。
image.png

画面上段もしくは「Your Task」の欄の「View Next Stage →」をクリックします。


「Respond with 404」のタスク

「Respond with 404」の画面に遷移します。ここで、「This stage requires a CodeCrafters Membership.」と表示され、有料会員になることが求められます。
image.png

ということで、ここから以降はそこそこの料金を支払う必要があるようです。
image.png


せっかくなので、「Respond with 404」以降のタスクの内容だけでも確認しましょう。

「Respond with 404」の「Your Task」を参照します。
image.png

このステージで行うべきタスクの内容は以下のとおりです。

  • HTTPリクエストのリクエストライン(例: GET /index.html HTTP/1.1 )からパス部分を抽出します。
  • 条件に合致する場合、HTTPレスポンスとして以下を返します。
    • HTTPメソッドが GET の場合
      • パスが / の場合
        • HTTP/1.1 200 OK
      • パスが / 以外の場合
        • HTTP/1.1 404 Not Found
  • Host: localhost:4221User-Agent: curl/7.64.1 はリクエストヘッダーです。(今回のステージでは利用しません)

「Respond with content」のタスク

「Respond with content」の「Your Task」を参照します。
image.png

このステージで行うべきタスクの内容は以下のとおりです。

  • ここまでのステージではHTTPレスポンスとしてステータスラインのみを返していましたが、このステージではbodyも返します。
  • HTTPリクエストのリクエストライン(例: GET /echo/abc HTTP/1.1 )からパス部分を抽出します。
  • 条件に合致する場合、HTTPレスポンスとして以下を返します。
    • HTTPメソッドが GET の場合
      • パスが /echo/<ランダムな文字列> の場合、 /echo/ 以降の <ランダムな文字列> の部分をbodyとして返します。
        HTTP/1.1 200 OK
        Content-Type: text/plain
        Content-Length: <ランダムな文字列>に応じたサイズ
        
        <ランダムな文字列>
        

「Parse headers」のタスク

「Parse headers」の「Your Task」を参照します。
image.png

このステージで行うべきタスクの内容は以下のとおりです。

  • HTTPリクエストのリクエストライン(例: GET /user-agent HTTP/1.1 )からパス部分を抽出します。
  • 条件に合致する場合、HTTPレスポンスとして以下を返します。
    • HTTPメソッドが GET の場合
      • パスが /user-agent の場合
        • リクエストヘッダーに User-Agent を含む場合、 User-Agent の値をbodyとして返します。
          HTTP/1.1 200 OK
          Content-Type: text/plain
          Content-Length: <User-Agent>の値に応じたサイズ
          
          <User-Agent>の値
          

「Concurrent connections」のタスク

「Concurrent connections」の「Your Task」を参照します。
image.png

このステージで行うべきタスクの内容は以下のとおりです。

  • ここまでのステージでは、1つの接続(HTTPリクエスト)に対してのみ、HTTPレスポンスを返すように実装してきました。
  • このステージでは複数同時接続を考慮し、HTTPリクエストが複数来てもそれぞれにHTTPレスポンスを返すように実装します。

「Get a file」のタスク

「Get a file」の「Your Task」を参照します。
image.png

このステージで行うべきタスクの内容は以下のとおりです。

  • テストでは、「 ./your_server.sh --directory <ディレクトリ名> 」のようにプログラムを実行します。
  • HTTPリクエストのリクエストライン(例: GET /files/ファイル名 HTTP/1.1 )からパス部分を抽出します。
  • 条件に合致する場合、HTTPレスポンスとして以下を返します。
    • HTTPメソッドが GET の場合
      • パスが /files/<ファイル名> の場合
        • 対象ファイルが --directory <ディレクトリ名> で指定されたディレクトリ内に存在する場合
          HTTP/1.1 200 OK
          Content-Type: application/octet-stream
          Content-Length: 対象ファイルのサイズ
          
          対象ファイルの内容
          
        • 対象ファイルが --directory <ディレクトリ名> で指定されたディレクトリ内に存在しない場合
          HTTP/1.1 404 Not Found
          

「Post a file」のタスク

「Post a file」の「Your Task」を参照します。
image.png

このステージで行うべきタスクの内容は以下のとおりです。

  • テストでは、「 ./your_server.sh --directory <ディレクトリ名> 」のようにプログラムを実行します。
  • HTTPリクエストのリクエストライン(例: POST /files/ファイル名 HTTP/1.1 )からパス部分を抽出します。
  • 条件に合致する場合、HTTPレスポンスとして以下を返します。
    • HTTPメソッドが POST の場合
      • パスが /files/<ファイル名> の場合
        • 対象ファイルを --directory <ディレクトリ名> で指定されたディレクトリ内に保存する。
        • ファイルの保存に成功したら以下を返す。
          HTTP/1.1 201 Created
          Content-Type: application/octet-stream
          Content-Length: 保存したファイルのサイズ
          
          保存したファイルの内容
          

CodeCraftersをやってみた感想

有料版の壁の件を把握していなかったので、やる前の「HTTPサーバー作るぞ」という気持ちを打ち砕かれて、終盤はちょっと残念な感じになってしまいましたが、最後にCodeCraftersをやってみた感想を少しだけ。

今回は「Build your own HTTP server」を触ってみましたが、普段仕事で利用しているHTTPサーバーなどの仕組みを知るきっかけとしては、CodeCraftersはとても良い教材だと思いました。

もちろん、「Build your own HTTP server」の各ステージをクリアしただけでは、「HTTPサーバー完全に理解した」という域に達することにはなりませんが、こういった複雑で難しそうなアプリケーションも小さな機能の集合体なので、少しずつ理解を深めていくきっかけになるのではないでしょうか。

ということで、CodeCraftersには様々な言語とアプリケーションを学べるように準備されていますので、ぜひチャレンジしてみてください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0