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

Fix Default Encoding for application/json Content-Type in HTTP Responses #1422

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

snoopdoggy322
Copy link

This merge request addresses a long-standing issue (#175) where the http package defaults to latin1 encoding when no charset is specified in the Content-Type header. Per RFC 8259, the default encoding for application/json should be utf-8.

The fix ensures that responses with Content-Type: application/json and no explicit charset parameter are decoded using utf8 by default. This change improves compliance with the JSON standard and prevents decoding errors for valid JSON payloads encoded in utf-8.

@snoopdoggy322
Copy link
Author

can anyone reply to my pull request?

@seifibrahim32
Copy link

seifibrahim32 commented Feb 4, 2025

Great but, could you try to pass some Chinese or Korean language tests through conformance tests? @snoopdoggy322.

@kevmoo
Copy link
Member

kevmoo commented Feb 4, 2025

CC @brianquinlan @devoncarew

Ooo...could be good

Copy link

github-actions bot commented Feb 4, 2025

PR Health

Changelog Entry
Package Changed Files
package:http pkgs/http/lib/src/multipart_file.dart
pkgs/http/lib/src/response.dart
pkgs/http/lib/src/utils.dart

Changes to files need to be accounted for in their respective changelogs.

This check can be disabled by tagging the PR with skip-changelog-check.

Coverage ✔️
File Coverage
pkgs/http/lib/src/multipart_file.dart 💚 95 %
pkgs/http/lib/src/response.dart 💚 100 %
pkgs/http/lib/src/utils.dart 💚 96 % ⬆️ 0 %

This check for test coverage is informational (issues shown here will not fail the PR).

API leaks ✔️

The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.

Package Leaked API symbols
License Headers ✔️
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
Files
no missing headers

All source files should start with a license header.

Unrelated files missing license headers
Files
pkgs/http/example/main.dart
pkgs/http_client_conformance_tests/example/client_test.dart
pkgs/http_client_conformance_tests/lib/src/dummy_isolate.dart
pkgs/http_parser/test/example_test.dart
pkgs/http_profile/lib/http_profile.dart
pkgs/web_socket/example/web_socket_example.dart
pkgs/web_socket/lib/testing.dart
pkgs/web_socket_conformance_tests/example/client_test.dart

/// encoding name is unknown, [latin1] is used by default, as per
/// [RFC 2616][].
/// encoding name is unknown, [utf8] is used by default, as per
/// [RFC3629][].
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you site a section? Is this only for JSON data for for all payloads?

Copy link
Author

@snoopdoggy322 snoopdoggy322 Feb 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, RFC3629 requires interpreting application/json as UTF-8, everything else is described as incorrect interpretation of the specification

Copy link
Collaborator

@brianquinlan brianquinlan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work, we are almost there!

Would you also:

  1. change the version in pubspec.yaml to version: 1.4.0-wip
  2. add a 1.4.0-wip section to CHANGELOG.md with a description of your change

final utf8Bytes = utf8.encode('{"foo":"Привет, мир!"}');
var response = http.Response.bytes(utf8Bytes, 200,
headers: {'content-type': 'application/json'});
expect(response.body, equals('{"foo":"Привет, мир!"}'));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, there should be one except per test because you are testing a single scenario.

Could you add tests for these additional scenarios:

  1. test .body with a non-empty charset with content-type application/json data (e.g. with Russian and iso-8859-1)
  2. test .body with an empty charset with a content-type of test/plain (e.g. with Russian to verify that the default of iso-8859-1 is used)

/// charset is unknown.
/// If the `Content-Type` header specifies a charset, it will use that charset.
/// If no charset is provided or the charset is unknown:
/// - Defaults to [utf8] if the `Content-Type` is `application/json` (since JSON is defined to use UTF-8 by default).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrap to 80 columns

@@ -21,10 +21,10 @@ class Response extends BaseResponse {
///
/// This is converted from [bodyBytes] using the `charset` parameter of the
/// `Content-Type` header field, if available. If it's unavailable or if the
/// encoding name is unknown, [latin1] is used by default, as per
/// [RFC 2616][].
/// encoding name is unknown, [utf8] is used by default,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only when content-type is UTF-8 right? So could you clarify that in your comments e.g.

If it's unavailable or if the encoding name is unknown:

  1. [utf8] is used when the content-type is 'application/json' (see [RFC 3629]).
  2. [latin1] is used in all other cases (see [RFC 2616][]).

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

Successfully merging this pull request may close these issues.

4 participants