# HTTP 探測

本頁說明 `Monitor.Check()` 如何判斷一個網站上線或離線：網址正規化、HEAD 與 GET 的切換條件、逾時與上線判定。

## 網址正規化

輸入的網址若不是以 `http` 開頭，會自動補上 `https://`（`internal/service/monitor.go:75`）。

| 輸入 | 實際請求 |
|------|---------|
| `example.com` | `https://example.com` |
| `https://example.com/health` | 不變 |
| `http://example.com` | 不變（以 HTTP 請求） |

正規化後的網址會寫進 `.webMonitor.json` 的 `list[].url`；重新啟動後監控清單以這個值載入，影響見 [已知限制](/zh/known-limitations)。

## 請求流程

```mermaid
graph TB
    Start[Check url] --> Norm[補 https://]
    Norm --> Head[送出 HEAD]
    Head -->|連線錯誤或 404| Get[改送 GET]
    Head -->|其他狀態碼| Judge
    Get --> Judge{有回應?}
    Judge -->|是| SSL[CheckExpire 讀憑證]
    SSL --> Code[依狀態碼判定上線]
    Judge -->|否| Offline[離線，Code = 0]
```

| 項目 | 值 |
|------|----|
| 第一個請求 | `HEAD` |
| 改送 `GET` 的條件 | HEAD 連線錯誤（含逾時），或狀態碼為 `404` |
| 逾時 | `http.Client.Timeout` 10 秒，HEAD 與 GET 各自計算 |
| 重新導向 | 跟隨 |
| 請求標頭 | `User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36`、`Accept: */*`、`Connection: keep-alive` |

只有連線錯誤與 `404` 會觸發 GET。伺服器以 `405`（Method Not Allowed）等其他 4xx／5xx 拒絕 HEAD 時，不會改送 GET，直接判定離線。

## 上線判定

| 結果 | `online` | `code` |
|------|----------|--------|
| 狀態碼 200–399 | `true` | 實際狀態碼 |
| 狀態碼 ≥ 400 | `false` | 實際狀態碼 |
| 連線失敗、逾時、DNS 錯誤 | `false` | `0` |

`duration` 記錄從開始到取得回應的總時間，包含 HEAD 失敗後改送 GET 的時間，表格中以毫秒顯示。

## SSL 檢查的觸發

請求有回應（不論狀態碼）時，才會呼叫 `util.CheckExpire()` 讀取憑證；連線失敗時 SSL 欄位為 `0`。細節見 [SSL 憑證到期](/zh/ssl-expiry)。
