Skip to content

HTTP HEAD responses are missing content-length header #220

@StuartMoncrieff

Description

@StuartMoncrieff

The HTTP headers returned by a HEAD request should be the same as the headers returned by a GET request for the same URL. The @hono/node-server does not include a Content-Length header in responses when the HEAD method is used.

The HEAD HTTP method requests the metadata of a resource in the form of headers that the server would have sent if the GET method was used instead. This method can be used in cases where a URL might produce a large download, for example, a HEAD request can read the Content-Length header to check the file size before downloading the file with a GET.

Reference: (https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD)

import { serve } from '@hono/node-server' // 1.13.7
import { Hono } from 'hono' // 4.6.14
import assert from 'node:assert/strict'

const app = new Hono()

// The app.get() method matches both GET and HEAD requests.
app.get('/', (c) => {
  return c.json({ message: 'Hello Node.js!' })
})

serve(app)

/*
GET request: ```curl -v http://localhost:3000/```

< HTTP/1.1 200 OK
< content-type: application/json
< Content-Length: 28
< Date: Tue, 17 Dec 2024 03:54:56 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
< 
< {"message":"Hello Node.js!"}

*/
const getResponse = await fetch('http://localhost:3000/', { method: 'GET' })
assert(getResponse.body !== null, 'GET response should have a response body')
assert(getResponse.headers.has('content-length') === true, 'GET response should have a content-length header')

/*
HEAD request: ```curl -v --head http://localhost:3000/```

The HEAD response is missing a content-length header!

< HTTP/1.1 200 OK
< content-type: application/json
< Date: Tue, 17 Dec 2024 03:55:30 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5

*/
const headResponse = await fetch('http://localhost:3000/', { method: 'HEAD' })
assert(headResponse.body === null, 'HEAD response should *not* have a response body')
assert(headResponse.headers.has('content-length') === true, 'HEAD response should have a content-length header') // AssertionError!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions