Multipart request headers must be Camel-Case not lower-case. Or at least provide some way to specify it
Please describe the bug and how to reproduce it.
I ran into a trouble using http package when I was consuming an API because the http package is using lower-case headers.
The RFC specification says headers must be case-insensitive, but some third-party services are implemented in a case-sensitive way.
A example service running this way is AnonFiles.com, and here is a reproducible example:
import 'dart:io';
import 'dart:typed_data';
import 'package:http/http.dart' as http;
class MyHttpoverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
void main() async {
// To debug with HTTP Toolkit
HttpOverrides.global = MyHttpoverrides();
var request = http.MultipartRequest(
'POST',
Uri.parse('https://api.anonfiles.com/upload'),
);
request.files.add(
http.MultipartFile.fromBytes(
'file',
Uint8List.fromList(
List<int>.filled(50, 0),
),
filename: 'file',
),
);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
} else {
print(response.reasonPhrase);
}
}
This will fail with status code 400.
But if you modify the line multipart_request.dart#L135 by replacing:
- 'content-disposition: form-data; name="${_browserEncode(file.field)}"';
+ 'Content-Disposition: form-data; name="${_browserEncode(file.field)}"';
You'll see the request will return 200 OK.
Although I agree that this is implementation error in the API side, I would appreciate a mechanism in this library that I can use to work around these issues since I've 0 control over the mentioned service.
This is the installed dependency version:
http:
dependency: "direct main"
description:
name: http
sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
url: "https://pub.dev"
source: hosted
version: "0.13.6"
Although it's not the latest version, the code I mentioned as containing the lower-cased headers is still present in the latest v1.0.0 version.
I also faced issues due to the 'content-disposition' string being in lowercase. While most APIs handle it without any problems, there can be cases where developers need more flexibility in handling it.
During my testing with 'dio', I discovered the 'camelCaseContentDisposition' option in the 'FormData' settings. It allowed me to address the problem caused by the lowercase 'content-disposition' string.
FormData.fromMap(
Map<String, dynamic> map, [
ListFormat collectionFormat = ListFormat.multi,
this.camelCaseContentDisposition = true,
])
It would be great if the 'MultipartRequest' in 'http' could also provide an option to set the 'content-disposition' string to to 'Content-Disposition'.