🙆♀️
pg-cloudflareでソケット接続
pg-cloudflareはnode-postgres内部のmodule。Cloudflare Workersでpgを動作させるために追加された。
pgがWorkerdランタイムをサポートするとそれを使っている各種ORMも動かることができる
これをnode-mysql2からも利用するように開発が進めらているので、Cloudflare Workersでmysql(をサポートするORMも)に接続できるようになると思われる
今後Workerdでソケット接続するプログラムで活用されるようになりそうだなと思ったので使い方を覚えた
npm create cloudflare@latest
npm i pg-cloudflare
/?url=http://amazon.com
でURLを渡すとHTTP 1.1でGETするプログラムを作ってみる
❯ curl "http://localhost:8787/?url=http://amazon.com"
HTTP/1.1 301 Moved Permanently
Server: Server
Date: Sun, 07 Apr 2024 07:44:34 GMT
Content-Type: text/html
Content-Length: 163
Connection: keep-alive
Location: https://amazon.com/
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>Server</center>
</body>
</html>
src/index.ts
import { CloudflareSocket as Socket } from 'pg-cloudflare';
type Env = Record<string, string>;
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
const p = new URLSearchParams(request.url.split("?")[1]);
const url = new URL(p.get("url") ?? 'http://example.com');
const isSecure = url.protocol === 'https:';
const socket = new Socket(isSecure);
const { readable, writable } = new TransformStream();
await socket.connect(isSecure ? 443 : 80, url.hostname, () => {
socket.write('GET / HTTP/1.1\r\n');
socket.write(`Host: ${url.hostname}\r\n`);
socket.write('Connection: close\r\n');
socket.write('\r\n');
});
socket.on('data', async (data: Buffer) => {
const writer = writable.getWriter();
const encoder = new TextEncoder();
await writer.write(encoder.encode(data.toString()));
writer.close();
});
return new Response(readable);
},
};
- CloudflareSocketのコンストラクタでは
ssl=true/false
を渡す - このクラスはEventEmitterを継承している
- pg-cloudflareはworkerdで動く時だけこの実装に差し替えられる
Discussion