Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dio is forcing headers to lowercase #641

Closed
shaxxx opened this issue Jan 10, 2020 · 37 comments · Fixed by #2008
Closed

Dio is forcing headers to lowercase #641

shaxxx opened this issue Jan 10, 2020 · 37 comments · Fixed by #2008

Comments

@shaxxx
Copy link

shaxxx commented Jan 10, 2020

Dio version: dio: ^3.0.8

When I set Dio header like this

dio.options.headers['Authorization'] = 'dGVzdDp0ZXN0';

I expect request header to look like this

Authorization: Basic dGVzdDp0ZXN0

Not like this (notice that capital "A" was transformed to "a")

authorization: Basic dGVzdDp0ZXN0

Reason for this is HERE. All headers are transformed to lower case.
I can only guess what your motivation for this was, but this is wrong.

Please read about it HERE and HERE

Even Dart team is currently reverting this
https://dart-review.googlesource.com/c/sdk/+/119100

Dio 2.1.5 did not have this behavior. I was able to use AltHttpClient with Dio and headers where left AS IS.

@shaxxx
Copy link
Author

shaxxx commented Jan 10, 2020

After some inspection I can confirm that version Dio 3.0.7 works as expected, it doesn't change headers casing. Problem is commit by @wendux 12 days ago.
I'm even more sure now that this is bug since entire commit was marked as "code style improvement". Please revert changes.

@stale
Copy link

stale bot commented Feb 9, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If this is still an issue, please make sure it is up to date and if so, add a comment that this is still an issue to keep it open. Thank you for your contributions.

@stale stale bot added the stale label Feb 9, 2020
@shaxxx
Copy link
Author

shaxxx commented Feb 9, 2020

Yes, this issue is very much still open

@stale stale bot removed the stale label Feb 9, 2020
@yangyangyyluck
Copy link

same problem.
Dio version 3.0.8
the bug came to assail me.
I need headers like CamelCase.
user-agent => User-Agent
referer => Referer
content-type => Content-Type
and so on...
as @shaxxx say, please revert changes.

@shaxxx
Copy link
Author

shaxxx commented Mar 2, 2020

FYI: Dart team has enabled support for case sensitive headers in the new upcoming version.
New Dart (and Flutter) release will support case sensitive headers, so should Dio.

@masseelch
Copy link

But the RFC clearly states, that headers are case-insensitive.
This means it should not matter if dio sends "content-type" or "Content-Type" or "cOntEnt-TyPE".
The server has the bug here. Not this package.

@shaxxx
Copy link
Author

shaxxx commented Mar 26, 2020

@masseelch I'm aware what RFC states, and I'm aware how servers should work.
I'm also aware there are millions of servers in the wild that are not acting according to RFC.
Forcing all headers to lowercase does not make Dio act more or less according to RFC.
RFC doesn't care about the headers casing, neither should Dio. Let developers worry about it.
Only possible reasons why Dio forces this:

  • because it's easier to maintain one codebase for HTTP and HTTP/2 (which expects lowercase)
  • because that's the way Dart team has implemented this (and reverted this in the next Dart version)
    Dart authors are aware of this and decided to revert this same behavior Dio is trying to force.

Are you aware of millions of people using apps that talk with devices running some kind of web server (like TV, Cable, Satellite receivers)? Do you think it realistic for users of my app to contact their cable provider, or maybe manufacturer of hardware to change their behavior?

Authors of Google Chrome are aware of this, yet they're sending 'Authorization' header, not 'authorization'. Why do you think this is the case?

And like I said in my previous post, I don't believe that someone has given any thought about this. Whole commit was marked as "code style improvement". If something breaks previous behavior it's all but not "code style improvement".

@masseelch
Copy link

masseelch commented Mar 27, 2020

RFC doesn't care about the headers casing, neither should Dio. Let developers worry about it.

This indeed is a valid point.

If something breaks previous behavior it's all but not "code style improvement".

Yes. This should be at least a new minor version.

If i think about it, it does not hurt to leave the header key untouched.

@jibiel
Copy link

jibiel commented Apr 19, 2020

Also I believe it is causing the following case:

flutter: headers:
flutter:  content-type: application/json; charset=utf-8
flutter:  x-auth-token: null
flutter:  X-Auth-Token: QcD7S_nbLJ7prcyU95pN

[via LogInterceptor]

I don't mind double assignments of headers that overwrite one another in my codebase (which would be the case if the lowercasing was not the case), but I do mind having to go over it to find out the reason behind these header values.

Both headers were assigned as options.headers['X-Auth-Token'] = ..., but the downcased one was passed to Dio(options) and the latter one was assigned during onRequest in an Interceptor.

@wstrange
Copy link

wstrange commented May 5, 2020

Just got bit by this as well.

@MaYunFei
Copy link

same problem.

@stale
Copy link

stale bot commented Jun 13, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If this is still an issue, please make sure it is up to date and if so, add a comment that this is still an issue to keep it open. Thank you for your contributions.

@stale stale bot added the stale label Jun 13, 2020
@shaxxx
Copy link
Author

