Skip to content

Why should we do toLowerCase to header name (by normalizeName()) ? #249

Closed
@mc-zone

Description

@mc-zone

Code first:

fetch( url, {
    headers:{
        'Cookie':'some key-value pass to server',
        'User-Agent': 'react-native Android'
    }
);

I found that the name of headers has been converted to lower case by normalizeName .

And when I use it on React-Native (Android platform) , it send a HTTP request with lower case header name which not be recognized in our Server.

There is the row HTTP text I've capture:

GET http://... HTTP/1.1
cookie: ...
user-agent: react-native Android 

So. Why should we do toLowerCase to header name ?

Activity

dgraham

dgraham commented on Dec 18, 2015

@dgraham
Contributor

HTTP headers are case insensitive. The lowercase header names were added in #85.

mc-zone

mc-zone commented on Dec 18, 2015

@mc-zone
Author

@dgraham. Thx for explanation!

smith

smith commented on Jun 14, 2016

@smith

I believe the native fetch implementation (in Chrome/Mac 51.0.2704.84 (64-bit) for me) also downcases the header names.

amrdraz

amrdraz commented on Jul 16, 2016

@amrdraz

While Http headers should be case-insensitive, a server for a client we're dealing with has miss implemented the spec. They check authorization header using equality it seems and accordingly produce an error.

We do not have control over modifying the code of that server, we can submit a request but that will take time to process.

If according to the spec the header should be case-insensitive I don't see why forcing the headers to be lower case matters then, we should be generally allowed to send headers in any case form.

hashplus

hashplus commented on Oct 31, 2016

@hashplus

chrome-dev-tool Network panel will divide these requests into Other not XHR.

/// request headers
accept:application/json
Accept-Encoding:gzip, deflate
Accept-Language:en,zh;q=0.8,zh-CN;q=0.6,zh-TW;q=0.4,ko;q=0.2
Cache-Control:no-cache
Connection:keep-alive
Content-Length:48
content-type:application/json

kobvel

kobvel commented on Oct 31, 2016

@kobvel

So, no way to prevent Lowercasing of headers?

mislav

mislav commented on Oct 31, 2016

@mislav
Contributor

@kobvel That's correct.

staabm

staabm commented on Oct 31, 2016

@staabm

chrome-dev-tool Network panel will divide these requests into Other not XHR.

@hashplus you should report that bug to the chrome team.

AMorgaut

AMorgaut commented on Mar 7, 2017

@AMorgaut

Same issue when sending requests to Gerrit server

It doesn't work when header 'X-Gerrit-Auth' is transformed to 'x-gerrit-auth' by the fetch API

I can post an issue to the Gerrit team but...
I'm pretty sure that plenty of legacy servers will have similar issues
(even more on custom header names that are not managed by core http server code but by application level one)

AMorgaut

AMorgaut commented on Mar 8, 2017

@AMorgaut

Same issue when sending requests to Gerrit server

It doesn't work when header 'X-Gerrit-Auth' is transformed to 'x-gerrit-auth' by the fetch API

I can post an issue to the Gerrit team but...
I'm pretty sure that plenty of legacy servers will have similar issues
(even more on custom header names that are not managed by core http server code but by application level one)

To get an idea, I looked into Gerrit Server implementation

It is based on Tomcat which getHeader() API is case insensitive

This header is occasionally added to the CORS Access-Control-Request-Headers HTTP header.
To handle CORS, they use a filter written this way .filter(h -> !ALLOWED_CORS_REQUEST_HEADERS.contains(h)) and of course, they didn't lowercased their header values before.

I created a ticket to the gerrit project: https://bugs.chromium.org/p/gerrit/issues/detail?id=5733

My point is just that we can be sure that the fetch API is probably unfortunately not usable, as is, on many (how many?) legacy servers.

It may be ok on Open Source project based services, as the mentioned one, to which we can contribute, but it can be a way harder issue when connecting to commercial closed-source services (or open source based ones that are not regularly maintained)

amrdraz

amrdraz commented on Mar 8, 2017

@amrdraz

@AMorgaut the workaround I resorted to was using axios until the server I was working with fixed their problem.

since it's fetch that lower cases not the XHR Object

iamawaisakram

iamawaisakram commented on Feb 18, 2019

@iamawaisakram

@AMorgaut the workaround I resorted to was using axios until the server I was working with fixed their problem.

since it's fetch that lower cases not the XHR Object

It's not working now! Even the headers in axios are converted to lowercase now.

MiriDevAndro

MiriDevAndro commented on Mar 31, 2020

@MiriDevAndro

omg i want to use header as case sensitive any help . i have use and flutter but same as react native . just java is perfect.

msvargas

msvargas commented on Sep 30, 2020

@msvargas

This working in react-native, I share here to help anybody.
polyfill.ts

 // Disable lowercase in FormData
//@ts-ignore
FormData.prototype.getParts = function(): Array<FormDataPart> {
  //@ts-ignore
  return this._parts.map(([name, value]) => {
    const contentDisposition = 'form-data; name="' + name + '"';
    //@ts-ignore
    const headers: Headers = { 'Content-Disposition': contentDisposition };

    // The body part is a "blob", which in React Native just means
    // an object with a `uri` attribute. Optionally, it can also
    // have a `name` and `type` attribute to specify filename and
    // content type (cf. web Blob interface.)
    if (typeof value === 'object' && value) {
      if (typeof value.name === 'string') {
        //@ts-ignore
        headers['Content-Disposition'] += '; filename="' + value.name + '"';
      }
      if (typeof value.type === 'string') {
        //@ts-ignore
        headers['Content-Type'] = value.type;
      }
      return { ...value, headers, fieldName: name };
    }
    // Convert non-object values to strings as per FormData.append() spec
    return { string: String(value), headers, fieldName: name };
  });
};

// Disable lowercase in headers
XMLHttpRequest.prototype.setRequestHeader = function(
  header: string,
  value: any
): void {
  if (this.readyState !== this.OPENED) {
    throw new Error('Request has not been opened');
  }
  //@ts-ignore
  this._headers[header /* .toLowerCase() */] = String(value);
};

index.js

import './polyfill.ts'
...
Ross-Hale

Ross-Hale commented on Sep 30, 2020

@Ross-Hale

Scripts for Artificial Intelligence

Ross-Hale

Ross-Hale commented on Sep 30, 2020

@Ross-Hale

We need Artificial Intelligence since Natural Intelligence is in such short supply!

Repository owner locked as resolved and limited conversation to collaborators on Sep 30, 2020
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

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @mislav@smith@AMorgaut@staabm@dgraham

        Issue actions

          Why should we do toLowerCase to header name (by normalizeName()) ? · Issue #249 · JakeChampion/fetch