-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
apollo-server doesn't seem to like when Node's http2 module is used. When an HTTP2 client (i.e. the browser) makes a request, this error happens:
TypeError: :method is not a legal HTTP header name
- index.js:670 validateName
[venom-api]/[apollo-server-env]/[node-fetch]/lib/index.js:670:9
- index.js:830 Headers.append
[venom-api]/[apollo-server-env]/[node-fetch]/lib/index.js:830:3
- nodeHttpToRequest.ts:11 Object.keys.forEach.key
[venom-api]/[apollo-server-core]/src/nodeHttpToRequest.ts:11:15
- Array.forEach
- nodeHttpToRequest.ts:6 Object.convertNodeHttpToRequest
[venom-api]/[apollo-server-core]/src/nodeHttpToRequest.ts:6:28
...more stuff
Since apollo-server-core uses Request and Headers objects from node-fetch, I'm not sure whether this is an upstream problem or not. The problem is that node-fetch doesn't seem to support the "special" header names documented here.
In HTTP/2, the request path, hostname, protocol, and method are represented as special headers prefixed with the : character (e.g. ':path'). These special headers will be included in the request.headers object.
Since nodeHttpToRequest isn't actually using node-fetch to make an HTTP request, this seems to me like a problem internal to Apollo Server. node-fetch has their own issue here for HTTP2, but that seems to be concerned with making HTTP2 requests.
Reproduction:
(I use Koa)
const Koa = require('koa');
const { ApolloServer } = require('apollo-server-koa');
const http2 = require('http2');
const app = new Koa();
const apollo = new ApolloServer({ etc });
apollo.applyMiddleware(app);
const server = http2.createSecureServer({ cert: 'cert here', key: 'key here' }, app.callback());
server.listen(8000);Then make a GraphQL request, with your browser, to https://localhost:8000/ (browsers do not allow insecure HTTP2, so you'll have to ignore the security warning)
Potential Fix
In nodeHttpToRequest, ignore headers starting with :