镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

maxHeaderSize option on HTTPS server is not working #38954

Description

@SantanM
Darwin Santans-MacBook-Pro.local 18.7.0 Darwin Kernel Version 18.7.0: Tue Aug 20 16:57:14 PDT 2019; root:xnu-4903.271.2~2/RELEASE_X86_64 x86_64
  • Version: v12.19.0
  • Platform: MacOS
  • Subsystem: HTTPS module

What steps will reproduce the bug?

Creating a server using HTTPS module with option maxHeaderSize, like below. While increasing maxHeaderSize, the server still shows 431 error for large header.

const server = https.createServer({
  key: process.env.SSL_PRIVATE_KEY,
  cert: process.env.SSL_PUBLIC_CERT,
  maxHeaderSize: 8192*6
}, app).listen(PORT, () => {
  log.info(`🚀 Approuter started on port ${PORT}`);
console.log(server.maxHeaderSize); // outputs undefined
});

How often does it reproduce? Is there a required condition?

It seems (according to the documentation) the options of HTTP server are applicable to HTTPS, but the value does not seem to work in my case (seeing 431 error always)

What is the expected behavior?

In doing so, I am expecting the large header sent to the server is accepted and does not return 431 error.

What do you see instead?

HTTP 431 error

Additional information

The test cases of maxHeaderSize option are covered only for HTTP Server module and not HTTPS. I don't think it has been tested with HTTPS module.

Activity

  1. changed the title [-]add maxHeaderSize to HTTPS server not working[/-] [+]maxHeaderSize option on HTTPS server is not working[/+] on Jun 7, 2021
  2. added
    httpsIssues and PRs related to the https subsystem.
    on Jun 7, 2021
  3. bl-ue commented on Jun 7, 2021

    @bl-ue
    Contributor

    Linking for reference: nodejs/help#3401

  4. Ayase-252 commented on Jun 10, 2021

    @Ayase-252
    Member

    Hi, @SantanM
    Thanks for bug reporting,

    How do you generate headers for your request? If possible, could you provide a code snippet containing both server and request? It would be very helpful.

    I've written a case with testing tools of Node.js, it passes on v12.19.0 (interestingly, fails on v14 and above, it seems maxHeaderSize is ignored (always 200)? but it may be different issue I guess...)

    'use strict'
    
    const assert = require('assert');
    const common = require('../common');
    const https = require('https');
    const fixtures = require('../common/fixtures');
    
    const options = {
      key: fixtures.readKey('agent1-key.pem'),
      cert: fixtures.readKey('agent1-cert.pem')
    };
    
    const maxHeaderSize = 8192
    
    const body = 'hello world\n';
    const serverCallback = function (req, res) {
      res.writeHead(200, { 'content-type': 'text/plain' });
      res.end(body);
    };
    
    // test header size is larger than maxHeaderSize
    {
      const server = https.createServer({
        ...options,
        maxHeaderSize
      }, serverCallback)
    
      server.listen(0, common.mustCall(() => {
        const serverPort = server.address().port
        const reqOptions = {
          hostname: '127.0.0.1',
          port: serverPort,
          path: '/',
          method: 'GET',
          rejectUnauthorized: false,
          headers: {
            "h": 'a'.repeat(maxHeaderSize + 1)
          }
        };
    
        const req = https.request(reqOptions, common.mustCall((res) => {
          assert.strictEqual(res.statusCode, 431)
    
          res.on('data', function (d) {
          });
    
          res.on('end', common.mustCall(() => {
            server.close()
          }))
        })).end()
      }))
    }
    
    // test header size is in the range
    {
      const server = https.createServer({
        ...options,
        maxHeaderSize
      }, serverCallback)
    
      server.listen(0, common.mustCall(() => {
        const serverPort = server.address().port
        const reqOptions = {
          hostname: '127.0.0.1',
          port: serverPort,
          path: '/',
          method: 'GET',
          rejectUnauthorized: false,
          headers: {
            // some other header overhead
            "h": 'a'.repeat(maxHeaderSize - 200)
          }
        };
    
        const req = https.request(reqOptions, common.mustCall((res) => {
          assert.strictEqual(res.statusCode, 200)
    
          res.on('data', function (d) {
          });
    
          res.on('end', common.mustCall(() => {
            server.close()
          }))
        })).end()
      }))
    }
  5. Ayase-252 commented on Jun 10, 2021

    @Ayase-252
    Member

    Well, never mind, maxHeaderSize is unconfigurable for https.createServer, investigating further.

  6. SantanM commented on Jun 10, 2021

    @SantanM
    Author

    Thanks for checking. Keep us updated on the next plan.

  7. richardlau commented on Jun 10, 2021

    @richardlau
    Member

    Being able to set maxHeaderSize on a server was added by #30570 but that was introduced in Node.js 13.3.0 and is not present in Node.js 12. There was a suggestion that it was "backportable to Node 12 with a bit of work" (#30570 (comment)) but that "bit of work" never happened and is unlikely to now that Node.js 12 is in maintenance and does not get new features.

  8. Ayase-252 commented on Jun 10, 2021

    @Ayase-252
    Member

    @SantanM

    I think maxHeaderSize has never been implemented in https Server. #30570 added maxHeaderSize for http.Server but not for https. Therefore,

    https.createServer
    options Accepts options from tls.createServer(), tls.createSecureContext() and http.createServer().

    The doc is wrong. https.createServer([options][, requestListener]) will not accept all options of http.createServer(). At least, maxHeaderSize is not supported.

    For now, I think the only way to control the maximun header size of a HTTPS Server is via CLI option --max-http-header-size.

    Also, it seems fairly simple to bring maxHeaderSize into https.Server, I may open a PR in days.

  9. SantanM commented on Aug 6, 2021

    @SantanM
    Author

    @Ayase-252 - The changes you made will be replicated to lower versions, more particularly to v14.XX? Could you confirm?

  10. Ayase-252 commented on Aug 6, 2021

    @Ayase-252
    Member

    @SantanM I think it has been released in v16.5.0. It has not been backported to v14.x yet. Hopefully soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    httpsIssues and PRs related to the https subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions