---
# System prepended metadata

title: HTTP

---

# The HTTP Protocol
**HTTP** (*Hypertext Transfer Protocol*) là giao thức sử dụng để trao đổi thông tin qua Internet. HTTP giống như hệ thống phân phối thông tin qua Internet, nó đảm bảo được thông tin truyền từ nơi này sang nơi khác. Đó là nền tảng của World Wide Web.
HTTP là một giao thức ứng dụng của bộ giao thức TCP/IP (các giao thức nền tảng cho Internet).

![](https://hackmd.io/_uploads/rJRzkIGZa.png)

HTTP hoạt động dựa trên mô hình **Client – Server**.

![](https://hackmd.io/_uploads/Syj4mLGba.png)

Máy khách (Client) sẽ gửi yêu cầu (request) và máy chủ (Server) sẽ phản hồi lại.

HTTP là **stateless protocol**, không có liên kết nào giữa hai yêu cầu được thực hiện liên tiếp trên cũng một kết nối. Hay có thể nói, yêu cầu (request) hiện tại không biết những gì đã hoàn thành ở yêu cầu (request) trước đó.
HTTP Messages là cách dữ liệu được trao đổi giữa máy chủ (server) và máy khách (client). Có hai loại messages: request và respond.

## HTTP Requests

**HTTP Request** là thông tin được gửi từ client lên server để yêu cầu server tìm hay xử lý thông tin mà client muốn. HTTP request có thể là một file text dưới dạng XML hoặc Json mà cả hai đều có thể hiểu được.
**HTTP Request** gồm ba phần chính:

![](https://hackmd.io/_uploads/HkJ3gYf-p.png)

### Request Line

Dòng đầu tiên của HTTP request bao gồm 3 yếu tố:

![](https://hackmd.io/_uploads/SkFPh8MZ6.png)

- Phương thức (method) gồm nhiều loại, phổ biến nhất là `GET` và `POST`.
- Đường dẫn URL (path) có tác dụng định danh các nguồn tài nguyên được yêu cầu bởi client và bắt buộc phải có dấu `/`.
- Phiên bản giao thức (HTTP version): Đây là phiên bản HTTP client sử dụng, trong đó phổ biến nhất là `HTTP/1.0` và `HTTP/1.1`.



### Headers
Đây là thành phần giúp các yêu cầu từ client có thể chuyển đến server. Trong đó, mỗi yêu cầu chứa đựng các thông số (gọi là Header Parameters).
Header sẽ phân biệt chữ thường và chữ hoa, theo sau đó là dấu `.` và một giá trị.
Các thông số thường gặp:
- `User-Agent`: cho phép server xác định ứng dụng, hệ điều hành, nhà cung cấp và phiên bản.
- `Connection`: kiểm soát kết nối mạng, cho phép dừng hoặc tiếp tục kết nối sau khi server thực hiện xong yêu cầu.
- `Cache-Control`: chỉ định chính sách, bộ nhớ đệm của trình duyệt.
- `Accept-language`: cho biết tất cả các ngôn ngữ mà client có thể hiểu được.

### Body
Phần này chứa các dòng yêu cầu, thông tin, dòng trống, tiêu đề và nội dung. 

Cho phép client gừi đến yêu cầu bổ sung cần server thực hiện như: tạo mới hoặc cập nhật dữ liệu mà không thể truyền trên Header Parameters.
Request body thường được sử dụng trong các phương thức `POST`, `PUT`, `PATCH`.

Ví dụ: request tạo account mới, với 2 parameter là userName và password

![](https://hackmd.io/_uploads/r1eRS9Mb6.png)
      
## HTTP Responses 
HTTP Responses là kết quả server trả về cho client.

![](https://hackmd.io/_uploads/r1MeGoM-6.png)

Cú pháp đơn giản như sau:
```
<http-version> <status> <reason-pharse>

<headers>

<body>: nội dung thông báo
```

Cấu trúc HTTP Response gần giống với HTTP request. Điểm khác biệt là thay vì Request Line, HTTP có response có Status Line. Cấu trúc của Status line gồm 3 phần:

![](https://hackmd.io/_uploads/BJcJliz-p.png)

- HTTP version: Phiên bản HTTP cao nhất mà máy chủ hỗ trợ.
- Status Code: mã kết quả trả về.
- Reason phrase: mô tả thêm trạng thái của response.

## HTTP Methods
### `GET`
`GET` được sử dụng để yêu cầu dữ liệu từ một tài nguyên được chỉ định.
Lưu ý rằng chuỗi truy vấn (cặp name/value) được gửi trong URL của `GET`request:
```
/test/demo_form.php?name1=value1&name2=value2
```
Một số chú ý:
- `GET` có thể được lưu trữ
- `GET` còn trong lịch sử trình duyệt
- `GET` có thể được đánh dấu
- `GET` không bao giờ được sử dụng khi xử lý dữ liệu nhạy cảm
- `GET` có giới hạn về độ dài
- `GET` chỉ dùng để yêu cầu dữ liệu (không sửa đổi)

### `POST`
`POST` được sử dụng để gửi dữ liệu đến máy chủ nhằm tạo hoặc cập nhật tài nguyên.
Dữ liệu được gửi đến máy chủ bằng `POST` được lưu trữ trong request body của HTTP request:
```
POST /test/demo_form.php HTTP/1.1
Host: w3schools.com

name1=value1&name2=value2
```
Một số chú ý:
- `POST` không được lưu vào bộ nhớ đệm
- `POST` không còn trong lịch sử trình duyệt
- `POST` không được đánh dấu
- `POST` không có hạn chế về độ dài dữ liệu

### So sánh `GET` và `POST`

|          | `GET` | `POST`|
| -------- | -------- | -------- |
| **Back/Reload**    | Không bị ảnh hưởng | Dữ liệu sẽ được gửi lại(trình duyệt sẽ cảnh báo người dùng)|
|**Bookmarked**|Có thể đánh dấu|Không thể đánh dấu|
|**Cached**|Có thể lưu vào bộ nhớ đệm|Không thể lưu vào bộ nhớ đệm|
|**Encoding type**|`application/x-www-form-urlencoded`|`application/x-www-form-urlencoded or multipart/form-data`. Sử dụng mã hóa nhiều phần cho dữ liệu nhị phân|
|**History**|Các thông số vẫn còn trong lịch sửtrình duyệt|Thông số không được lưu trong lịch sử trình duyệt|
|**Restrictions on data length**|Khi gửi dữ liệu, phương thức GET sẽ thêm dữ liệu vào URL và độ dài của URL bị giới hạn (độ dài URL tối đa là 2048 ký tự)|Không bị giới hạn|
|**Restrictions on data type**|Chỉ cho phép ký tự ASCII|KHông có hạn chế|
|**Security**|`GET` kém an toàn hơn so với `POST` vì dữ liệu được gửi là một phần của URL. Không bao giờ sử dụng GET khi gửi mật khẩu hoặc thông tin nhạy cảm khác|`POST` an toàn hơn GET vì các tham số không được lưu trong lịch sử trình duyệt hoặc trong nhật ký máy chủ web|
|**Visibility**|Dữ liệu được hiển thị cho mọi người trong URL|Dữ liệu không được hiển thị trong URL|

### `PUT`
`PUT` được sử dụng để gửi dữ liệu đến máy chủ nhằm tạo/cập nhật tài nguyên. Nếu phương thức này được bật, bạn có thể tận dụng nó để tấn công ứng dụng, chẳng hạn như bằng cách tải lên một tập lệnh tùy ý và thực thi nó trên máy chủ.


Sự khác biệt giữa `POST` và `PUT` khi gọi `PUT` nhiều lần sẽ luôn cho cùng một kết quả. Ngược lại, việc gọi `POST` liên tục có tác dụng phụ là tạo cùng một tài nguyên nhiều lần.
### `HEAD`
`HEAD` gần giống với`GET` nhưng không có phần thân phản hồi.

Nói cách khác, nếu `GET` /users trả về danh sách người dùng thì `HEAD` /users sẽ đưa ra yêu cầu tương tự nhưng sẽ **không** trả về danh sách người dùng.

`HEAD` rất hữu ích trong việc kiểm tra xem `GET` sẽ trả về những gì trước khi thực sự thực hiện - như trước khi tải xuống một tệp lớn hoặc nội dung phản hồi.
### `DELETE`
Xóa dữ liệu của server về resource
### `PATCH`
Tương tự như `PUT` và `POST` như nó được sử dụng cho việc cập nhật một phần dữ liệu của đối tượng. Áp dụng sửa đổi một phần cho tài nguyên.
### `OPTIONS`
Yêu cầu máy chủ báo cáo các phương thức HTTP sẵn có cho một tài nguyên cụ thể. Máy chủ thường trả về phản hồi chứa tiêu đề Allow liệt kê các phương thức có sẵn.
### `TRACE`
`TRACE` được dùng cho mục đích chẩn đoán(hữu ích cho mục đích gỡ lỗi). Máy chủ sẽ trả về nội dung phản hồi chính xác của thông báo yêu cầu mà nó nhận được. Điều này có thể được sử dụng để phát hiện tác động của bất kỳ máy chủ proxy nào giữa client và server có thể thao túng yêu cầu.
### `CONNECT`
Tạo kết nối đến máy chủ thông qua HTTP và tham số URL.
### `COPY`
Sao chép tài nguyên được chỉ định vào vị trí được cung cấp.
### `MOVE`
Di chuyển tài nguyên được chỉ định tới vị trí được cung cấp 
### `SEARCH`
Tìm kiếm đường dẫn thư mục cho các nguồn tài nguyên.
### `PROFIND`
Truy xuất thông tin về tài nguyên được chỉ định, chẳng hạn như tác giả, kích thước và loại nội dung.
### Summary
| Phương thức | Hoạt động |
| -------- | -------- | 
| `GET`  |  Truy cập dữ liệu từ máy chủ cụ thể (không có body request)  | 
|`HEAD`|Không thông báo trong nội dung (không có response body), dùng khi đánh giá tính khả dụng của API tại điểm cuối|
|`POST`|Dùng khi muốn gửi thông tin đến máy chủ, thêm hoặc cập nhật dữ liệu|
|`PUT`| Tương tự như `POST` nhưng nó chỉ dùng để cập nhật dữ liệu. Khi dùng, bạn phải sửa toàn bộ dữ liệu của một đối tượng|
|`PATCH`|Áp dụng sửa đổi một phần cho tài nguyên.|
|`DELETE`|Xóa dữ liệu của server về resource|
|`TRACE`|Kiểm tra sự lặp lại theo đường dẫn, dùng để chạy thử nghiệm gỡ lỗi và thực hiện chẩn đoán trên API|
|`CONNECT`|Tạo kết nối đến máy chủ thông qua HTTP và tham số URL.|
|`OPTIONS`| Trả về phương thức HTTP mà server hỗ trợ.|
|`COPY`|Di chuyển tài nguyên được chỉ định tới vị trí được cung cấp |
|`SEARCH`| Tìm kiếm đường dẫn thư mục cho các nguồn tài nguyên.|
| `PROFIND`|Truy xuất thông tin về tài nguyên được chỉ định, chẳng hạn như tác giả, kích thước và loại nội dung.|

## URLs
**URL** (*Uniform Resource Locator*) là địa chỉ duy nhất trên Internet, dùng để trỏ đến tài nguyên cụ thể như trang web, hình ảnh, video hoặc tập tin.

Khi bạn nhấp vào một liên kết hoặc gõ URL vào trình duyệt của mình, trình duyệt sẽ gửi yêu cầu đến máy chủ tổng hợp tài nguyên và trả về tài nguyên đó cho bạn để hiển thị.

Cấu trúc của URL bao gồm:

![](https://hackmd.io/_uploads/H1O_t-QZp.png)

Lưu ý: *Bạn có thể gặp thuật ngữ URI (Uniform Resource Identifier) đang được sử dụng thay cho URL, nhưng nó thực sự chỉ được sử dụng trong các thông số kỹ thuật chính thức.*
### Scheme
![](https://hackmd.io/_uploads/rk8EK-7WT.png)
Phần đầu tiên của URL là scheme, cho biết giao thức mà trình duyệt phải sử dụng để yêu cầu tài nguyên. 

Giao thức:` http, https, FTP…`

Khi chỉ định URL để tải tài nguyên như một phần của trang (chẳng hạn như khi sử dụng `<script>, <audio>, <img>, <video>, v.v.`), thông thường bạn chỉ nên sử dụng URL `HTTP` và `HTTPS`. Sử dụng `FTP` không an toàn và không còn được các trình duyệt hiện đại hỗ trợ.


### Authority
![](https://hackmd.io/_uploads/SkyHKbX-6.png)
 
 Authority (quyền) được phân tách khỏi `scheme` bằng mẫu ký tự `://`. Nếu có cả `domain` và `port` thì chúng được phân cách bằng dấu `:`
- `domain name` cho biết máy chủ Web nào đang được yêu cầu. Thông thường đây là một tên miền, nhưng địa chỉ IP cũng có thể được sử dụng.
- `port` cho biết "cổng" kỹ thuật được sử dụng để truy cập tài nguyên trên máy chủ web.
### Path to resource (Đường dẫn)
![](https://hackmd.io/_uploads/HyIl1M7Zp.png)

`/path/to/myfile.html` là đường dẫn đến tài nguyên trên máy chủ Web. Đường dẫn (hoạt động như đường dẫn trong Windows, macOS hoặc Linux) đưa bạn đến đúng thư mục hoặc file trên máy chủ đó. Đường dẫn được bắt đầu bằng dấu gạch chéo và có các dấu gạch chéo giữa các thư mục và thư mục con.
### Parameters
![](https://hackmd.io/_uploads/r179ezXWa.png)

`?key1=value1&key2=value2` là các tham số bổ sung được cung cấp cho máy chủ Web. Các tham số đó là danh sách các cặp khóa/giá trị được phân tách bằng ký hiệu `&`.

Web server có thể sử dụng các tham số đó để thực hiện các công việc bổ sung trước khi trả lại tài nguyên. Mỗi máy chủ web có các quy tắc riêng về những tham số và cách để biết liệu một máy chủ web cụ thể có đang xử lý các tham số hay không bằng cách hỏi chủ sở hữu máy chủ web.

### Anchor
![](https://hackmd.io/_uploads/HJVz4M7-p.png)

`#SomewhereInTheDocument` là một `anchor` cho một phần khác của chính tài nguyên. Anchor đại diện cho một loại "bookmark" bên trong tài nguyên, cung cấp cho trình duyệt các hướng dẫn để hiển thị nội dung nằm tại vị trí được đánh dấu đó. Cần lưu ý rằng phần sau dấu`#`(còn được gọi là `fragment identifier`) không bao giờ được gửi đến máy chủ cùng với yêu cầu.
### Query
Phần truy vấn của một URL được sử dụng để xác định những thứ **không phải** là thành phần của một cấu trúc đường dẫn cố định. Thông thường, bạn sẽ thấy chúng được sử dụng để thực hiện tìm kiếm hoặc khi trang web phân phối dữ liệu thông qua biểu mẫu. Phần truy vấn này được bắt đầu bằng dấu hỏi chấm `?` và theo sau đường dẫn (hoặc sau tên máy chủ nếu không có đường dẫn).


## HTTP Headers
HTTP headers được thêm vào sau "first line" và được khai báo theo kiểu các cặp: name-value, phân tách bởi dấu chấm phẩy. HTTP headers được sử dụng để gửi thêm các tham số trong các request/response.

### General header
Các Headers có thể được sử dụng trong cả request hoặc response và chúng độc lập với data được trao đổi.
#### `Cache-Control`
Được sử dụng để xác định các chỉ dẫn mà **PHẢI** được tuân theo bởi tất cả các hệ thống bộ nhớ ẩn. Client hoặc Server có thể sử dụng `Cache-Control` để xác định các tham số cho bộ nhớ ẩn hoặc yêu cầu các loại cụ thể của tài liệu từ bộ nhớ ẩn. Các chỉ dẫn bộ nhớ ẩn được xác định trong một danh sách được phân biệt bởi dấu phẩy.
```
Cache-Control : cache-request-directive|cache-response-directive
```
*Request*


| Chỉ thị | Mô tả |
| -------- | -------- | 
|  **no-cache**  |  yêu cầu bộ đệm xác thực phản hồi HTTP trước khi gửi   | 
|**no-store**|yêu cầu bộ đệm không lưu trữ yêu cầu HTTP hoặc phản hồi HTTP tương ứng|
|**no-transform**|Không chuyển đổi phần thân đối tượng|
|**max-age**|chỉ ra rằng các phản hồi được lưu trữ trong số giây đã chỉ định sẽ được chấp nhận|
|**max-stale**|Máy khách chấp nhận các phản hồi HTTP cũ trong một số giây nhất định.|
|**min-fresh**|cho phép phản hồi HTTP được lưu trữ sẽ vẫn mới trong một số giây được chỉ định|
|**only-if-cached**|Không lấy dữ liệu mới, phản hồi HTTP được lưu trữ dự kiến sẽ được trả về|

*Response*


| Chỉ thị  | Mô tả |
| -------- | -------- |
| **max-age**|  phản hồi HTTP sẽ vẫn mới trong một số giây được chỉ định sau khi nó được tạo, số giây cho biết khoảng thời gian mà nội dung được tạo ra   |
|**s-maxage**|*Shared max-age* - luôn luôn được bỏ qua bởi một bộ nhớ cá nhân.|
|**no-cache**|xác thực phản hồi từ máy chủ gốc trước khi gửi chúng|
|**no-store**|ngăn việc lưu trữ phản hồi HTTP trong bất kỳ bộ đệm nào|
|**no-transform**|đảm bảo rằng các bên trung gian không thao tác được các phản hồi HTTP trước khi nó được chuyển tiếp đến máy khách, bất kể nó có được lưu vào bộ nhớ đệm hay không|
|**must-understand**|bộ nhớ đệm chỉ lưu trữ phản hồi HTTP trong trường hợp máy chủ nhận ra mã trạng thái và hiểu các yêu cầu|
|**must-revalidate**|xác minh trạng thái của các tài liệu đã cũ trước khi sử dụng nó và các tài liệu đã mãn hạn không nên được sử dụng |
|**proxy-revalidate**|Chỉ dẫn tái xác nhận ủy quyền có cùng ý nghĩa với chỉ dẫn must-revalidate, ngoại trừ nó không áp dụng tới các bộ nhớ ẩn user agent không được chia sẻ|
|**stale-if-error**|phản hồi HTTP cũ có thể được sử dụng khi máy chủ gốc đang báo cáo một trong các mã trạng thái phản hồi lỗi HTTP sau: `500`, `502`, `503`, `504`|
|**public**|được bao gồm trong phản hồi HTTP của máy chủ để cho biết rằng nó có thể được lưu trữ trong bộ nhớ đệm dùng chung|
|**private**|phản hồi HTTP chỉ có thể được lưu trữ trong bộ đệm riêng|
|****||




#### `Connection`
Kiểm soát xem kết nối mạng có còn mở sau khi giao dịch hiện tại kết thúc hay không. Có 2 chỉ thị: `keep-alive` và `close`.
- Lệnh `keep-alive` cho biết rằng máy khách muốn Kết nối HTTP tồn tại và duy trì trạng thái mở sau khi giao dịch hiện tại hoàn tất. Đây là cài đặt mặc định cho các yêu cầu` HTTP/1.1`.
```
Connection: keep-alive
```
- Lệnh `close` báo hiệu rằng máy khách muốn đóng Kết nối HTTP sau giao dịch. Đây là cài đặt mặc định cho các yêu cầu `HTTP/1.0`.
```
Connection: close
```

**Lưu ý:** Kể từ HTTP/2, `connection` không còn hợp lệ. Một số triển khai trình duyệt bỏ qua tiêu đề HTTP trong khi những triển khai khác sẽ từ chối thông báo có chứa nó.

#### `Content-Type`
Chỉ định loại nội dung chứa trong nội dung thư, chẳng hạn như văn bản /html cho tài liệu HTML.
Các chỉ thị cho `Content-Type` là `media type`, `charset`, và `boundary`
Ví dụ:
```
Content-Type: text/html; charset=UTF-8
```
Bản gốc` media type` là` text/html` và sử dụng bộ ký tự `UTF-8`.


```
Content-Type: multipart/form-data; boundary=-----
```
Một `multipart` phản hồi được gửi đi. Mỗi phần được phân tách bằng cụm từ `boundary` được chỉ định. Trong trường hợp này, khoảng cách `boundary` giữa các phần là `------`.

#### `Content-Encoding`
Chỉ định loại mã hóa nào đang được sử dụng cho nội dung chứa trong nội dung thư.

`Content-Encoding` là danh sách có thứ tự tất cả các mã hóa đã được áp dụng cho tin nhắn. Điều này cho phép Client giải mã, trả tài nguyên về trạng thái ban đầu.

**Note:** Nội dung ban đầu của tin nhắn được mô tả bằng `Content-Type`, trong khi `Content-Encoding` đề cập đến trạng thái hiện tại. 
```
Content-Encoding: deflate, br
```
Server cho Client biết rằng tài nguyên đã bị thay đổi trước tiên bằng cách sử dụng `deflate`, sau đó là `br`(Brotli).

#### `Content-Length`
Chỉ định độ dài của nội dung thư, tính bằng `byte`. Nó có thể được client sử dụng để xác minh rằng toàn bộ tin nhắn đã được nhận. Ngoài ra, đối với những tin nhắn dài, nó có thể được sử dụng để ước tính thời gian truyền.
Respond
```
Content-Length: <bytes>
```

#### `Transfer-Encoding`
Chỉ định bất kỳ mã hóa nào được thực hiện trên nội dung thư để tạo điều kiện thuận lợi cho việc truyền nó qua HTTP. Nó cho biết phương pháp mã hóa được sử dụng cho nội dung thông báo trong quá trình truyền hiện tại và có thể được sử dụng giữa các nút.

Các chỉ thị `Transfer-Encoding` là `chunked`, `compress`, `deflate`, và `gzip`. Các chỉ thị có thể được đưa vào bằng cách sử dụng các  HTTP header riêng biệt hoặc được đưa vào trên cùng một dòng ở định dạng được phân cách bằng dấu phẩy.
- `chunked` : client hỗ trợ các trường `trailer `ở dạng mã hóa chuyển khối.
- `compress` sử dụng thuật toán nén Lempel-Ziv-Welch (LZW)
- `deflate` sử dụng cấu trúc zlib để nén dữ liệu.
- `gzip` sử dụng phương pháp mã hóa Lempel-Zif và duy trì CRC 32 bit.
- 
**Note** `Transfer-Encoding` không được sử dụng trong `HTTP/2`.

#### Tham khảo thêm
https://http.dev/headers#caching

### Request Headers
#### `Accept`
`Accept` được client sử dụng để thông báo cho server về loại nội dung mà họ có thể hiểu và loại nội dung nào họ muốn nhận.

`Accept`là một phần của quy trình *Content Negotiation* và chỉ định loại *MIME* (một tiêu chuẩn Internet về định dạng cho thư điện tử) nào mà máy khách có thể hiểu được trong quá trình giao tiếp với máy chủ. Các trình duyệt Internet như Chrome , Firefox và Microsoft Edge đặt giá trị cho điều này dựa trên loại yêu cầu HTTP.

```
Accept: <MIME-type>/<MIME-subtype>
```
 Chỉ định một loại nội dung cụ thể, ví dụ như `text/html` hoặc `image/jpg`.

```
Accept: <MIME-type>/*
```
Chỉ định một loại chung, không bao gồm chi tiết cần thiết cho các loại phụ cụ thể. Ví dụ: `text/*`thông báo cho máy chủ rằng máy khách sẵn sàng chấp nhận tất cả các tài liệu văn bản, cho dù chúng là text/plain, text/html, hay cách khác.

```
Accept:*/*
```
Mọi loại nội dung đều được phép.
##### q-factor
Một số loại có thể được chỉ định trên một dòng và mức độ ưu tiên của loại này so với loại khác có thể được tính trọng số bằng cách sử dụng hệ số `q`.
```
Accept: type/subtype [q=qvalue]
```
Yếu tố `q` (`;q=`), cho biết rằng client sẵn sàng chấp nhận bộ này ở mức độ ưu tiên tương đối. Nếu không có mức ưu tiên nào thì giá trị mặc định là 1.0 sẽ được sử dụng.

Ví dụ:
```
Accept: text/html, text/plain;q=0.8, text/*;q=0.6, */*;q=0.5
```
`Accept` cho biết `text/html` được ưu tiên 1.0, `text/plain` có mức ưu tiên là 0,8. Các tài nguyên văn bản cụ thể ít hơn có mức độ ưu tiên là 0.6 và phần còn lại được coi bằng nhau với mức ưu tiên là 0.5.

**Note**: Nếu hai loại có cùng mức độ ưu tiên nhưng có độ đặc hiệu khác nhau thì loại cụ thể hơn sẽ được ưu tiên. Ví dụ: nếu `text/html` cả `text/*` hai đều có mức độ ưu tiên là 1.0 thì `text/html` được chọn.
#### `Accept-Encoding`
`Accept-Encoding` cho server biết loại mã hóa nội dung nào mà client sẵn sàng chấp nhận.

Nhiều mã hóa có thể được chỉ định bằng cách sử dụng `Accept-Encoding` riêng biệt hoặc thay vào đó sử dụng danh sách được phân cách bằng dấu phẩy. Hệ số `q` cũng có thể được đưa vào để biểu thị mức độ ưu tiên hoặc mức độ ưu tiên.

Ví dụ:
*Request*
- request type 1
```
GET / HTTP/1.1
Host: www.example.re
Accept-Encoding: gzip
Accept-Encoding: deflate
Accept-Encoding: br
Accept-Encoding: identity
Accept-Encoding: *
```
- request type 2
```
GET / HTTP/1.1
Host: www.example.re
Accept-Encoding: gzip, deflate, br;q=1.0, identity;q=0.5, *;q=0.25
```
*Response*
```
HTTP/1.1 200 OK
Content-Encoding: gzip, br
```
Client yêu cầu Server sử dụng một trong một số phương pháp mã hóa. Trong kiểu 1, mỗi tùy chọn đều được ưu tiên như nhau. Trong kiểu 2, chỉ thị giá trị q được sử dụng để gán trọng số cho mức độ ưu tiên mã hóa. Server phản hồi bằng danh sách các mã hóa đã được áp dụng, sắp xếp theo cách chúng được xử lý.

#### `Authorization`
`Authorization` được sử dụng để cung cấp thông tin xác thực cho người dùng, cho phép Client tương tác với tài nguyên được bảo vệ.

`auuthentiction-scheme` là một chỉ thị bắt buộc và có thể đi kèm với các tham số cụ thể khác của chương trình. Nó xác định phương thức HTTP, trong đó thông tin đăng nhập được mã hóa và các cách tiếp cận bao gồm `Basic`, `Digest`, `Negotiate`.

Ví dụ:
```
Authorization: Basic RXhhbXBsZTphaQ==
```
Client sử dụng `Basic Authentication scheme`. Thông tin xác thực là một cặp `username:password` được mã hóa bằng `base64`. 

#### `Cookie`
`Cookie` gửi cookie đến máy chủ mà máy chủ đã cấp trước đó.

`Cookie` bắt nguồn từ phía máy chủ và được gửi đến máy khách để sử dụng trong các HTTP response tương lai. `Cookie` được sử dụng để duy trì trạng thái và xác định người dùng cụ thể.

Giá trị `Cookie` chứa một cặp `name/value` của thông tin được lưu trữ cho URL đó.
```
Cookie: name=value
```
Nhiều `cookie` có thể được xác định phân biệt nhau bằng dấu chấm phẩy `;`
```
Cookie: name1=value1;name2=value2;name3=value3
```
#### `Host`
`Host` chỉ định tên máy chủ xuất hiện trong URL đầy đủ đang được yêu cầu.

`Host` được sử dụng để xác định Internet host và số hiệu cổng của nguồn được yêu cầu. Cú pháp chung:

```
Host : "Host" ":" host [ ":" port ] ;
```
Một `Host` mà không có bất kỳ thông tin port nào thì là port đó mặc định được coi là 80.

`Host` là header bắt buộc trong `HTTP/1.1` request. Nếu máy chủ nhận được yêu cầu HTTP không bao gồm `Host` thì nó sẽ trả về lỗi `400 Bad Request`. Mã trạng thái HTTP lỗi tương tự sẽ được trả về nếu có nhiều hơn một `Host`.

Ví dụ:
```
Host: example.re
```
#### `If-Modified-Since`
`If-Modified-Since` chỉ định thời điểm cuối cùng trình duyệt nhận được tài nguyên được yêu cầu. Nếu tài nguyên không thay đổi kể từ thời điểm đó, máy chủ có thể hướng dẫn khách hàng sử dụng bản sao được lưu trong bộ nhớ đệm của nó(sử dụng phản hồi có mã trạng thái `304`).

`If-Modified-Since`  được sử dụng để chuyển đổi yêu cầu HTTP thành yêu cầu có điều kiện , trong đó tài nguyên phải được sửa đổi vào hoặc sau một ngày cụ thể để yêu cầu HTTP tiếp tục.

```
If-Modified-Since : HTTP-date
```
Ví dụ:
```
If-Modified-Since: Wed, 11 Oct 2023 08:00:00 GMT
```
Yêu cầu HTTP sẽ không được thực hiện trừ khi tài nguyên được sửa đổi kể từ ngày 11 tháng 10 năm 2023, lúc 8 giờ sáng theo giờ GMT

#### `If-None-Match`
`If-None-Match` được sử dụng để chuyển đổi yêu cầu HTTP thành yêu cầu có điều kiện dựa trên một tập hợp các HTTP ETag header không khớp.
```
If-None-Match : entity-tag
```
Một cách sử dụng phổ biến của `If-None-Match` là cập nhật bộ đệm cục bộ cho các tài nguyên thu được bằng` GET` hoặc `HEAD `. Khi đó, tài nguyên sẽ chỉ được trả về nếu một trong các tiêu đề HTTP ETag được chỉ định khớp nếu không, máy chủ sẽ trả về mã trạng thái `304 Not Modified` . 

Đối với các phương thức không an toàn như  `PUT`, có thể được sử dụng để đảm bảo rằng tệp hiện có không bị ghi đè, dẫn đến sự cố cập nhật bị mất.

Lệnh duy nhất là giá trị ETag. Nhiều ETag có thể được chỉ định trên các dòng khác nhau hoặc thay vào đó dưới dạng danh sách được phân cách bằng dấu phẩy trên một dòng. Việc bao gồm dấu hoa thị `*` đóng vai trò như một ký tự đại diện, nghĩa là mọi tài nguyên đều khớp.

#### `Origin`
`Origin` được sử dụng trong các yêu cầu Ajax tên miền chéo để chỉ ra tên miền mà yêu cầu bắt nguồn từ đó.
#### `Referer`
`Referer` cho biết URL của ứng dụng máy khách đang thực hiện yêu cầu HTTP. `Referer` có thể được sử dụng cho mục đích phân tích cũng như để tối ưu hóa bộ nhớ đệm.

Lệnh duy nhất là URL, có thể bao gồm `origin`, `path` và `query string`, tùy thuộc vào `Referrer-Policy`. Điều quan trọng là thông tin bí mật như thông tin xác thực trang web không được đưa vào `Referer`.

**Note**: Vì `Referer` tiết lộ thông tin chi tiết về ứng dụng máy khách mà không có sự đồng ý cụ thể nên `Referer` có thể làm 'xói mòn' quyền riêng tư trực tuyến.

#### `User-Agent`
`User-Agent` hay còn gọi là User-Agent String hoặc UA-String cung cấp thông tin về trình duyệt hoặc phần mềm máy khách khác đã tạo ra yêu cầu.

Có ba chỉ thị bao gồm `the product`,` the version`, và `a comment`. Đây productlà một mã định danh đơn giản và phần đi kèm versionsẽ chỉ rõ thêm về nó. Được commentsử dụng để chỉ định thêm chi tiết như thông tin sản phẩm phụ. `product` là một mã định danh đơn giản và phần `version` đi kèm sẽ chỉ rõ thêm về nó. `comment` được sử dụng để chỉ định thêm chi tiết như thông tin sản phẩm phụ.

```
User-Agent: <product> / <version> <comment>
```
HTTP User-Agent header có thể thay bằng Client Hints.

### Response Headers
#### `Access-Control-Allow-Origin`
`Access-Control-Allow-Origin` là một phần của giao thức CORS cho phép chia sẻ nhiều nguồn gốc và được máy chủ gửi để cho máy khách biết rằng phản hồi HTTP có thể được chia sẻ bằng cách yêu cầu mã từ nguồn gốc được chỉ định.

```
Access-Control-Allow-Origin: *
```
Dấu `*` là ký tự đại diện cho các yêu cầu HTTP không có thông tin xác thực. Nó yêu cầu người dùng cho phép các yêu cầu HTTP từ bất kỳ nguồn gốc nào truy cập vào tài nguyên.

```
Access-Control-Allow-Origin: null
```
Lệnh`null` cho biết sự vắng mặt của mạng gốc. Việc sử dụng `null` không được khuyến khích vì một số tác nhân người dùng (user agent) nhất định sẽ tự động cấp cho các tài liệu đó quyền truy cập vào phản hồi HTTP có chứa HTTP header này. Do đó, nó có thể dẫn đến vi phạm bảo mật, theo đó kẻ xấu có thể tạo tài liệu độc hại bằng cách sử dụng null origin.

Ví dụ:
```
Access-Control-Allow-Origin: https://example.re
```
Thông báo cho khách hàng rằng việc cho phép yêu cầu mã từ `https://example.re` để truy cập tài nguyên là an toàn.

#### `ETag`
`ETag` cung cấp giá trị hiện tại của thẻ đối tượng cho biến thể được yêu cầu. `ETag` chứa mã định danh được sử dụng để phân biệt giữa các tài nguyên khác nhau và các phiên bản khác nhau của cùng một tài nguyên.
- Weak ETag và Strong ETag: Weak ETag dễ tạo ra hơn Strong Etag.

     - Weak ETag: `ETag: W/"<ETag-value>"`
     - Strong ETag: `ETag: "<ETag-value>"`

#### `Expires`
`Expires` cho trình duyệt biết nội dung của nội dung thư có hiệu lực trong bao lâu. Trình duyệt có thể sử dụng bản sao được lưu trong bộ nhớ cache của tài nguyên này cho đến thời điểm này.

`Expires` chứa ngày và giờ cụ thể, nếu nó chứa số 0 thì phản hồi HTTP đã hết hạn.

```
Expires : HTTP-date
```
Ví dụ:
```
Expires: Thu, 12 Oct 2023 16:00:00 GMT
```

#### `Location`
Được sử dụng để chỉ định URL mục tiêu khi xảy ra chuyển hướng trang.
- Chuyển hướng:
   - Nếu phản hồi HTTP là ` 301 Moved Permanently` hoặc `302 Found` thì phương thức HTTP tương tự sẽ được sử dụng để chuyển hướng. Tuy nhiên, một số cách triển khai cũ hơn có thể thay đổi phương thức HTTP.
   - Trong trường hợp phản hồi HTTP `307 Temporary Redirect` hoặc `308 Permanent Redirect` được trả về, phương thức HTTP tương tự được sử dụng trong yêu cầu HTTP ban đầu sẽ luôn được sử dụng.

- Tạo tài nguyên: Khi một tài nguyên mới được tạo và trạng thái HTTP `201 Created` được trả về, `Location` sẽ trỏ đến tài nguyên mới.
Ví dụ:
```
HTTP/1.1 302 Found
Location: https://example.re/
```
**Note**: `Content-Location` khác với `Location`. `Location` cho biết URL của tài nguyên mới được tạo, trong khi `Content-Location` chứa URL trực tiếp được sử dụng trong giai đoạn Content Negotiation. Cụ thể, `Location` có liên quan đến phản hồi HTTP và `Content-Location` liên quan đến thực thể trả về cho client.

#### `Pragma`
`Pragma` chuyển chỉ thị bộ nhớ đệm tới trình duyệt. N có các hiệu ứng khác nhau dành riêng cho việc triển khai và không được bao gồm trong đặc tả HTTP. Tuy nhiên, nó  có thể được sử dụng để tương thích ngược với các máy khách HTTP/1.0. 

Lệnh duy nhất là `no-cache`
```
Pragma: no-cache
```
#### `Server`
`Server` cho biết phần mềm đang được sử dụng trên máy chủ gốc.

Lệnh duy nhất là `product`, có định dạng tương tự như `User-Agent`  được khách hàng cung cấp trong yêu cầu HTTP.

Một số máy chủ web, chẳng hạn như Nginx , cho phép bạn xóa hoặc tùy chỉnh `HTTP Server header`.

#### `Set-Cookie`
`Set-Cookie` được sử dụng để gửi Cookie từ máy chủ đến máy khách để sử dụng tiếp theo.
```
Set-Cookie: <cookie-name>=<cookie-value>; OPTIONS
```

#### `WWW-Authenticate`
`WWW-Authenticate` cho biết thông báo xác thực nào có thể được sử dụng để truy cập vào một tài nguyên cụ thể. `WWW-Authenticate` được sử dụng trong các phản hồi có mã trạng thái 401 để cung cấp chi tiết về (các) loại xác thực mà máy chủ hỗ trợ.

`WWW-Authenticat`e chứa ít nhất một `authentication-scheme` và bất kỳ tham số hoặc dữ liệu nào được yêu cầu để thực hiện xác thực bằng tiêu đề đó.

Ví dụ định dạng scheme:
```
WWW-Authenticate: <scheme>
WWW-Authenticate: <scheme> realm=<realm>
WWW-Authenticate: <scheme> token68
WWW-Authenticate: <scheme> parameter1=token1
WWW-Authenticate: <scheme> realm=<realm> token68
WWW-Authenticate: <scheme> realm=<realm> token68 parameter1=token1
```

#### `X-Frame-Options`
`X-Frame-Options` cho biết liệu phản hồi hiện tại có thể được tải trong khung trình duyệt hay không và bằng cách nào.
- `X-Frame-Options: DENY`: Trang không thể được hiển thị trong khung, bất kể trang web có cố gắng làm như vậy hay không.
- `X-Frame-Options: SAMEORIGIN`: Trang chỉ có thể được hiển thị nếu tất cả các khung có cùng nguồn gốc với chính trang đó.
- ` ALLOW-FROM origin`: Đây là một lệnh lỗi thời và không còn hoạt động trong các trình duyệt hiện đại (Sử dụng nó sẽ có hành vi tương tự như bỏ qua tiêu đề).
## `Cookie`
Cookie HTTP (cookie web, cookie trình duyệt) là một đoạn dữ liệu nhỏ mà máy chủ gửi đến trình duyệt web của người dùng. Trình duyệt có thể lưu trữ cookie và gửi nó trở lại cùng một máy chủ với các yêu cầu sau này. Thông thường, cookie HTTP được sử dụng để biết liệu hai yêu cầu có đến từ cùng một trình duyệt hay không. Ví dụ: giữ người dùng đăng nhập. 

Cookie chủ yếu được sử dụng cho ba mục đích: Quản lý thông tin, cá nhân hóa, và theo dõi.

Về cơ bản cookie có thể được phân làm hai loại chính:

- **Session cookies** (phiên cookie): giữ lại ở trình duyệt và sẽ bị xóa bỏ khi đóng trình duyệt. Khi cửa sổ trình duyệt mới được mở lại, người dùng sẽ phải cung cấp lại các chứng thực của mình.
- **Persistent cookise**(coookie liên tục): giữ ở trình duyệt cho tới khi hết hạn hoặc được xóa một cách thủ công. Các trang web sẽ ghi nhớ các chứng thực ngay cả khi người dùng đóng trình duyệt.
![](https://hackmd.io/_uploads/rJeN4lPZT.png)

Ứng dụng quan trọng nhất của cookies là giữ cho người dùng đăng nhập khi họ duyệt từ trang này qua trang khác. Một số trang web thương mại điện tử thì sử dụng cả session cookies và persistent cookies để tạo sự liền mạch cho giỏ hàng khi mua sắm.
### Khởi tạo cookie
Khi người dùng truy cập vào trang web lần đầu tiên, header mà trình duyệt gửi lên sẽ có dạng sau:
```htmlmixed
GET /index.html HTTP/1.1
Host: www.example.org
```
Server không tìm thấy cookie trên request người dùng, nên nó sẽ khởi tạo cookie bằng cách gửi lại header như sau:
```htmlmixed
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: theme=light
Set-Cookie: sessionToken=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT
Set-Cookie: status=active; Max-Age: 300
Set-Cookie: name=tien; Expires=Wed, 09 Jun 2021 10:18:14 GMT; Max-Age: 300
```
### `cookie-name`
`cookie-name` có thể chứa bất kỳ ký tự US-ASCII nào ngoại trừ ký tự điều khiển, dấu cách, tab hoặc một trong các ký tự đặc biệt sau: `() <> [] @ \/ , ; : " ?`.
### `expires`
Thuộc tính `expires` chứa ngày cũ nhất mà cookie có thể được duy trì. Nó liên quan đến ứng dụng khách mà cookie được lưu trữ trên đó.
```
expires=<date>
```
### `max-age`
`max-age` được sử dụng để đặt số giây trước khi cookie hết hạn. Số âm sẽ khiến cookie hết hạn ngay lập tức.
```
max-age=<number>
```

**Note**: Trình duyệt có thể chọn giới hạn giá trị tối đa cho `expires` và `max-age` thuộc tính là 400 ngày. Khoảng thời gian này là gần 13 tháng, cho phép các trang web được người dùng truy cập khoảng một lần mỗi năm tiếp tục hoạt động, ví dụ: báo cáo việc sử dụng các tiện ích hàng năm thông qua trang web của công ty tiện ích.
### `domain`
Thuộc tính `domain` đề cập đến máy chủ mà cookie sẽ được gửi đến. Nếu thuộc tính này bị bỏ qua thì nó được coi là máy chủ của URL tài nguyên hiện tại. Không thể chỉ định nhiều giá trị `domain`,
```
domain=<domain-value>
```
### `path`
`path` bắt buộc phải có đường dẫn tồn tại trong URL để client gửi tiêu đề cookie. Dấu gạch chéo `/` được sử dụng để phân định các thư mục và thư mục con.
```
path=<path-value>
```
![](https://hackmd.io/_uploads/H1jbVi8-6.png)

### `secure`
Khi` secure` được đặt, cookie sẽ chỉ được gửi đến máy chủ khi giao thức được bảo mật (HTTPS), ngoại trừ trên máy cục bộ. Điều này được sử dụng để ngăn chặn các cuộc tấn công trung gian.

`secure` không bảo vệ Cookie khỏi các chương trình có thể đọc ổ cứng vật lý của máy khách. Ngoài ra, có thể truy cập vào cookie bằng cách sử dụng JavaScript nếu `HttpOnly` không được bao gồm.

### `HttpOnly`
Khi `HttpOnly` được đặt, các ứng dụng JavaScipt không có quyền truy cập thô vào dữ liệu của cookie. Cookie vẫn có thể được gửi nhưng không thể truy cập được thông qua thuộc tính tài liệu.
### `SameSite`
`SameSite` kiểm soát xem Cookie có được gửi trong các yêu cầu cross-origin hay không. Ba giá trị cho thuộc tính này là `strict`, `lax`, và `none`.
- Cài đặt `strict` có nghĩa là Cookie sẽ chỉ được gửi cho các yêu cầu trên cùng một trang.
- Cài đặt `lax` có nghĩa là Cookies sẽ không được gửi ở chế độ nền cho các tác vụ như tải hình ảnh. Cài đặt này là mặc định khi `SameSite` không được chỉ định.
-  Khi cài đặt `none` được sử dụng, cookie sẽ được gửi cùng với các yêu cầu trên nhiều trang web cũng như các yêu cầu HTTP trên cùng một trang web. Khi sử dụng `none` cho SameSite, `secure` cũng phải được đặt. 
```
SameSite=<SameSite-value>
```
## Status Codes
Mỗi thông báo phản hồi HTTP phải chứa mã trạng thái ở dòng đầu tiên, cho biết kết quả của yêu cầu. Mã trạng thái được chia thành năm nhóm, theo chữ số đầu tiên của mã:
- `1xx`- **information Message**: các status code này chỉ có tính chất tạm thời, client có thể không quan tâm.
     - `100` **Continue**: Phản hồi tạm thời này cho biết rằng khách hàng nên tiếp tục yêu cầu hoặc bỏ qua phản hồi nếu yêu cầu đã kết thúc.
     - `101` **Switching Protocols**: Mã này được gửi để phản hồi tiêu đề yêu cầu nâng cấp từ client và cho biết giao thức mà server đang chuyển sang.
     - `102` **Processing**: Mã này cho biết máy chủ đã nhận được và đang xử lý yêu cầu nhưng chưa có phản hồi nào.
    
- `2xx`- **Successful**: khi đã xử lý thành công request của client, server trả về status dạng này
    - `200` **OK**: request thành công.
    - `201` Created: Yêu cầu đã thành công và kết quả là một tài nguyên mới đã được tạo. 
    - `202` **Accepted**: request đã được nhận, nhưng không có kết quả nào trả về, thông báo cho client tiếp tục chờ đợi.
    - `204` **No Content**: request đã được xử lý nhưng không có thành phần nào được trả về.
    - `205` **Reset**: giống như 204 nhưng mã này còn yêu câu client reset lại document view.
    - `206` **Partial Content**: server chỉ gửi về một phần dữ liệu, phụ thuộc vào giá trị range header của client đã gửi.

- `3xx` **Redirection**: server thông báo cho client phải thực hiện thêm thao tác để hoàn tất request:
     - `301` **Moved Permanently**: tài nguyên đã được chuyển hoàn toàn tới địa chỉ Location trong HTTP response.
     - `303` **Found**: Mã phản hồi này có nghĩa là URI của tài nguyên được yêu cầu đã *tạm thời* được thay đổi. Những thay đổi tiếp theo trong URI có thể được thực hiện trong tương lai. Do đó, chính URI này sẽ được khách hàng sử dụng trong các yêu cầu trong tương lai.
     - `303` **See other**: tài nguyên đã được chuyển tạm thời tới địa chỉ Location trong HTTP response.
     - `304` **Not Modified**: tài nguyên không thay đổi từ lần cuối client request, nên client có thể sử dụng đã lưu trong cache.
    
- `4xx` **Client error**: lỗi của client:

    - `400` **Bad Request**: request không đúng dạng, cú pháp.
    - `401` **Unauthorized**: client chưa xác thực. 
    - `403` **Forbidden**: client không có quyền truy cập.
    - `404` **Not Found**: không tìm thấy tài nguyên.
    - `405` **Method Not Allowed**: phương thức không được server hỗ trợ.
    - `413` **Payload Too Large**: Thực thể yêu cầu lớn hơn giới hạn do máy chủ xác định. Máy chủ có thể đóng kết nối hoặc trả về  trường tiêu đề `Retry-After`.
    - `414` **URI Too Long**: URI được máy khách yêu cầu dài hơn mức mà máy chủ sẵn sàng giải thích.

- `5xx` **Server Error**: lỗi của server:

    - `500` **Internal Server Error**: có lỗi trong quá trình xử lý của server.
    - `502` **Bad Gateway**: Phản hồi lỗi này có nghĩa là máy chủ, trong khi hoạt động như một cổng để nhận phản hồi cần thiết để xử lý yêu cầu, đã nhận được phản hồi không hợp lệ.
    - `501` **Not Implemented**: server không hỗ trợ chức năng client yêu cầu.
    - `503` **Service Unavailable**: Server bị quá tải, hoặc bị lỗi xử lý.

## HTTPS
**HTTPS** (*Hypertext Transfer Protocol Secure*) là giao thức truyền tải siêu văn bản an toàn. Thực chất, đây chính là giao thức HTTP nhưng tích hợp thêm *Chứng chỉ bảo mật SSL* nhằm mã hóa các thông điệp giao tiếp để tăng tính bảo mật. Có thể hiểu, HTTPS là phiên bản HTTP an toàn, bảo mật hơn.

![](https://hackmd.io/_uploads/SyknHlPbT.png)

Hoạt động tương tự như HTTP, tuy nhiên HTTPS được bổ sung thêm chứng chỉ SSL (Secure Sockets Layer) hoặc TLS (Transport Layer Security). Cả SSL và TLS đều sử dụng hệ thống PKI (Public Key Infrastructure -hạ tầng khóa công khai) không đối xứng. Hệ thống này sử dụng hai “khóa” để mã hóa thông tin liên lạc, “khóa công khai” (public key) và “khóa riêng” (private key). 

### HTTP VS HTTPS
![](https://hackmd.io/_uploads/rk2rvePWa.png)

Sự khác biệt lớn nhất giữa HTTP và HTTPS là chứng chỉ SSL. Các tiêu chuẩn SSL sẽ luôn đảm bảo liên lạc giữa máy khách và máy chủ được an toàn, chống bị dòm ngó.
### Port trên HTTP và HTTPS

Giao thức HTTP sử dụng Port 80, trong khi đó HTTPS sử dụng Port 443 – đây chính là cổng hỗ trợ mã hóa kết nối từ máy tính client đến server, nhằm bảo vệ gói dữ liệu đang được truyền đi.

#### Nhược điểm duy nhất của HTTPS so với HTTP là sử dụng HTTPS khiến tốc độ giao tiếp (duyệt web, tải trang đích) giữa Client và Server chậm hơn HTTP, nhưng không đáng kể. 

## HTTP Proxies
Proxy HTTP là một máy chủ làm trung gian truy cập giữa trình duyệt client và web server. Khi một trình duyệt đã được cấu hình để sử dụng máy chủ proxy, nó sẽ thực hiện tất cả các yêu cầu của mình tới máy chủ đó. Proxy chuyển tiếp các yêu cầu đến các web server có liên quan và chuyển tiếp phản hồi của chúng trở lại trình duyệt. Hầu hết các proxy cũng cung cấp các dịch vụ bổ sung, bao gồm bộ nhớ đệm, xác thực và kiểm soát truy cập.

![](https://hackmd.io/_uploads/SkzXTgw-a.png)

- Các loại máy chủ Proxy
     - Transparent Proxy (Proxy trong suốt): là loại Proxy sử dụng IP của bạn để xác nhận yêu cầu truy cập trang web. Loại Proxy này thường được những nơi công cộng như thư viện, nhà sách, trường học, công viên, siêu thị sử dụng. Lý do là bởi vì bọn chúng khá dễ lọc nội dung truy cập do dễ dàng lập tên máy chủ và máy khách. 
     - Incognito Proxy( Proxy ẩn danh): Khi sử dụng máy chủ proxy cần lưu ý 2 điểm: hoạt động giống như trang web ẩn danh mà bạn hay dùng với mục đích cá nhân. Thay vì lấy IP của bạn để truy cập web thì Proxy ẩn danh sẽ không lấy. Nhưng nó vẫn cho phép bạn truy cập web, điều này giúp bạn bảo mật thông tin của mình, và không để lại dấu vết gì khi vào những trang web khác. 
     - Distorting Proxy (Proxy mạo danh): hoạt động như 1 máy chủ không tên, nó lấy IP và sửa thành một IP mạo danh.
     - High Anonymity Proxy (Proxy ẩn danh cao): Proxy ẩn danh cao có lợi hơn Proxy ẩn danh là nó giúp bạn truy cập Internet an toàn và bảo mật hơn rất nhiều lần. 

Khi sử dụng proxy cần chú ý 2 điểm:
- Khi trình duyệt đưa ra yêu cầu HTTP không được mã hóa tới máy chủ proxy, trình duyệt sẽ đặt URL đầy đủ vào yêu cầu, bao gồm tiền tố giao thức `http://`, tên máy chủ của máy chủ và số cổng nếu đây không phải là tiêu chuẩn. Máy chủ proxy trích xuất tên máy chủ và cổng rồi sử dụng chúng để chuyển yêu cầu đến đúng máy chủ web đích.

- Khi HTTPS đang được sử dụng, trình duyệt không thể thực hiện kết nối SSL với máy chủ proxy vì điều này sẽ phá vỡ đường hầm an toàn và khiến thông tin liên lạc dễ bị tấn công đánh chặn. Do đó, trình duyệt phải sử dụng proxy làm chuyển tiếp cấp TCP thuần túy, truyền tất cả dữ liệu mạng theo cả hai hướng giữa trình duyệt và máy chủ web đích, qua đó trình duyệt thực hiện bắt tay SSL như bình thường. Để thiết lập chuyển tiếp này, trình duyệt thực hiện yêu cầu HTTP tới máy chủ proxy bằng phương thức kết nối và chỉ định tên máy chủ đích và số cổng làm URL. Nếu proxy cho phép yêu cầu, nó sẽ trả về phản hồi HTTP với trạng thái` 200`, giữ kết nối TCP mở và từ thời điểm đó trở đi hoạt động như một chuyển tiếp cấp TCP thuần túy đến máy chủ web đích.

*(Tham khảo trong quyển The Web Application Hacker Handbook)*

## HTTP Authentication
HTTP Authentication là cơ chế xác thực HTTP giúp người dùng xác minh danh tính. Nó là một cơ chế bảo mật kiểm tra xem người dùng có đủ điều kiện truy cập web hay không.

HTTP Authentication Schemes được gọi là lược đồ xác thực HTTP. Máy chủ đưa ra những lược đồ xác thực khác nhau cho người dùng lựa chọn. Chúng đều là những phương pháp dùng trên web cho độ an toàn cao.

### HTTP Authentication Schemes phổ biến
- **Basic authentication** còn được gọi là mô hình thử thách – phản hồi. Máy chủ yêu cầu xác thực và máy khách cung cấp tên người dùng, mật khẩu. Đó là cơ chế xác thực một yếu tố và thông tin được trao đổi ở định dạng văn bản rõ ràng.
- **Digest authentication** (xác thực thông báo): loại này an toàn hơn xác thực cơ bản. Cũng với quy trình xác thực giống nhau nhưng nó có thêm giá trị `nonce` và thuật toán `MD5` để mã hóa. Từ đó tăng cường bảo mật khi xác thực danh tính người dùng.
- **Bearer authentication** (xác thực đa yếu tố): xác thực dựa trên mã thông báo. Nó có thêm một lớp bổ sung và bảo mật cấp với mã thông báo để xác thực thông tin nhận được từ người dùng.
- **HOBA**(HTTP Origin-Bound Authentication) là một scheme không yêu cầu máy chủ duy trì danh sách mật khẩu được lưu trữ và do đó không dễ bị tấn công lừa đảo.
- **NTLM** (*New Technology LAN Manager* – quản lý mạng LAN theo công nghệ mới) là một giao thức bảo mật của Windows xác thực danh tính người dùng mà không cần thông tin đăng nhập và truy cập vào tài nguyên.
- **Negotiate authentication** (đàm phán xác thực): là phiên bản nâng cấp của NTLM. Nó sử dụng giao thức [Kerberos](https://vi.wikipedia.org/wiki/Giao_thức_Kerberos) làm nhà cung cấp xác thực một cách nhanh chóng và an toàn.

### Hoạt động của HTTP Authentication
HTTP có một framework chung để kiểm soát kiềm truy cập của người dùng vào tài nguyên web. Framework sẽ dựa vào header xác thực để sử dụng. Có hai loại header chủ yếu là:` WWW-Authenticate header` và `Proxy Authentication header`.

Cú pháp của các header:
```
WWW-Authenticate: <type> realm=<realm>
Proxy-Authenticate: <type> realm=<realm>
```
`<type>`: lược đồ sử dụng trong quy trình xác thực.
`<realm>`: phạm vi bảo mật cho máy khách.
    
![](https://hackmd.io/_uploads/r1L70-w-6.png)
Quy trình hoạt động:
- Request: Máy khách đưa ra yêu cầu truy cập dưới dạng ẩn danh (máy chủ không có bất cứ thông tin nào về máy khách yêu cầu).
- Challenge: khi thấy yêu cầu, máy chủ sẽ phản hồi trạng thái `401` và hướng dẫn người dùng cần xác minh danh tính ở phần header
- Response: Máy khách phản hồi yêu cầu xác thực của máy chủ bằng tên người dùng, mật khẩu để truy cập vào tài nguyên.
- Proxy Authentication: Máy chủ Proxy sẽ gửi trạng thái `407` yêu cầu xác thực. Nó sẽ đứng ra cung cấp xác thực cho máy khách để truy cập tài nguyên (chỉ xảy ra khi bạn sử dụng máy chủ Proxy để xác thực).
- Verification: khi đã nhận được thông tin đăng nhập, máy chủ sẽ xác minh chúng. Nếu thông tin không hợp lệ, nó trả về trạng thái `403`. Ngược lại nó sẽ ra thông báo chào mừng.

# WRITE-UP
https://github.com/aQ05/Write-up/blob/main/README.md