Skip to content

Host Header is set incorrectly for ipv6 addresses with custom port #1241

@BenjaminBruenau

Description

@BenjaminBruenau

Specifiying an ipv6 address as an endpoint with a non-default port in the MinioClient constructor, similar to the snippet seen below, will result in an S3Error: Invalid Request (address 2606:4700::6810:1922:9000: too many colons in address) Error every time the Object Storage is accessed (e.g. when trying to upload a file).

new Minio.Client({
            endPoint: '2606:4700::6810:1922',
            port: 9000,
            useSSL: false,
            accessKey: useRuntimeConfig().minioKey,
            secretKey: useRuntimeConfig().minioSecret,
 })

It seems like the problem is caused by this line:

reqOptions.headers.host = `${host}:${port}`

Which is not taking into account that an ipv6 address should be enclosed in square brackets and sets the host-header to 2606:4700::6810:1922:9000, probably leading to the port being read as part of the ipv6 address later, resulting in a rejection of the request.
Enclosing the endpoint in the Client constructor with square brackets will throw an InvalidEndpointError.

I would expect ipv6 addresses in the host header to be handled in a similar way as it is done by nodejs internally (when no host-header is specified):
(https://github.com/nodejs/node/blob/59ebf6d397c9c468e5beb75b9ed8c82ab0603e3b/lib/_http_client.js#L290-L307)

    if (host && !this.getHeader('host') && setHost) {
      let hostHeader = host;

      // For the Host header, ensure that IPv6 addresses are enclosed
      // in square brackets, as defined by URI formatting
      // https://tools.ietf.org/html/rfc3986#section-3.2.2
      const posColon = StringPrototypeIndexOf(hostHeader, ':');
      if (posColon !== -1 &&
          StringPrototypeIncludes(hostHeader, ':', posColon + 1) &&
          StringPrototypeCharCodeAt(hostHeader, 0) !== 91/* '[' */) {
        hostHeader = `[${hostHeader}]`;
      }

      if (port && +port !== defaultPort) {
        hostHeader += ':' + port;
      }
      this.setHeader('Host', hostHeader);
    }

We worked around this problem by having a domain point to our ipv6-only cloud server and using that for the endpoint option.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions