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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions