dev server: no Content-Length header on HEAD requests
alukach opened this issue ยท 4 comments
๐ bug report
When running the dev server, it appears that the server does not respond with a Content-Length
when responding to a HEAD
request.
๐ Configuration (.babelrc, package.json, cli command)
{
"name": "sqlite-playground",
"source": "src/index.html",
"browserslist": "> 0.5%, last 2 versions, not dead",
"scripts": {
"start": "parcel",
"build": "parcel build"
},
"devDependencies": {
"buffer": "^6.0.3",
"crypto-browserify": "^3.12.0",
"events": "^3.3.0",
"parcel": "latest",
"path-browserify": "^1.0.1",
"process": "^0.11.10",
"stream-browserify": "^3.0.0"
},
"dependencies": {
"sql.js": "^1.7.0",
"sql.js-httpvfs": "^0.8.11"
}
}
๐ค Expected Behavior
HEAD
response contains Content-Length
& Accept-Ranges
headers
$ curl http://localhost:1234 --head
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, HEAD, PUT, PATCH, POST, DELETE
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Content-Type
Accept-Ranges: bytes
Cache-Control: max-age=0, must-revalidate
Content-Length: 106
Date: Fri, 19 Aug 2022 03:02:58 GMT
Connection: keep-alive
Keep-Alive: timeout=5
๐ฏ Current Behavior
HEAD
response does not contain Content-Length
or Accept-Ranges
headers
$ curl http://localhost:1234 --head
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, HEAD, PUT, PATCH, POST, DELETE
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Content-Type
Cache-Control: max-age=0, must-revalidate
Date: Fri, 19 Aug 2022 03:32:02 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Note that responses `GET` requests _do_ contain `Content-Length` and `Accept-Ranges` headers
curl http://localhost:1234 --verbose
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 1234 (#0)
> GET / HTTP/1.1
> Host: localhost:1234
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, HEAD, PUT, PATCH, POST, DELETE
< Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Content-Type
< Cache-Control: max-age=0, must-revalidate
< Content-Length: 98
< Content-Disposition: inline; filename="index.html"
< Accept-Ranges: bytes
< Last-Modified: Fri, 19 Aug 2022 03:40:25 GMT
< Content-Type: text/html; charset=utf-8
< Date: Fri, 19 Aug 2022 03:40:41 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
<
<html><meta charset="utf-8"><title>example</title>
* Connection #0 to host localhost left intact
<script src="/tmp.3464ddca.js"></script></html>* Closing connection 0
๐ Possible Solution
๐ฆ Context
I'm using a library that makes range requests to a static file (a SQLite database). It first makes a HEAD
request to understand the size of the file but throws an error being that the Content-Length
header is not present in the HEAD
request's response.
๐ป Code Sample
echo "<html><meta charset=utf-8><title>example</title>" > index.html
npx parcel index.html
curl http://localhost:1234 --head
๐ Your Environment
Software | Version(s) |
---|---|
Parcel | .2.7.0 |
Node | v16.13.0 |
npm/Yarn | 1.22.17 |
Operating System | OSX |
Relevant code:
parcel/packages/reporters/dev-server/src/Server.js
Lines 327 to 350 in cbc84b0
@mischnic A quick test shows that if I comment out lines 327-330, the server behaves as I expect:
โค curl --head http://localhost:1234/
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, HEAD, PUT, PATCH, POST, DELETE
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Content-Type
Cache-Control: max-age=0, must-revalidate
Content-Length: 302
Content-Disposition: inline; filename="index.html"
Accept-Ranges: bytes
Last-Modified: Wed, 24 Aug 2022 04:04:07 GMT
Content-Type: text/html; charset=utf-8
Date: Wed, 24 Aug 2022 04:11:17 GMT
Connection: keep-alive
Keep-Alive: timeout=5
However, I admit that I don't know if there are negative repercussions to such a change.
I'm not sure why that check is there.
As long as
handles HEAD correctly, removing that should be fine.
(And another question is how a head request should behave with if-modified-since (that other if block)
another question is how a head request should behave with if-modified-since (that other if block)
Reading RF 7231, I see:
The HEAD method is identical to GET except that the server MUST NOT send a message body in the response [...] The server SHOULD send the same header fields in response to a HEAD request as it would have sent if the request had been a GET, except that the payload header fields (Section 3.3) MAY be omitted.
Reading the If-Modified-Since
header docs, I see:
Unlike If-Unmodified-Since, If-Modified-Since can only be used with a GET or HEAD.
These details makes me think that the HEAD
request should be handled exactly as a GET
request should be handled, with the following exceptions:
- No body should be returned.
- Payload header fields may be omitted.
Point 2 makes me think this issue is actually a feature request rather than a bug report, but nonetheless I think the idea still stands.