概要
HTTP(HyperText Transfer Protocol)は、World Wide Webの基盤を成すアプリケーション層プロトコルです。1991年にTim Berners-Leeが最初のバージョンを定義して以来、インターネット上でHTMLドキュメント・画像・API応答など、あらゆる種類のデータをやり取りする標準手段として使われ続けています。
HTTPS(HTTP Secure)はHTTPにTLS(Transport Layer Security)による暗号化・認証を組み合わせたものです。現代のWebではHTTPSが標準となっており、IoT機器がクラウドAPIと通信する際も基本的にHTTPSを使います。
組み込み・IoT分野では以下のような場面でHTTP/HTTPSが使われます。
- クラウドのREST APIへのセンサーデータ送信
- ファームウェアのダウンロード(OTA)
- Webベースの管理画面(HTTPサーバーを内蔵したマイコン)
- Webhookによるイベント通知
Raspberry PiやESP32など処理能力のあるデバイスではフル機能のHTTPクライアントが動きますが、超小型マイコンではメモリ制約からlibcurlやhttpclientなどの軽量ライブラリを使います。
歴史・背景
バージョンの変遷
| バージョン | 年 | 主な特徴 |
|---|---|---|
| HTTP/0.9 | 1991 | GETのみ、テキストのみ |
| HTTP/1.0 | 1996 | ヘッダー追加、POST/HEADサポート |
| HTTP/1.1 | 1997 | 持続接続、パイプライン、チャンク転送 |
| HTTP/2 | 2015 | バイナリフレーム、多重化、ヘッダー圧縮 |
| HTTP/3 | 2022 | QUIC(UDP)ベース、接続確立高速化 |
HTTP/1.1は長年の主流でしたが、1リクエストごとに1レスポンスを待つ「HOL(Head-of-Line)ブロッキング」が問題でした。HTTP/2は多重化でこれを解消し、HTTP/3はQUICプロトコルによってTCPのハンドシェイクコストまで排除しました。
IoTとHTTPの関係
スマートフォンやシングルボードコンピュータ(Raspberry Pi等)の普及により、IoT機器がHTTPクライアントとしてクラウドAPIに直接接続するパターンが一般化しました。AWS IoT、Azure IoT Hub、Google Cloud IoTはいずれもHTTPS(REST)を主要プロトコルの一つとしてサポートしています。
技術仕様
HTTPリクエスト構造
POST /api/v1/sensors HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGc...
Content-Length: 42
{"device_id":"ESP32-01","temperature":25.3}
HTTPレスポンス構造
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/v1/sensors/measurements/1234
{"id":1234,"timestamp":"2025-01-15T12:00:00Z","status":"stored"}
ステータスコード
| コード | 意味 | IoTでの典型例 |
|---|---|---|
| 200 OK | 成功 | データ取得成功 |
| 201 Created | 作成成功 | センサーデータ登録成功 |
| 400 Bad Request | リクエスト不正 | JSONパースエラー |
| 401 Unauthorized | 認証失敗 | トークン無効 |
| 403 Forbidden | 権限なし | デバイス未登録 |
| 404 Not Found | リソースなし | デバイスID不存在 |
| 429 Too Many Requests | レート制限 | 送信頻度超過 |
| 500 Internal Server Error | サーバーエラー | バックエンド障害 |
TLS(HTTPS)の仕組み
Client Server
| |
|-- ClientHello --------------->| (TLS 1.3)
|<-- ServerHello + Certificate -|
|<-- Finished ------------------|
|-- Finished + Application Data>| (ここからHTTP暗号化通信)
TLS 1.3では従来の1.5往復から0.5往復(1-RTT)にハンドシェイクが短縮され、セッション再開では0-RTTも可能です。組み込み機器では接続確立のコストが大きいため、Keep-AliveやTLSセッション再利用が重要です。
HTTPヘッダーの主要フィールド(IoT関連)
| ヘッダー | 用途 |
|---|---|
| Content-Type | ペイロード形式(application/json等) |
| Authorization | 認証トークン(Bearer/Basic) |
| X-API-Key | APIキー認証 |
| If-None-Match | ETagによる条件付きGET(OTAに有用) |
| Content-Encoding | gzip圧縮等 |
| Keep-Alive | 持続接続設定 |
動作原理
TCP接続とKeep-Alive
HTTP/1.1はデフォルトでTCP接続を維持します(Keep-Alive)。マイコンでHTTPS通信を繰り返す場合、接続を使い回すことでTLS再ハンドシェイクのコストを削減できます。
// ESP-IDF(ESP32)でのHTTPS接続維持
esp_http_client_config_t config = {
.url = "https://api.example.com",
.cert_pem = server_cert,
.keep_alive_enable = true,
.keep_alive_idle = 5,
.keep_alive_interval = 5,
.keep_alive_count = 3,
};
esp_http_client_handle_t client = esp_http_client_init(&config);
// 複数回のリクエストで同一接続を再利用
for (int i = 0; i < 10; i++) {
esp_http_client_set_url(client, "https://api.example.com/data");
esp_http_client_set_method(client, HTTP_METHOD_POST);
esp_http_client_set_post_field(client, json_buf, strlen(json_buf));
esp_http_client_perform(client);
vTaskDelay(pdMS_TO_TICKS(1000));
}
esp_http_client_cleanup(client);
チャンク転送(ファームウェアOTA)
大容量ファームウェアをメモリに一度に収めずにダウンロードするチャンク転送。
// Chunked Transfer Encoding でOTAデータを受信
esp_http_client_open(client, 0); // GETリクエスト送信
int content_length = esp_http_client_fetch_headers(client);
int data_read = 0;
char *buf = malloc(CHUNK_SIZE);
while (1) {
int len = esp_http_client_read(client, buf, CHUNK_SIZE);
if (len <= 0) break;
// OTAパーティションへ書き込み
esp_ota_write(ota_handle, buf, len);
data_read += len;
}
free(buf);
WebSocketアップグレード
HTTPはWebSocketへのアップグレードにも使われます。最初はHTTPで接続し、Upgradeヘッダーで切り替えます(詳細はWebSocketを参照)。
GET /ws HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
用途・ユースケース
クラウドREST API連携
ESP32やRaspberry Piからセンサーデータをクラウドに送る最もシンプルな方法です。
# MicroPython(Raspberry Pi Pico W)での例
import urequests
import json
data = {
"device": "pico_w_01",
"temperature": 24.5,
"humidity": 60.2
}
headers = {
"Content-Type": "application/json",
"X-API-Key": "your-api-key"
}
response = urequests.post(
"https://api.example.com/measurements",
json=data,
headers=headers
)
if response.status_code == 201:
print("送信成功:", response.json())
response.close()
組み込みWebサーバー(管理画面)
ESP32やSTM32はHTTPサーバーを内蔵し、ブラウザから設定変更・状態確認ができます。
// ESP-IDFのhttpd使用例
static esp_err_t status_get_handler(httpd_req_t *req) {
char json[256];
snprintf(json, sizeof(json),
"{\"uptime\": %lld, \"temp\": %.1f, \"heap\": %d}",
esp_timer_get_time() / 1000000,
get_temperature(),
esp_get_free_heap_size());
httpd_resp_set_type(req, "application/json");
httpd_resp_sendstr(req, json);
return ESP_OK;
}
httpd_uri_t status_uri = {
.uri = "/api/status",
.method = HTTP_GET,
.handler = status_get_handler,
};
httpd_register_uri_handler(server, &status_uri);
OTA(ファームウェア更新)
HTTPSで署名済みファームウェアをダウンロードし、フラッシュに書き込むOTAの実装に使われます。
Webhook通知
センサーが閾値を超えたときに、SlackやTeamsのWebhook URLにHTTP POSTで通知する実装もよく使われます。
実装・開発のポイント
証明書管理
HTTPSにはルートCA証明書が必要です。マイコンのフラッシュに組み込む際は証明書のサイズと有効期限に注意が必要です。
// 証明書をバイナリとしてフラッシュに埋め込む(ESP-IDF)
extern const uint8_t server_cert_pem_start[] asm("_binary_server_cert_pem_start");
extern const uint8_t server_cert_pem_end[] asm("_binary_server_cert_pem_end");
esp_http_client_config_t config = {
.cert_pem = (const char *)server_cert_pem_start,
.cert_len = server_cert_pem_end - server_cert_pem_start,
};
タイムアウトと再試行
組み込み環境では接続タイムアウトを適切に設定し、指数バックオフで再試行します。
#define HTTP_TIMEOUT_MS 10000
#define MAX_RETRY 3
#define RETRY_BASE_DELAY_MS 1000
int send_with_retry(esp_http_client_handle_t client) {
for (int i = 0; i < MAX_RETRY; i++) {
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
int status = esp_http_client_get_status_code(client);
if (status == 200 || status == 201) return 0;
}
// 指数バックオフ
vTaskDelay(pdMS_TO_TICKS(RETRY_BASE_DELAY_MS * (1 << i)));
}
return -1;
}
メモリ最適化
HTTPヘッダーとボディ全体をRAMに保持しないよう、ストリーミング受信を使います。特にOTAの際は重要です。
他技術との比較
| 項目 | HTTP/HTTPS | MQTT | CoAP | WebSocket |
|---|---|---|---|---|
| トランスポート | TCP | TCP | UDP | TCP(HTTP経由) |
| 通信モデル | Req/Res | Pub/Sub | Req/Res | 双方向 |
| ブラウザ対応 | ◎ | △ | × | ◎ |
| 制約機器適合 | ○ | ◎ | ◎ | △ |
| 標準化 | RFC 9110- | OASIS | RFC 7252 | RFC 6455 |
| 暗号化 | TLS(HTTPS) | TLS | DTLS | TLS(WSS) |
REST API設計と組み合わせることで、IoTデバイスとWebサービスのシームレスな統合が実現できます。双方向リアルタイム通信が必要な場合はWebSocketへのアップグレードを検討します。