From d12901e20a43112c23913a21c220549418164e34 Mon Sep 17 00:00:00 2001 From: Brian Quinlan Date: Wed, 29 Nov 2023 16:33:57 -0800 Subject: [PATCH] Add support for setting headers for all requests --- pkgs/cupertino_http/CHANGELOG.md | 5 ++- .../url_session_configuration_test.dart | 43 +++++++++++++++++++ pkgs/cupertino_http/example/lib/main.dart | 4 ++ .../cupertino_http/lib/src/cupertino_api.dart | 27 ++++++++++++ pkgs/cupertino_http/pubspec.yaml | 2 +- 5 files changed, 79 insertions(+), 2 deletions(-) diff --git a/pkgs/cupertino_http/CHANGELOG.md b/pkgs/cupertino_http/CHANGELOG.md index 48d990e185..d768f7a5c7 100644 --- a/pkgs/cupertino_http/CHANGELOG.md +++ b/pkgs/cupertino_http/CHANGELOG.md @@ -1,4 +1,7 @@ -## 1.1.1-wip +## 1.2.0 + +* Add support for setting additional http headers in + `URLSessionConfiguration`. ## 1.1.0 diff --git a/pkgs/cupertino_http/example/integration_test/url_session_configuration_test.dart b/pkgs/cupertino_http/example/integration_test/url_session_configuration_test.dart index 85386bcd90..e763337156 100644 --- a/pkgs/cupertino_http/example/integration_test/url_session_configuration_test.dart +++ b/pkgs/cupertino_http/example/integration_test/url_session_configuration_test.dart @@ -2,10 +2,37 @@ // 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. +import 'dart:io'; + import 'package:cupertino_http/cupertino_http.dart'; import 'package:integration_test/integration_test.dart'; import 'package:test/test.dart'; +Future>> sentHeaders( + URLSessionConfiguration config) async { + final session = URLSession.sessionWithConfiguration(config); + final headers = >{}; + final server = (await HttpServer.bind('localhost', 0)) + ..listen((request) async { + request.headers.forEach((k, v) => headers[k] = v); + await request.drain(); + request.response.headers.set('Content-Type', 'text/plain'); + request.response.write('Hello World'); + await request.response.close(); + }); + + final task = session.dataTaskWithRequest( + URLRequest.fromUrl(Uri.parse('http://localhost:${server.port}'))) + ..resume(); + while (task.state != URLSessionTaskState.urlSessionTaskStateCompleted) { + // Let the event loop run. + await Future.delayed(const Duration()); + } + + await server.close(); + return headers; +} + void testProperties(URLSessionConfiguration config) { group('properties', () { test('allowsCellularAccess', () { @@ -32,6 +59,22 @@ void testProperties(URLSessionConfiguration config) { config.discretionary = false; expect(config.discretionary, false); }); + test('httpAdditionalHeaders', () async { + expect(config.httpAdditionalHeaders, isNull); + + config.httpAdditionalHeaders = { + 'User-Agent': 'My Client', + 'MyHeader': 'myvalue' + }; + expect(config.httpAdditionalHeaders, + {'User-Agent': 'My Client', 'MyHeader': 'myvalue'}); + final headers = await sentHeaders(config); + expect(headers, containsPair('user-agent', ['My Client'])); + expect(headers, containsPair('myheader', ['myvalue'])); + + config.httpAdditionalHeaders = null; + expect(config.httpAdditionalHeaders, isNull); + }); test('httpCookieAcceptPolicy', () { config.httpCookieAcceptPolicy = HTTPCookieAcceptPolicy.httpCookieAcceptPolicyAlways; diff --git a/pkgs/cupertino_http/example/lib/main.dart b/pkgs/cupertino_http/example/lib/main.dart index edfceac92e..0d3b98ef6d 100644 --- a/pkgs/cupertino_http/example/lib/main.dart +++ b/pkgs/cupertino_http/example/lib/main.dart @@ -15,6 +15,10 @@ import 'book.dart'; void main() { var clientFactory = Client.new; // The default Client. if (Platform.isIOS || Platform.isMacOS) { + final config = URLSessionConfiguration.ephemeralSessionConfiguration() + ..cache = URLCache.withCapacity(memoryCapacity: 2 * 1024 * 1024) + ..httpAdditionalHeaders = {'User-Agent': 'Book Agent'}; + clientFactory = () => CupertinoClient.fromSessionConfiguration(config); clientFactory = CupertinoClient.defaultSessionConfiguration.call; } runWithClient(() => runApp(const BookSearchApp()), clientFactory); diff --git a/pkgs/cupertino_http/lib/src/cupertino_api.dart b/pkgs/cupertino_http/lib/src/cupertino_api.dart index 01c4853b1c..0317eeb834 100644 --- a/pkgs/cupertino_http/lib/src/cupertino_api.dart +++ b/pkgs/cupertino_http/lib/src/cupertino_api.dart @@ -344,6 +344,32 @@ class URLSessionConfiguration bool get discretionary => _nsObject.discretionary; set discretionary(bool value) => _nsObject.discretionary = value; + /// Additional headers to send with each request. + /// + /// Note that the getter for this field returns a **copy** of the headers. + /// + /// See [NSURLSessionConfiguration.HTTPAdditionalHeaders](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1411532-httpadditionalheaders) + Map? get httpAdditionalHeaders { + if (_nsObject.HTTPAdditionalHeaders == null) { + return null; + } + final headers = ncb.NSDictionary.castFrom(_nsObject.HTTPAdditionalHeaders!); + return stringDictToMap(headers); + } + + set httpAdditionalHeaders(Map? headers) { + if (headers == null) { + _nsObject.HTTPAdditionalHeaders = null; + return; + } + final d = ncb.NSMutableDictionary.alloc(linkedLibs).init(); + headers.forEach((key, value) { + d.setObject_forKey_( + value.toNSString(linkedLibs), key.toNSString(linkedLibs)); + }); + _nsObject.HTTPAdditionalHeaders = d; + } + /// What policy to use when deciding whether to accept cookies. /// /// See [NSURLSessionConfiguration.HTTPCookieAcceptPolicy](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1408933-httpcookieacceptpolicy). @@ -441,6 +467,7 @@ class URLSessionConfiguration 'allowsConstrainedNetworkAccess=$allowsConstrainedNetworkAccess ' 'allowsExpensiveNetworkAccess=$allowsExpensiveNetworkAccess ' 'discretionary=$discretionary ' + 'httpAdditionalHeaders=$httpAdditionalHeaders ' 'httpCookieAcceptPolicy=$httpCookieAcceptPolicy ' 'httpShouldSetCookies=$httpShouldSetCookies ' 'httpMaximumConnectionsPerHost=$httpMaximumConnectionsPerHost ' diff --git a/pkgs/cupertino_http/pubspec.yaml b/pkgs/cupertino_http/pubspec.yaml index 9b7e1f828a..93cd94bfca 100644 --- a/pkgs/cupertino_http/pubspec.yaml +++ b/pkgs/cupertino_http/pubspec.yaml @@ -2,7 +2,7 @@ name: cupertino_http description: > A macOS/iOS Flutter plugin that provides access to the Foundation URL Loading System. -version: 1.1.1-wip +version: 1.2.0 repository: https://github.com/dart-lang/http/tree/master/pkgs/cupertino_http environment: