Name Last Update
assets/images Loading commit data...
src Loading commit data...
.gitignore Loading commit data...
404.html Loading commit data...
Cargo.lock Loading commit data...
Cargo.toml Loading commit data...
README.md Loading commit data...
hello.html Loading commit data...

Commit 1 Reflection notes

Dalam fungsi handle_connection, kita memproses request yang masuk dari browser. Berikut adalah penjelasan metode yang digunakan:

  1. BufReader::new(&mut stream): Kita membungkus TcpStream menggunakan BufReader. Ini bertujuan untuk menambahkan buffering, sehingga pembacaan data menjadi lebih efisien karena kita bisa memanggil fungsi seperti .lines() untuk membaca data baris per baris secara langsung, daripada membaca byte demi byte secara manual.
  2. .lines(): Mengubah BufReader menjadi iterator yang mengembalikan setiap baris teks dari stream.
  3. .map(|result| result.unwrap()): Karena setiap baris yang dibaca mengembalikan tipe Result (bisa sukses atau error), kita menggunakan .map() dan .unwrap() untuk mengekstrak nilai String dari Result::Ok secara langsung (mengasumsikan tidak ada error saat pembacaan demi kesederhanaan).
  4. .take_while(|line| !line.is_empty()): HTTP request header selalu diakhiri dengan dua buah newline (baris kosong). Fungsi ini akan terus membaca baris dari stream sampai menemukan baris kosong tersebut, lalu berhenti. Ini mencegah program hang karena menunggu data yang tidak akan dikirim lagi oleh browser.
  5. .collect(): Mengumpulkan semua baris teks yang sudah diproses di atas ke dalam sebuah koleksi vektor (Vec<_>), yang kemudian kita simpan ke variabel http_request untuk di-print.

Commit 2 Reflection notes

Commit 2 screen capture

Pada code yang baru ditambahkan di handle_connection, server sekarang mengirimkan response yang valid sesuai HTTP Protocol. Berikut hal baru yang dipelajari:

  1. fs::read_to_string("hello.html"): Digunakan untuk membaca seluruh isi file HTML dan mengubahnya menjadi tipe data String di Rust agar bisa dikirimkan sebagai body dari HTTP response.
  2. HTTP/1.1 200 OK: Ini adalah status line standar dari HTTP yang memberitahu browser bahwa request berhasil diproses.
  3. Content-Length: Header HTTP yang wajib disertakan agar browser tahu seberapa besar ukuran data (dalam byte) yang akan diterima. Kita menghitungnya menggunakan contents.len().
  4. Format Response (\r\n\r\n): Protokol HTTP mensyaratkan penggunaan CRLF (\r\n) untuk memisahkan setiap baris header. Selain itu, harus ada dua buah CRLF (\r\n\r\n) yang berfungsi sebagai pemisah mutlak antara bagian Headers dan bagian Body (isi konten HTML).
  5. stream.write_all: Mengirimkan seluruh string balasan yang sudah diformat tadi (diubah menjadi bytes) kembali melalui TCP stream ke browser.

Commit 3 Reflection notes

Commit 3 screen capture

Pada tahap ini, kita memvalidasi request HTTP yang masuk agar server tidak merespons semua request dengan hello.html.

  1. Cara memisahkan respons: Kita membaca baris pertama dari HTTP request (request_line). Jika baris tersebut sama persis dengan "GET / HTTP/1.1", kita mengembalikan hello.html dengan status 200 OK. Jika request line berupa hal lain (misalnya /bad), kita masuk ke blok else dan mengembalikan 404.html dengan status 404 NOT FOUND.
  2. Kenapa refactoring diperlukan: Pada awalnya, blok if dan else memiliki banyak duplikasi kode (seperti pemanggilan fs::read_to_string, penghitungan length, dan format response). Membiarkan kode duplikat bertentangan dengan prinsip Clean Code (DRY - Don't Repeat Yourself). Dengan melakukan refactoring, kita hanya menggunakan blok if-else untuk menentukan status_line dan filename, lalu mengeksekusi logika pembacaan file dan pengiriman respons secara universal di luar blok kondisi tersebut. Ini membuat kode lebih bersih, mudah dibaca, dan mudah di-maintenance jika nanti kita ingin menambahkan modifikasi pada format respons HTTP.