Chuyển đến nội dung chính

レッスン 7: HTTP/HTTPS と HTTP/2

http.createServer、ルーティング、ミドルウェア パターンを最初から作成します。 HTTPS/TLS の設定。 HTTP/2 サーバープッシュ。リクエスト/レスポンスの処理、チャンク転送。キープアライブ、接続プーリング。

💻 プログラミング — レッスン 7 レッスン 7: HTTP/HTTPS と HTTP/2

Node.js コア: 基本から高度まで

パート 2: コアモジュールの詳細

xdev.asia

1. 基本的なHTTPサーバー

import { createServer, IncomingMessage, ServerResponse } from 'node:http'

const server = createServer((req: IncomingMessage, res: ServerResponse) => {
  // Request info
  const { method, url, headers } = req
  console.log(`${method} ${url}`)

  // Routing cơ bản
  if (method === 'GET' && url === '/') {
    res.writeHead(200, { 'Content-Type': 'application/json' })
    res.end(JSON.stringify({ message: 'Hello World' }))
  } else if (method === 'GET' && url === '/health') {
    res.writeHead(200)
    res.end('OK')
  } else {
    res.writeHead(404)
    res.end('Not Found')
  }
})

server.listen(3000, () => console.log('Server on :3000'))

2. リクエスト本文の読み取り

async function parseBody(req: IncomingMessage): Promise<unknown> {
  const chunks: Buffer[] = []
  for await (const chunk of req) {
    chunks.push(chunk as Buffer)
  }
  const body = Buffer.concat(chunks).toString()
  const contentType = req.headers['content-type'] || ''

  if (contentType.includes('application/json')) {
    return JSON.parse(body)
  }
  return body
}

// Sử dụng
const server = createServer(async (req, res) => {
  if (req.method === 'POST' && req.url === '/api/users') {
    const body = await parseBody(req) as { name: string }
    res.writeHead(201, { 'Content-Type': 'application/json' })
    res.end(JSON.stringify({ id: 1, name: body.name }))
  }
})

3.HTTPS/TLSサーバー

import { createServer } from 'node:https'
import { readFileSync } from 'node:fs'

const server = createServer({
  key: readFileSync('certs/private-key.pem'),
  cert: readFileSync('certs/certificate.pem'),
  ca: readFileSync('certs/ca.pem'),
}, (req, res) => {
  res.writeHead(200)
  res.end('Secure!')
})

server.listen(443)

4.HTTP/2サーバー

import { createSecureServer } from 'node:http2'
import { readFileSync } from 'node:fs'

const server = createSecureServer({
  key: readFileSync('certs/key.pem'),
  cert: readFileSync('certs/cert.pem'),
  allowHTTP1: true,
})

server.on('stream', (stream, headers) => {
  const path = headers[':path']
  const method = headers[':method']

  stream.respond({
    'content-type': 'application/json',
    ':status': 200,
  })
  stream.end(JSON.stringify({ path, method, protocol: 'h2' }))
})

server.listen(8443)

5.フェッチ(組み込み)

// Node.js 22+ — fetch là global (dựa trên undici)
const response = await fetch('https://api.github.com/users/octocat', {
  headers: { 'User-Agent': 'Node.js' },
  signal: AbortSignal.timeout(5000), // Timeout 5s
})

if (!response.ok) throw new Error(`HTTP ${response.status}`)
const data = await response.json()

6. 接続プーリング

import { Agent } from 'node:http'

// Custom agent với connection pooling
const agent = new Agent({
  keepAlive: true,
  keepAliveMsecs: 30000,
  maxSockets: 50,
  maxFreeSockets: 10,
})

// Dùng với fetch (undici)
import { Agent as UndiciAgent, setGlobalDispatcher } from 'undici'

setGlobalDispatcher(new UndiciAgent({
  connections: 50,
  pipelining: 10,
  keepAliveTimeout: 30000,
}))

次の記事: 暗号、OS、プロセス — ハッシュ、暗号化、子プロセス。