[小ネタ] Cloudflare WorkersでFetch API使ったら521エラー

2024.02.22

WorkersからFetchで外部にアクセス

Cloudflare Workers(Rust)でFetch APIつかって別サイトにアクセスしようとしたんですが、
任意のポートでアクセスしようとしたらダメだったというメモ。

↓みたいに外部サーバ立ててFetchでアクセスしようとした。

use url::Url;
use worker::*;

・・・

let mut init = RequestInit::new();
let url = "http://xxxxxxxxx:3000";
init.with_method(worker::http::Method::Get.clone());
let external_request = worker::request::Request::new_with_init(&url, &init);
let res = Fetch::Request(external_request?).send().await?;

実際はEC2立てて、IP制限なしで3000番ポートを開放。
curlでローカルからアクセスして問題ない状態でした。
しかし、実際にWorkersにデプロイして動かすと、
「Error 521: web server is down」
のエラーが発生。

下記のようにMiniflare使ってローカルでテストしたときは
80/443以外のポートでも動いたからてっきり動くものかと。

import { Miniflare } from "miniflare";
import { fileURLToPath } from "url";

let server = null;
const serverUrl = 'http://localhost:3000';

// Miniflare
let mf = new Miniflare({
    scriptPath: scriptPath,
    modules: true,
    modulesRules: [
      { type: "CompiledWasm", include: ["**/*.wasm"], fallthrough: true }
    ],
    verbose: true
  });

// test(use ava)
test("test", async (t) => {
  const res = await mf.dispatchFetch("http://localhost:8787");
  t.is(await res.text(), "hogehoge");
});

ここなどによると、
Cloudflare WorkersのFetch APIを使用する際、
80番ポート(HTTP)と443番ポート(HTTPS)以外のポートを
指定できない様子。 勝手にHTTPかHTTPSで接続するらしい。

特定のポートでアクセスしたい場合、
普通にサーバ側で80/443で待ち受けるか、
リバースプロキシ使うかなどをする必要があるとのことです。

テスト用サーバはnodeで動くシンプルなhttpサーバだったので
80/443で起動させようとしたけど、なんかそれもいろいろ面倒だったので、
EC2で80番ポートあけてiptablesで3000番ポートにリダイレクトさせました。

% sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3000

WorkersでFetchするとき、接続先はHTTP/HTTPSであること。
覚えておきましょう。