shaxxx commented Jun 13, 2020

Still an issue.

@stale stale bot removed the stale label Jun 13, 2020
@pengshaomin
Copy link

same problem.

1 similar comment
@conghaonet
Copy link

same problem.

@matejthetree
Copy link

same problem

@rdsuncn
Copy link

rdsuncn commented Jul 28, 2020

same problem.

@wendux wendux closed this as completed in 516825f Aug 7, 2020
wendux added a commit that referenced this issue Aug 7, 2020
@vickyleu
Copy link

io_adapter.dart====>>>

  options.headers.forEach((k, v) {
   ##### if header value is null, build BytesBuilder will crash,set preserveHeaderCase true to keep case
    request.headers.set(k, v??"null",preserveHeaderCase: true);
  });

@SteveOye
Copy link

Same problem. Has anyone gotten a solution yet?

@hnxyzhw
Copy link

hnxyzhw commented Jan 13, 2021

same problem.

@szlxz
Copy link

szlxz commented Feb 22, 2021

Same problem. Has anyone gotten a solution yet?

@zhangxiongbiao
Copy link

io_adapter.dart====>>>

  options.headers.forEach((k, v) {
   ##### if header value is null, build BytesBuilder will crash,set preserveHeaderCase true to keep case
    request.headers.set(k, v??"null",preserveHeaderCase: true);
  });

should change io_adapter.dart like this.

@johnnycook
Copy link

johnnycook commented Apr 6, 2021

same problem :/

Edit: Btw, @vickyleu 's solution solves my issue with old device returning 400 Bad Request

@fernando-s97
Copy link

@vickyleu how can I apply your fix?

@yisusparkr
Copy link

If someone still having this issue, I recommend you to use the HttpClient class from dart:io.

I fixed it with the following code block:

HttpClient client = new HttpClient();
await client
  .getUrl(Uri.parse("YOUR URL"))
  .then((HttpClientRequest request) {
     request.headers.set(
       "Authorization",
       "Bearer TOKEN",
        preserveHeaderCase: true,
     );
     // Optionally write to the request object...
     // Then call close.
     return request.close();
   }).then((HttpClientResponse response) {
      final completer = Completer<String>();
      final contents = StringBuffer();
      response.transform(utf8.decoder).listen((data) {
      contents.write(data);
      print(data);
      }, onDone: () => completer.complete(contents.toString()));
});

THIS CODE BLOCK WILL NOT WORK IN FLUTTER WEB, use http or Dio packages instead.

I suggest you check out the official documentation:
HttpClient class
HttpHeader class

@johnnycook
Copy link

Yes, this was also my workaround, but I don't think it's that nice. I'd prefer if dio would implement some property that would propagate to underlying client to set this.

@omeraydindev
Copy link

Just got bit by this as well... tracking it down took a good 4 hours :/

io_adapter.dart====>>>

  options.headers.forEach((k, v) {
   ##### if header value is null, build BytesBuilder will crash,set preserveHeaderCase true to keep case
    request.headers.set(k, v??"null",preserveHeaderCase: true);
  });

My workaround was, instead of editing an already existing file of dio, I found it safer to copy the adapter from io_adapter.dart to another file in my own project and do the changes there. Then I used httpClientAdapter property of my Dio client to use it.

I shared the gist here in case anyone is interested.

With that being said, I do think dio should implement a way (like a flag) for us to be able to disable case-insensitive header names, as workarounds like this are dirty.

@Toavina23
Copy link

still no updates of dio to support this ?
that bug is really frustrating me right now

@manjarqo
Copy link

same problem

@T-moz
Copy link

T-moz commented Nov 4, 2022

Should be opened

@NRMrYang
Copy link

Should be opened.
Same problem

@AlexV525
Copy link
Member

AlexV525 commented Dec 8, 2022

Hey guys. I saw there is a commit that removes .toLowerCase(), is that mean the commit is valid or does not cover all cases? If so, can you guys provide a minimum example that fails?

Also, can anyone provide any commit link that the Dart team reverted in the previous Dart SDK? That helps to apply new fixes too.

cc @shaxxx @vickyleu

@dr-samrat
Copy link

I hope this gets fixed soon. Still facing the issue. Since we are newly making the api contract, we are migrating to case-insensitive headers.

@onayem
Copy link

onayem commented Mar 24, 2023

This issue still alive. I am facing the same issue. Please solve this out, even adding a flag could help the ones facing this issue.

@brunogc
Copy link

brunogc commented Aug 25, 2023

The issue is 'closed' but I keep experiencing this issue in version 5.3.2.

@mayankHype
Copy link

Same the issue is 'closed' but I keep experiencing this issue in version 5.3.2.

@AlexV525
Copy link
Member

AlexV525 commented Oct 20, 2023

We no longer handle issues before 12th Feb 2023. Please submit new issues with new requirements.

@cfug cfug locked and limited conversation to collaborators Oct 20, 2023
@AlexV525 AlexV525 linked a pull request Oct 23, 2023 that will close this issue
7 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.