dio
A powerful Http client for Dart, which supports Interceptors, Global configuration, FormData, Request Cancellation, File downloading, Timeout, etc.
Get started
Add dependency
dependencies:
dio: 3.x #latest version
In order to support Flutter Web, v3.x was heavily refactored, so it was not compatible with version 3.x See here for a detailed list of updates.
Super simple to use
import 'package:dio/dio.dart';
void getHttp() async {
try {
Response response = await Dio().get("http://www.google.com");
print(response);
} catch (e) {
print(e);
}
}
awesome-dio
???? A curated list of awesome things related to dio.
Plugins
Plugins Status Description dio_cookie_manager A cookie manager for Dio dio_http2_adapter A Dio HttpClientAdapter which support Http/2.0 dio_flutter_transformer A Dio transformer especially for a flutter, by which the JSON decoding will be in the background with compute function. dio_http_cache A cache library for Dio, like Rxcache in Android. dio-http-cache uses sqflite as disk cache, and LRU strategy as memory cache. retrofit retrofit.dart is an dio client generator using source_gen and inspired by Chopper and Retrofit.
Related Projects
Welcome to submit Dio’s third-party plugins and related libraries here .
Table of contents
Examples
Performing a GET request:
Response response;
Dio dio = new Dio();
response = await dio.get("/test?id=12&name=wendu");
print(response.data.toString());
// Optionally the request above could also be done as
response = await dio.get("/test", queryParameters: {"id": 12, "name": "wendu"});
print(response.data.toString());
Performing a POST request:
response = await dio.post("/test", data: {"id": 12, "name": "wendu"});
Performing multiple concurrent requests:
response = await Future.wait([dio.post("/info"), dio.get("/token")]);
Downloading a file:
response = await dio.download("https://www.google.com/", "./xx.html");
Get response stream:
Response<ResponseBody> rs = await Dio().get<ResponseBody>(url,
options: Options(responseType: ResponseType.stream), // set responseType to `stream`
);
print(rs.data.stream); //response stream
Get response with bytes:
Response<List<int>> rs = await Dio().get<List<int>>(url,
options: Options(responseType: ResponseType.bytes), // // set responseType to `bytes`
);
print(rs.data); // List<int>
Sending FormData:
FormData formData = new FormData.fromMap({
"name": "wendux",
"age": 25,
});
response = await dio.post("/info", data: formData);
Uploading multiple files to server by FormData:
FormData.fromMap({
"name": "wendux",
"age": 25,
"file": await MultipartFile.fromFile("./text.txt",filename: "upload.txt"),
"files": [
await MultipartFile.fromFile("./text1.txt", filename: "text1.txt"),
await MultipartFile.fromFile("./text2.txt", filename: "text2.txt"),
]
});
response = await dio.post("/info", data: formData);
Listening the uploading progress:
response = await dio.post(
"http://www.dtworkroom.com/doris/1/2.0.0/test",
data: {"aa": "bb" * 22},
onSendProgress: (int sent, int total) {
print("$sent $total");
},
);
Post binary data by Stream:
// Binary data
List<int> postData = <int>[...];
await dio.post(
url,
data: Stream.fromIterable(postData.map((e) => [e])), //create a Stream<List<int>>
options: Options(
headers: {
Headers.contentLengthHeader: postData.length, // set content-length
},
),
);
…you can find all examples code here .
Dio APIs
Creating an instance and set default configs.
You can create instance of Dio with an optional BaseOptions object:
Dio dio = new Dio(); // with default Options
// Set default configs
dio.options.baseUrl = "https://www.xx.com/api";
dio.options.connectTimeout = 5000; //5s
dio.options.receiveTimeout = 3000;
// or new Dio with a BaseOptions instance.
BaseOptions options = new BaseOptions(
baseUrl: "https://www.xx.com/api",
connectTimeout: 5000,
receiveTimeout: 3000,
);
Dio dio = new Dio(options);
The core API in Dio instance is:
Future request(String path, {data,Map queryParameters, Options options,CancelToken cancelToken, ProgressCallback onSendProgress,
ProgressCallback onReceiveProgress)
response=await request(
"/test",
data: {"id":12,"name":"xx"},
options: Options(method:"GET"),
);
Request method aliases
For convenience aliases have been provided for all supported request methods.
Future get(…)
Future post(…)
Future put(…)
Future delete(…)
Future head(…)
Future put(…)
Future path(…)
Future download(…)
Request Options
The Options class describes the http request information and configuration. Each Dio instance has a base config for all requests maked by itself, and we can override the base config with [Options] when make a single request. The [BaseOptions] declaration as follows:
{
/// Http method.
String method;
/// Request base url, it can contain sub path, like: "https://www.google.com/api/".
String baseUrl;
/// Http request headers.
Map<String, dynamic> headers;
/// Timeout in milliseconds for opening url.
int connectTimeout;
/// Whenever more than [receiveTimeout] (in milliseconds) passes between two events from response stream,
/// [Dio] will throw the [DioError] with [DioErrorType.RECEIVE_TIMEOUT].
/// Note: This is not the receiving time limitation.
int receiveTimeout;
/// Request data, can be any type.
T data;
/// If the `path` starts with "http(s)", the `baseURL` will be ignored, otherwise,
/// it will be combined and then resolved with the baseUrl.
String path="";
/// The request Content-Type. The default value is "application/json; charset=utf-8".
/// If you want to encode request body with "application/x-www-form-urlencoded",
/// you can set [Headers.formUrlEncodedContentType], and [Dio]
/// will automatically encode the request body.
String contentType;
/// [responseType] indicates the type of data that the server will respond with
/// options which defined in [ResponseType] are `JSON`, `STREAM`, `PLAIN`.
///
/// The default value is `JSON`, dio will parse response string to json object automatically
/// when the content-type of response is "application/json".
///
/// If you want to receive response data with binary bytes, for example,
/// downloading a image, use `STREAM`.
///
/// If you want to receive the response data with String, use `PLAIN`.
ResponseType responseType;
/// `validateStatus` defines whether the request is successful for a given
/// HTTP response status code. If `validateStatus` returns `true` ,
/// the request will be perceived as successful; otherwise, considered as failed.
ValidateStatus validateStatus;
/// Custom field that you can retrieve it later in [Interceptor]、[Transformer] and the [Response] object.
Map<String, dynamic> extra;
/// Common query parameters
Map<String, dynamic /*String|Iterable<String>*/ > queryParameters;
}
There is a complete example here .
Response Schema
The response for a request contains the following information.
{
/// Response body. may have been transformed, please refer to [ResponseType].
T data;
/// Response headers.
Headers headers;
/// The corresponding request info.
Options request;
/// Http status code.
int statusCode;
/// Whether redirect
bool isRedirect;
/// redirect info
List<RedirectInfo> redirects ;
/// Returns the final real request uri (maybe redirect).
Uri realUri;
/// Custom field that you can retrieve it later in `then`.
Map<String, dynamic> extra;
}
When request is succeed, you will receive the response as follows:
Response response = await dio.get("https://www.google.com");
print(response.data);
print(response.headers);
print(response.request);
print(response.statusCode);
Interceptors
For each dio instance, We can add one or more interceptors, by which we can intercept requests or responses before they are handled by then or catchError.
dio.interceptors.add(InterceptorsWrapper(
onRequest:(RequestOptions options) async {
// Do something before request is sent
return options; //continue
// If you want to resolve the request with some custom data,
// you can return a `Response` object or return `dio.resolve(data)`.
// If you want to reject the request with a error message,
// you can return a `DioError` object or return `dio.reject(errMsg)`
},
onResponse:(Response response) async {
// Do something with response data
return response; // continue
},
onError: (DioError e) async {
// Do something with response error
return e;//continue
}
));
Simple interceptor example:
import 'package:dio/dio.dart';
class CustomInterceptors extends InterceptorsWrapper {
@override
Future onRequest(RequestOptions options) {
print("REQUEST[${options?.method}] => PATH: ${options?.path}");
return super.onRequest(options);
}
@override
Future onResponse(Response response) {
print("RESPONSE[${response?.statusCode}] => PATH: ${response?.request?.path}");
return super.onResponse(response);
}
@override
Future onError(DioError err) {
print("ERROR[${err?.response?.statusCode}] => PATH: ${err?.request?.path}");
return super.onError(err);
}
}
Resolve and reject the request
In all interceptors, you can interfere with their execution flow. If you want to resolve the request/response with some custom data,you can return a Response object or return dio.resolve(data). If you want to reject the request/response with a error message, you can return a DioError object or return dio.reject(errMsg) .
dio.interceptors.add(InterceptorsWrapper(
onRequest:(RequestOptions options) {
return dio.resolve("fake data")
},
));
Response response = await dio.get("/test");
print(response.data);//"fake data"
Lock/unlock the interceptors
You can lock/unlock the interceptors by calling their lock()/unlock method. Once the request/response interceptor is locked, the incoming request/response will be added to a queue before they enter the interceptor, they will not be continued until the interceptor is unlocked.
tokenDio = new Dio(); //Create a new instance to request the token.
tokenDio.options = dio;
dio.interceptors.add(InterceptorsWrapper(
onRequest:(Options options) async {
// If no token, request token firstly and lock this interceptor
// to prevent other request enter this interceptor.
dio.interceptors.requestLock.lock();
// We use a new Dio(to avoid dead lock) instance to request token.
Response response = await tokenDio.get("/token");
//Set the token to headers
options.headers["token"] = response.data["data"]["token"];
dio.interceptors.requestLock.unlock();
return options; //continue
}
));
You can clean the waiting queue by calling clear();
aliases
When the request interceptor is locked, the incoming request will pause, this is equivalent to we locked the current dio instance, Therefore, Dio provied the two aliases for the lock/unlock of request interceptors.
dio.lock() == dio.interceptors.requestLock.lock()
dio.unlock() == dio.interceptors.requestLock.unlock()
dio.clear() == dio.interceptors.requestLock.clear()
Example
Because of security reasons, we need all the requests to set up a csrfToken in the header, if csrfToken does not exist, we need to request a csrfToken first, and then perform the network request, because the request csrfToken progress is asynchronous, so we need to execute this async request in request interceptor. The code is as follows:
dio.interceptors.add(InterceptorsWrapper(
onRequest: (Options options) async {
print('send request:path:${options.path},baseURL:${options.baseUrl}');
if (csrfToken == null) {
print("no token,request token firstly...");
//lock the dio.
dio.lock();
return tokenDio.get("/token").then((d) {
options.headers["csrfToken"] = csrfToken = d.data['data']['token'];
print("request token succeed, value: " + d.data['data']['token']);
print(
'continue to perform request:path:${options.path},baseURL:${options.path}');
return options;
}).whenComplete(() => dio.unlock()); // unlock the dio
} else {
options.headers["csrfToken"] = csrfToken;
return options;
}
}
));
For complete codes click here .
Log
You can set LogInterceptor to print request/response log automaticlly, for example:
dio.interceptors.add(LogInterceptor(responseBody: false)); //开启请求日志
Custom Interceptor
You can custom interceptor by extending the Interceptor class. There is an example that implementing a simple cache policy: custom cache interceptor .
Cookie Manager
dio_cookie_manager package is a cookie manager for Dio.
Handling Errors
When a error occurs, Dio will wrap the Error/Exception to a DioError:
try {
//404
await dio.get("https://wendux.github.io/xsddddd");
} on DioError catch(e) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx and is also not 304.
if(e.response) {
print(e.response.data)
print(e.response.headers)
print(e.response.request)
} else{
// Something happened in setting up or sending the request that triggered an Error
print(e.request)
print(e.message)
}
}
DioError scheme
{
/// Response info, it may be `null` if the request can't reach to
/// the http server, for example, occurring a dns error, network is not available.
Response response;
/// Error descriptions.
String message;
DioErrorType type;
/// The original error/exception object; It's usually not null when `type`
/// is DioErrorType.DEFAULT
dynamic error;
}
DioErrorType
enum DioErrorType {
/// When opening url timeout, it occurs.
CONNECT_TIMEOUT,
///It occurs when receiving timeout.
RECEIVE_TIMEOUT,
/// When the server response, but with a incorrect status, such as 404, 503...
RESPONSE,
/// When the request is cancelled, dio will throw a error with this type.
CANCEL,
/// Default error type, Some other Error. In this case, you can
/// read the DioError.error if it is not null.
DEFAULT,
}
Using application/x-www-form-urlencoded format
By default, Dio serializes request data(except String type) to JSON. To send data in the application/x-www-form-urlencoded format instead, you can :
//Instance level
dio.options.contentType= Headers.formUrlEncodedContentType;
//or works once
dio.post("/info", data:{"id":5},
options: Options(contentType:Headers.formUrlEncodedContentType ));
Sending FormData
You can also send FormData with Dio, which will send data in the multipart/form-data, and it supports uploading files.
FormData formData = FormData.fromMap({
"name": "wendux",
"age": 25,
"file": await MultipartFile.fromFile("./text.txt",filename: "upload.txt")
});
response = await dio.post("/info", data: formData);
There is a complete example here .
Multiple files upload
There are two ways to add multiple files to FormData, the only difference is that upload keys are different for array types。
FormData.fromMap({
"files": [
MultipartFile.fromFileSync("./example/upload.txt",
filename: "upload.txt"),
MultipartFile.fromFileSync("./example/upload.txt",
filename: "upload.txt"),
]
});
The upload key eventually becomes “files[]”,This is because many back-end services add a middle bracket to key when they get an array of files. If you don’t want “[]” ,you should create FormData as follows(Don’t use FormData.fromMap):
var formData = FormData();
formData.files.addAll([
MapEntry(
"files",
MultipartFile.fromFileSync("./example/upload.txt",
filename: "upload.txt"),
),
MapEntry(
"files",
MultipartFile.fromFileSync("./example/upload.txt",
filename: "upload.txt"),
),
]);
Transformer
Transformer allows changes to the request/response data before it is sent/received to/from the server. This is only applicable for request methods ‘PUT’, ‘POST’, and ‘PATCH’. Dio has already implemented a DefaultTransformer, and as the default Transformer. If you want to customize the transformation of request/response data, you can provide a Transformer by your self, and replace the DefaultTransformer by setting the dio.transformer.
In flutter
If you use dio in flutter development, you’d better decode JSON in background with [compute] function.
// Must be top-level function
_parseAndDecode(String response) {
return jsonDecode(response);
}
parseJson(String text) {
return compute(_parseAndDecode, text);
}
void main() {
...
//Custom jsonDecodeCallback
(dio.transformer as DefaultTransformer).jsonDecodeCallback = parseJson;
runApp(MyApp());
}
Other Example
There is an example for customizing Transformer .
HttpClientAdapter
HttpClientAdapter is a bridge between Dio and HttpClient.
Dio implements standard and friendly API for developer.
HttpClient: It is the real object that makes Http requests.
We can use any HttpClient not just dart:io:HttpClient to make the Http request. And all we need is providing a HttpClientAdapter. The default HttpClientAdapter for Dio is DefaultHttpClientAdapter.
dio.httpClientAdapter = new DefaultHttpClientAdapter();
Here is a simple example to custom adapter.
Using proxy
DefaultHttpClientAdapter provide a callback to set proxy to dart:io:HttpClient, for example:
import 'package:dio/dio.dart';
import 'package:dio/adapter.dart';
...
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
// config the http client
client.findProxy = (uri) {
//proxy all request to localhost:8888
return "PROXY localhost:8888";
};
// you can also create a new HttpClient to dio
// return new HttpClient();
};
There is a complete example here .
Https certificate verification
There are two ways to verify the https certificate. Suppose the certificate format is PEM, the code like:
String PEM="XXXXX"; // certificate content
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
client.badCertificateCallback=(X509Certificate cert, String host, int port){
if(cert.pem==PEM){ // Verify the certificate
return true;
}
return false;
};
};
Another way is creating a SecurityContext when create the HttpClient:
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
SecurityContext sc = new SecurityContext();
//file is the path of certificate
sc.setTrustedCertificates(file);
HttpClient httpClient = new HttpClient(context: sc);
return httpClient;
};
In this way, the format of certificate must be PEM or PKCS12.
Http2 support
dio_http2_adapter package is a Dio HttpClientAdapter which support Http/2.0 .
Cancellation
You can cancel a request using a cancel token . One token can be shared with multiple requests. When a token’s cancel method invoked, all requests with this token will be cancelled.
CancelToken token = CancelToken();
dio.get(url1, cancelToken: token);
dio.get(url2, cancelToken: token);
// cancel the requests with "cancelled" message.
token.cancel("cancelled");
There is a complete example here .
Extends Dio class
Dio is a abstract class with factory constructor,so we don’t extend Dio class directy. For this purpose, we can extend DioForNative or DioForBrowser instead, for example:
import 'package:dio/dio.dart';
import 'package:dio/native_imp.dart'; //If in browser, import 'package:dio/browser_imp.dart'
class Http extends DioForNative {
Http([BaseOptions options]):super(options){
// do something
}
}
We can also implement our Dio client:
class MyDio with DioMixin implements Dio{
// ...
}
Copyright & License
This open source project authorized by https://flutterchina.club , and the license is MIT.
Features and bugs
Please file feature requests and bugs at the issue tracker .
Donate
Buy a cup of coffee for me (Scan by wechat):
Download DIO – A powerful Http client for Dart Source Code on GitHub
A powerful HTTP client for Dart and Flutter, which supports global settings, Interceptors, FormData, aborting and canceling a request, files uploading and downloading, requests timeout, custom adapters, etc. https://github.com/cfug/dio 1,559 forks. 12,832 stars. 29 open issues. Recent commits: fix(http2_adapter): handle closed streams during uploads (#2571)Supersedes #2469.The original report and reproduction are credited to @vanelizarov. Thisreplacement is rebuilt on the current `main` branch and addresses theunresolved review feedback and the cancellation hang found whileauditing the earlier implementation.### MotivationWhen an HTTP/2 peer closes a connection before a streamed request bodyfinishes, `http2` closes its outgoing stream controller. The requestbody subscription can then deliver another chunk to the closed sink,producing an unhandled `StateError: Bad state: Cannot add event afterclosing` instead of the transport error that caused the closure.### Changes- Stop the request body subscription when the outgoing HTTP/2 sink hasalready closed.- Explicitly settle request-body waiting when cancellation stops thesubscription, rather than relying on `onDone`, which is not called aftercancellation.- Keep cancellation callbacks weakly referenced so shared,never-cancelled tokens do not retain completed request resources.- Assert the exact `TransportConnectionException` for a peer connectionclosure and cover cancellation while the source stream remains open.- Update the `dio_http2_adapter` changelog.### VerificationWith only the new tests applied to `main`, the connection-closure testfails with the reported `StateError`, and the cancellation test timesout after two seconds. Both pass with this change, and the cancellationtest also confirms that the source stream listener is removed.`dart test` for `plugins/http2_adapter`, `melos run format`, and `melosrun analyze` complete successfully. An independent adversarial pass alsoexercised 20 concurrent cancellations, send timeout, a synchronousstream controller, and request-source error propagation.### Hosted verificationThe min, stable, and beta workflows all pass with the configured httpbunand proxy services. The stable workflow also passes formatting,analysis, publish dry-run, VM/Chrome/Firefox/Flutter tests, the exampleAPK build, and coverage reporting. Changed-file coverage for`http2_adapter.dart` increases from 75.69% to 82.42%.### AI assistanceImplementation, tests, and local review were performed with Codex. Aseparate Codex sub-agent performed the adversarial review. The originaldiagnosis and reproduction came from @vanelizarov in #2469.### New Pull Request Checklist- [x] I have read the[Documentation](https://pub.dev/documentation/dio/latest/)- [x] I have read the [Agent ContributionGuidelines](https://github.com/cfug/dio/blob/main/AGENTS.md) (requiredif any part of the change was produced with AI assistance)- [ ] I have searched for a similar pull request in the[project](https://github.com/cfug/dio/pulls) and found none *(notapplicable – this supersedes #2469)*- [x] I have updated this branch with the latest `main` branch to avoidconflicts (via merge from master or rebase)- [x] I have added the required tests to prove the fix/feature I'madding- [ ] I have updated the documentation (if necessary) *(not applicable -no public API or documented behavior changes)*- [x] I have run the tests without failures- [x] I have updated the `CHANGELOG.md` in the corresponding package### Additional context and info (if any)The replacement preserves the final outgoing-sink close as a normal`await`; the observed `StateError` originates from adding the next bodychunk after the transport has closed the sink, not from closing the sinkagain.Co-authored-by: Codex <noreply@openai.com> , GitHub fix(cookie_manager): prevent duplicate cookies on reused request options (#2572)Closes #2442.Supersedes #2498.## SummaryReusing the same `RequestOptions` instance sends it through`CookieManager` again with the Cookie header produced by the previouspass. Merging that generated header with the cookie jar again makes jarcookies accumulate on every pass.This change keeps weak per-`RequestOptions` state containing theoriginal source header and the last header generated by the manager.When the current header still exactly matches that generated value,`loadCookies` rebuilds it from the original caller input and the latestjar state.Unlike the name-only filtering proposed in #2498, this preserves theestablished behavior where caller-provided and jar cookies with the samename can coexist. It also removes stale jar values after updates,deletion, or an origin change.The state is intentionally scoped to the same `CookieManager` and`RequestOptions` instance reported in #2442. A copied request or adifferent manager instance is a new identity and is outside this fix.## Implementation details### Why an `Expando`[`Expando<T>`](https://api.dart.dev/dart-core/Expando-class.html)associates private data with an object identity without adding a fieldto that object's class. The association does not keep its property valuealive after the key object becomes inaccessible. It has been part of`dart:core` since before Dart 1.0, so this use does not raise thepackage's Dart 2.18 lower bound.`CookieManager` owns one instance:“`dartfinal Expando<_CookieHeaderState> _cookieHeaderStates = Expando();“`Each key is a `RequestOptions` object, and each value contains twoimmutable strings: the header supplied as the source of the merge andthe header last generated by this manager. Keeping this bookkeepingoutside `RequestOptions.extra` avoids reserving a user-visible key,exposing internal state to loggers, or copying an internal markerthrough `RequestOptions.copyWith`.### State transitions| Interceptor pass | Current Cookie header | Source used for the merge |Result || — | — | — | — || First pass | Caller header or `null` | Current header | Source +cookies currently loaded from the jar || Reused options, unchanged header | Exactly equals this manager's lastoutput | Stored original source | Original source + freshly loaded jarcookies || Header replaced between passes | Does not equal the last output | Newcurrent header | New source + freshly loaded jar cookies |For example:“`textfirst pass: source=provided=value, jar=session=old -> provided=value; session=oldsecond pass after the jar changes to session=new: source=provided=value, jar=session=new -> provided=value; session=new“`The old jar contribution is not treated as caller input, so it isneither duplicated nor retained after an update, deletion, or originchange.### Interceptor orderingRequest interceptors run in registration order. `CookieManager` readsboth `options.uri` and the current Cookie header at its position in thatchain, so interceptors that mutate either value must run before it:“`dartdio.interceptors ..add(uriOrCookieMutatingInterceptor) ..add(CookieManager(cookieJar)) ..add(interceptorThatDoesNotChangeUriOrCookies);“`Changes made by a later interceptor have these consequences:| Later mutation | Effect when the same options are reused || — | — || Authorization, body, method, `extra`, or unrelated headers | Does notaffect Cookie state matching || Replace the complete Cookie header | The replacement becomes thesource for the next merge || Append, reorder, or reformat the generated Cookie header | It nolonger exactly matches the stored output; the embedded old jar cookiescan be treated as source cookies and merged again || Change `baseUrl` or path | The current request may carry cookiesselected for the URI observed before that change |The URI case is an ordering requirement for the current request, notonly for retries. Moving a request from one origin or path to anotherafter `CookieManager` has selected cookies can send cookies outside thescope for which they were loaded.### Why not deduplicate cookie names or valuesA serialized Cookie request header contains `name=value` pairs but notthe domain and path metadata that identified the cookies in the jar. Thesame request can legitimately contain multiple cookies with the samename, and dio also deliberately preserves a caller-provided cookiealongside a same-name jar cookie.Filtering by name, or by a reconstructed cookie identity, thereforecannot distinguish a cookie generated by the previous interceptor passfrom one explicitly supplied by the caller. Tracking the exact previousoutput preserves that provenance without changing first-pass mergebehavior.### API and identity boundaries- No public API, request header precedence, or cookie ordering ischanged.- No state is added to `RequestOptions.extra`.- Entries are scoped to one `CookieManager` and one `RequestOptions`object identity.- A `copyWith` result or a different manager instance is a new identityand intentionally starts with its current header as a new source.## VerificationAdded six regression tests covering three sequential `Dio.fetch` callswith the same options, caller-provided same-name cookies, jar update anddeletion, origin changes, caller header replacement, and state isolationbetween options. All six fail against `origin/main` and pass with thischange.The `dio_cookie_manager` package passes 21 tests. Scoped Melos formatand fatal-info analysis checks are clean. Local coverage records 74 of75 executable lines in `cookie_mgr.dart` (98.67%), including all newstate logic.Implementation and tests by Codex; independent authenticity andadversarial review passes by two Codex subagents.### New Pull Request Checklist- [ ] I have read the[Documentation](https://pub.dev/documentation/dio/latest/)- [x] I have read the [Agent ContributionGuidelines](https://github.com/cfug/dio/blob/main/AGENTS.md) (requiredif any part of the change was produced with AI assistance)- [ ] I have searched for a similar pull request in the[project](https://github.com/cfug/dio/pulls) and found none *(notapplicable: this replaces #2498)*- [x] I have updated this branch with the latest `main` branch to avoidconflicts (via merge from master or rebase)- [x] I have added the required tests to prove the fix/feature I amadding- [ ] I have updated the documentation *(not applicable: no public APIor usage changes)*- [x] I have run the affected package tests without failures- [x] I have updated the `CHANGELOG.md` in the corresponding package### Additional context and infoThe previous implementation in #2498 used RFC 6265 cookie-store identityrules to justify filtering request-header cookies. Cookie-storereplacement and request-header merging are different operations; this PRavoids changing first-pass merge semantics.———Co-authored-by: Codex <noreply@openai.com> , GitHub build(deps): bump the codeql-action group with 3 updates (#2569)Bumps the codeql-action group with 3 updates:[github/codeql-action/init](https://github.com/github/codeql-action),[github/codeql-action/autobuild](https://github.com/github/codeql-action)and[github/codeql-action/analyze](https://github.com/github/codeql-action).Updates `github/codeql-action/init` from 4.37.0 to 4.37.1<details><summary>Release notes</summary><p><em>Sourced from <ahref="https://github.com/github/codeql-action/releases">github/codeql-action/init'sreleases</a>.</em></p><blockquote><h2>v4.37.1</h2><ul><li><em>Upcoming breaking change</em>: Add a deprecation warning forcustomers using CodeQL version 2.20.6 and earlier. These versions ofCodeQL were discontinued on 1 July 2026 alongside GitHub EnterpriseServer 3.16, and will be unsupported by the next minor release of theCodeQL Action. <ahref="https://redirect.github.com/github/codeql-action/pull/3956">#3956</a></li><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.1">2.26.1</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/4019">#4019</a></li></ul></blockquote></details><details><summary>Changelog</summary><p><em>Sourced from <ahref="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action/init'schangelog</a>.</em></p><blockquote><h1>CodeQL Action Changelog</h1><p>See the <ahref="https://github.com/github/codeql-action/releases">releasespage</a> for the relevant changes to the CodeQL CLI and languagepacks.</p><h2>[UNRELEASED]</h2><p>No user facing changes.</p><h2>4.37.1 – 16 Jul 2026</h2><ul><li><em>Upcoming breaking change</em>: Add a deprecation warning forcustomers using CodeQL version 2.20.6 and earlier. These versions ofCodeQL were discontinued on 1 July 2026 alongside GitHub EnterpriseServer 3.16, and will be unsupported by the next minor release of theCodeQL Action. <ahref="https://redirect.github.com/github/codeql-action/pull/3956">#3956</a></li><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.1">2.26.1</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/4019">#4019</a></li></ul><h2>4.37.0 – 08 Jul 2026</h2><ul><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.0">2.26.0</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/3995">#3995</a></li><li>In addition to the existing input format, the<code>config-file</code> input for the <code>codeql-action/init</code>step will soon support a new <code>[owner/]repo[@ref][:path]</code>format. All components except the repository name are optional. Ifomitted, <code>owner</code> defaults to the same owner as the repositorythe analysis is running for, <code>ref</code> to <code>main</code>, and<code>path</code> to <code>.github/codeql-action.yaml</code>. Supportfor this format ships in this version of the CodeQL Action, but willonly be enabled over the coming weeks. <ahref="https://redirect.github.com/github/codeql-action/pull/3973">#3973</a></li></ul><h2>4.36.3 – 01 Jul 2026</h2><p>No user facing changes.</p><h2>4.36.2 – 04 Jun 2026</h2><ul><li>Cache CodeQL CLI version information across Actions steps. <ahref="https://redirect.github.com/github/codeql-action/pull/3943">#3943</a></li><li>Reduce requests while waiting for analysis processing by usingexponential backoff when polling SARIF processing status. <ahref="https://redirect.github.com/github/codeql-action/pull/3937">#3937</a></li><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.6">2.25.6</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/3948">#3948</a></li></ul><h2>4.36.1 – 02 Jun 2026</h2><p>No user facing changes.</p><h2>4.36.0 – 22 May 2026</h2><ul><li><em>Breaking change</em>: Bump the minimum required CodeQL bundleversion to 2.19.4. <ahref="https://redirect.github.com/github/codeql-action/pull/3894">#3894</a></li><li>Add support for SHA-256 Git object IDs. <ahref="https://redirect.github.com/github/codeql-action/pull/3893">#3893</a></li><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.5">2.25.5</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/3926">#3926</a></li></ul><h2>4.35.5 – 15 May 2026</h2><ul><li>We have improved how the JavaScript bundles for the CodeQL Actionare generated to avoid duplication across bundles and reduce the size ofthe repository by around 70%. This should have no effect on the runtimebehaviour of the CodeQL Action. <ahref="https://redirect.github.com/github/codeql-action/pull/3899">#3899</a></li><li>For performance and accuracy reasons, <ahref="https://redirect.github.com/github/roadmap/issues/1158">improvedincremental analysis</a> will now only be enabled on a pull request whendiff-informed analysis is also enabled for that run. If diff-informedanalysis is unavailable (for example, because the PR diff ranges couldnot be computed), the action will fall back to a full analysis. <ahref="https://redirect.github.com/github/codeql-action/pull/3791">#3791</a></li><li>If multiple inputs are provided for the GitHub-internal<code>analysis-kinds</code> input, only <code>code-scanning</code> willbe enabled. The <code>analysis-kinds</code> input is experimental, forGitHub-internal use only, and may change without notice at any time. <ahref="https://redirect.github.com/github/codeql-action/pull/3892">#3892</a></li><li>Added an experimental change which, when running a Code Scanninganalysis for a PR with <ahref="https://redirect.github.com/github/roadmap/issues/1158">improvedincremental analysis</a> enabled, prefers CodeQL CLI versions that havea cached overlay-base database for the configured languages. This speedsup analysis for a repository when there is not yet a cached overlay-basedatabase for the latest CLI version. We expect to roll this change outto everyone in May. <ahref="https://redirect.github.com/github/codeql-action/pull/3880">#3880</a></li></ul><h2>4.35.4 – 07 May 2026</h2><ul><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.4">2.25.4</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/3881">#3881</a></li></ul><h2>4.35.3 – 01 May 2026</h2><!– raw HTML omitted –></blockquote><p>… (truncated)</p></details><details><summary>Commits</summary><ul><li><ahref="https://github.com/github/codeql-action/commit/7188fc363630916deb702c7fdcf4e481b751f97a"><code>7188fc3</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4020">#4020</a>from github/update-v4.37.1-9e7c07009</li><li><ahref="https://github.com/github/codeql-action/commit/c8b5f69be686908c3dfd844428137d56fe80c936"><code>c8b5f69</code></a>Update changelog for v4.37.1</li><li><ahref="https://github.com/github/codeql-action/commit/9e7c070092090e89e8b3d62f977d4456e0732cd7"><code>9e7c070</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4014">#4014</a>from github/mbg/explicit-remote-prefix</li><li><ahref="https://github.com/github/codeql-action/commit/3492b7e9ab96e28b1d8b971345d30e929c6f8fee"><code>3492b7e</code></a>Change <code>REMOTE_PATH_PREFIX</code> to <code>remote=</code></li><li><ahref="https://github.com/github/codeql-action/commit/3654baa924bc6456db54002581cb7c1c877548c4"><code>3654baa</code></a>Merge remote-tracking branch 'origin/main' intombg/explicit-remote-prefix</li><li><ahref="https://github.com/github/codeql-action/commit/2d682ac05f1b3588aaff3814826bede39b9ba6bb"><code>2d682ac</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4017">#4017</a>from github/dependabot/github_actions/dot-github/wor…</li><li><ahref="https://github.com/github/codeql-action/commit/23f6a50753a88efd9b7ae8687b29f6bdb65f6250"><code>23f6a50</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4009">#4009</a>from github/mbg/action-state/additions</li><li><ahref="https://github.com/github/codeql-action/commit/1ee3c75d1988ab8621f01ebb165115c38d56df91"><code>1ee3c75</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4018">#4018</a>from github/dependabot/github_actions/dot-github/wor…</li><li><ahref="https://github.com/github/codeql-action/commit/e053684dc500899b0b5520edc8549ac0f1ed730b"><code>e053684</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4015">#4015</a>from github/dependabot/npm_and_yarn/npm-minor-fd2e83…</li><li><ahref="https://github.com/github/codeql-action/commit/6803c5671d2f87a83ed96e151c441b1cb3bdc66a"><code>6803c56</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4019">#4019</a>from github/update-bundle/codeql-bundle-v2.26.1</li><li>Additional commits viewable in <ahref="https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9…7188fc363630916deb702c7fdcf4e481b751f97a">compareview</a></li></ul></details><br />Updates `github/codeql-action/autobuild` from 4.37.0 to 4.37.1<details><summary>Release notes</summary><p><em>Sourced from <ahref="https://github.com/github/codeql-action/releases">github/codeql-action/autobuild'sreleases</a>.</em></p><blockquote><h2>v4.37.1</h2><ul><li><em>Upcoming breaking change</em>: Add a deprecation warning forcustomers using CodeQL version 2.20.6 and earlier. These versions ofCodeQL were discontinued on 1 July 2026 alongside GitHub EnterpriseServer 3.16, and will be unsupported by the next minor release of theCodeQL Action. <ahref="https://redirect.github.com/github/codeql-action/pull/3956">#3956</a></li><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.1">2.26.1</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/4019">#4019</a></li></ul></blockquote></details><details><summary>Changelog</summary><p><em>Sourced from <ahref="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action/autobuild'schangelog</a>.</em></p><blockquote><h1>CodeQL Action Changelog</h1><p>See the <ahref="https://github.com/github/codeql-action/releases">releasespage</a> for the relevant changes to the CodeQL CLI and languagepacks.</p><h2>[UNRELEASED]</h2><p>No user facing changes.</p><h2>4.37.1 – 16 Jul 2026</h2><ul><li><em>Upcoming breaking change</em>: Add a deprecation warning forcustomers using CodeQL version 2.20.6 and earlier. These versions ofCodeQL were discontinued on 1 July 2026 alongside GitHub EnterpriseServer 3.16, and will be unsupported by the next minor release of theCodeQL Action. <ahref="https://redirect.github.com/github/codeql-action/pull/3956">#3956</a></li><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.1">2.26.1</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/4019">#4019</a></li></ul><h2>4.37.0 – 08 Jul 2026</h2><ul><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.0">2.26.0</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/3995">#3995</a></li><li>In addition to the existing input format, the<code>config-file</code> input for the <code>codeql-action/init</code>step will soon support a new <code>[owner/]repo[@ref][:path]</code>format. All components except the repository name are optional. Ifomitted, <code>owner</code> defaults to the same owner as the repositorythe analysis is running for, <code>ref</code> to <code>main</code>, and<code>path</code> to <code>.github/codeql-action.yaml</code>. Supportfor this format ships in this version of the CodeQL Action, but willonly be enabled over the coming weeks. <ahref="https://redirect.github.com/github/codeql-action/pull/3973">#3973</a></li></ul><h2>4.36.3 – 01 Jul 2026</h2><p>No user facing changes.</p><h2>4.36.2 – 04 Jun 2026</h2><ul><li>Cache CodeQL CLI version information across Actions steps. <ahref="https://redirect.github.com/github/codeql-action/pull/3943">#3943</a></li><li>Reduce requests while waiting for analysis processing by usingexponential backoff when polling SARIF processing status. <ahref="https://redirect.github.com/github/codeql-action/pull/3937">#3937</a></li><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.6">2.25.6</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/3948">#3948</a></li></ul><h2>4.36.1 – 02 Jun 2026</h2><p>No user facing changes.</p><h2>4.36.0 – 22 May 2026</h2><ul><li><em>Breaking change</em>: Bump the minimum required CodeQL bundleversion to 2.19.4. <ahref="https://redirect.github.com/github/codeql-action/pull/3894">#3894</a></li><li>Add support for SHA-256 Git object IDs. <ahref="https://redirect.github.com/github/codeql-action/pull/3893">#3893</a></li><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.5">2.25.5</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/3926">#3926</a></li></ul><h2>4.35.5 – 15 May 2026</h2><ul><li>We have improved how the JavaScript bundles for the CodeQL Actionare generated to avoid duplication across bundles and reduce the size ofthe repository by around 70%. This should have no effect on the runtimebehaviour of the CodeQL Action. <ahref="https://redirect.github.com/github/codeql-action/pull/3899">#3899</a></li><li>For performance and accuracy reasons, <ahref="https://redirect.github.com/github/roadmap/issues/1158">improvedincremental analysis</a> will now only be enabled on a pull request whendiff-informed analysis is also enabled for that run. If diff-informedanalysis is unavailable (for example, because the PR diff ranges couldnot be computed), the action will fall back to a full analysis. <ahref="https://redirect.github.com/github/codeql-action/pull/3791">#3791</a></li><li>If multiple inputs are provided for the GitHub-internal<code>analysis-kinds</code> input, only <code>code-scanning</code> willbe enabled. The <code>analysis-kinds</code> input is experimental, forGitHub-internal use only, and may change without notice at any time. <ahref="https://redirect.github.com/github/codeql-action/pull/3892">#3892</a></li><li>Added an experimental change which, when running a Code Scanninganalysis for a PR with <ahref="https://redirect.github.com/github/roadmap/issues/1158">improvedincremental analysis</a> enabled, prefers CodeQL CLI versions that havea cached overlay-base database for the configured languages. This speedsup analysis for a repository when there is not yet a cached overlay-basedatabase for the latest CLI version. We expect to roll this change outto everyone in May. <ahref="https://redirect.github.com/github/codeql-action/pull/3880">#3880</a></li></ul><h2>4.35.4 – 07 May 2026</h2><ul><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.4">2.25.4</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/3881">#3881</a></li></ul><h2>4.35.3 – 01 May 2026</h2><!– raw HTML omitted –></blockquote><p>… (truncated)</p></details><details><summary>Commits</summary><ul><li><ahref="https://github.com/github/codeql-action/commit/7188fc363630916deb702c7fdcf4e481b751f97a"><code>7188fc3</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4020">#4020</a>from github/update-v4.37.1-9e7c07009</li><li><ahref="https://github.com/github/codeql-action/commit/c8b5f69be686908c3dfd844428137d56fe80c936"><code>c8b5f69</code></a>Update changelog for v4.37.1</li><li><ahref="https://github.com/github/codeql-action/commit/9e7c070092090e89e8b3d62f977d4456e0732cd7"><code>9e7c070</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4014">#4014</a>from github/mbg/explicit-remote-prefix</li><li><ahref="https://github.com/github/codeql-action/commit/3492b7e9ab96e28b1d8b971345d30e929c6f8fee"><code>3492b7e</code></a>Change <code>REMOTE_PATH_PREFIX</code> to <code>remote=</code></li><li><ahref="https://github.com/github/codeql-action/commit/3654baa924bc6456db54002581cb7c1c877548c4"><code>3654baa</code></a>Merge remote-tracking branch 'origin/main' intombg/explicit-remote-prefix</li><li><ahref="https://github.com/github/codeql-action/commit/2d682ac05f1b3588aaff3814826bede39b9ba6bb"><code>2d682ac</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4017">#4017</a>from github/dependabot/github_actions/dot-github/wor…</li><li><ahref="https://github.com/github/codeql-action/commit/23f6a50753a88efd9b7ae8687b29f6bdb65f6250"><code>23f6a50</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4009">#4009</a>from github/mbg/action-state/additions</li><li><ahref="https://github.com/github/codeql-action/commit/1ee3c75d1988ab8621f01ebb165115c38d56df91"><code>1ee3c75</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4018">#4018</a>from github/dependabot/github_actions/dot-github/wor…</li><li><ahref="https://github.com/github/codeql-action/commit/e053684dc500899b0b5520edc8549ac0f1ed730b"><code>e053684</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4015">#4015</a>from github/dependabot/npm_and_yarn/npm-minor-fd2e83…</li><li><ahref="https://github.com/github/codeql-action/commit/6803c5671d2f87a83ed96e151c441b1cb3bdc66a"><code>6803c56</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4019">#4019</a>from github/update-bundle/codeql-bundle-v2.26.1</li><li>Additional commits viewable in <ahref="https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9…7188fc363630916deb702c7fdcf4e481b751f97a">compareview</a></li></ul></details><br />Updates `github/codeql-action/analyze` from 4.37.0 to 4.37.1<details><summary>Release notes</summary><p><em>Sourced from <ahref="https://github.com/github/codeql-action/releases">github/codeql-action/analyze'sreleases</a>.</em></p><blockquote><h2>v4.37.1</h2><ul><li><em>Upcoming breaking change</em>: Add a deprecation warning forcustomers using CodeQL version 2.20.6 and earlier. These versions ofCodeQL were discontinued on 1 July 2026 alongside GitHub EnterpriseServer 3.16, and will be unsupported by the next minor release of theCodeQL Action. <ahref="https://redirect.github.com/github/codeql-action/pull/3956">#3956</a></li><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.1">2.26.1</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/4019">#4019</a></li></ul></blockquote></details><details><summary>Changelog</summary><p><em>Sourced from <ahref="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action/analyze'schangelog</a>.</em></p><blockquote><h1>CodeQL Action Changelog</h1><p>See the <ahref="https://github.com/github/codeql-action/releases">releasespage</a> for the relevant changes to the CodeQL CLI and languagepacks.</p><h2>[UNRELEASED]</h2><p>No user facing changes.</p><h2>4.37.1 – 16 Jul 2026</h2><ul><li><em>Upcoming breaking change</em>: Add a deprecation warning forcustomers using CodeQL version 2.20.6 and earlier. These versions ofCodeQL were discontinued on 1 July 2026 alongside GitHub EnterpriseServer 3.16, and will be unsupported by the next minor release of theCodeQL Action. <ahref="https://redirect.github.com/github/codeql-action/pull/3956">#3956</a></li><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.1">2.26.1</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/4019">#4019</a></li></ul><h2>4.37.0 – 08 Jul 2026</h2><ul><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.0">2.26.0</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/3995">#3995</a></li><li>In addition to the existing input format, the<code>config-file</code> input for the <code>codeql-action/init</code>step will soon support a new <code>[owner/]repo[@ref][:path]</code>format. All components except the repository name are optional. Ifomitted, <code>owner</code> defaults to the same owner as the repositorythe analysis is running for, <code>ref</code> to <code>main</code>, and<code>path</code> to <code>.github/codeql-action.yaml</code>. Supportfor this format ships in this version of the CodeQL Action, but willonly be enabled over the coming weeks. <ahref="https://redirect.github.com/github/codeql-action/pull/3973">#3973</a></li></ul><h2>4.36.3 – 01 Jul 2026</h2><p>No user facing changes.</p><h2>4.36.2 – 04 Jun 2026</h2><ul><li>Cache CodeQL CLI version information across Actions steps. <ahref="https://redirect.github.com/github/codeql-action/pull/3943">#3943</a></li><li>Reduce requests while waiting for analysis processing by usingexponential backoff when polling SARIF processing status. <ahref="https://redirect.github.com/github/codeql-action/pull/3937">#3937</a></li><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.6">2.25.6</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/3948">#3948</a></li></ul><h2>4.36.1 – 02 Jun 2026</h2><p>No user facing changes.</p><h2>4.36.0 – 22 May 2026</h2><ul><li><em>Breaking change</em>: Bump the minimum required CodeQL bundleversion to 2.19.4. <ahref="https://redirect.github.com/github/codeql-action/pull/3894">#3894</a></li><li>Add support for SHA-256 Git object IDs. <ahref="https://redirect.github.com/github/codeql-action/pull/3893">#3893</a></li><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.5">2.25.5</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/3926">#3926</a></li></ul><h2>4.35.5 – 15 May 2026</h2><ul><li>We have improved how the JavaScript bundles for the CodeQL Actionare generated to avoid duplication across bundles and reduce the size ofthe repository by around 70%. This should have no effect on the runtimebehaviour of the CodeQL Action. <ahref="https://redirect.github.com/github/codeql-action/pull/3899">#3899</a></li><li>For performance and accuracy reasons, <ahref="https://redirect.github.com/github/roadmap/issues/1158">improvedincremental analysis</a> will now only be enabled on a pull request whendiff-informed analysis is also enabled for that run. If diff-informedanalysis is unavailable (for example, because the PR diff ranges couldnot be computed), the action will fall back to a full analysis. <ahref="https://redirect.github.com/github/codeql-action/pull/3791">#3791</a></li><li>If multiple inputs are provided for the GitHub-internal<code>analysis-kinds</code> input, only <code>code-scanning</code> willbe enabled. The <code>analysis-kinds</code> input is experimental, forGitHub-internal use only, and may change without notice at any time. <ahref="https://redirect.github.com/github/codeql-action/pull/3892">#3892</a></li><li>Added an experimental change which, when running a Code Scanninganalysis for a PR with <ahref="https://redirect.github.com/github/roadmap/issues/1158">improvedincremental analysis</a> enabled, prefers CodeQL CLI versions that havea cached overlay-base database for the configured languages. This speedsup analysis for a repository when there is not yet a cached overlay-basedatabase for the latest CLI version. We expect to roll this change outto everyone in May. <ahref="https://redirect.github.com/github/codeql-action/pull/3880">#3880</a></li></ul><h2>4.35.4 – 07 May 2026</h2><ul><li>Update default CodeQL bundle version to <ahref="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.4">2.25.4</a>.<ahref="https://redirect.github.com/github/codeql-action/pull/3881">#3881</a></li></ul><h2>4.35.3 – 01 May 2026</h2><!– raw HTML omitted –></blockquote><p>… (truncated)</p></details><details><summary>Commits</summary><ul><li><ahref="https://github.com/github/codeql-action/commit/7188fc363630916deb702c7fdcf4e481b751f97a"><code>7188fc3</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4020">#4020</a>from github/update-v4.37.1-9e7c07009</li><li><ahref="https://github.com/github/codeql-action/commit/c8b5f69be686908c3dfd844428137d56fe80c936"><code>c8b5f69</code></a>Update changelog for v4.37.1</li><li><ahref="https://github.com/github/codeql-action/commit/9e7c070092090e89e8b3d62f977d4456e0732cd7"><code>9e7c070</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4014">#4014</a>from github/mbg/explicit-remote-prefix</li><li><ahref="https://github.com/github/codeql-action/commit/3492b7e9ab96e28b1d8b971345d30e929c6f8fee"><code>3492b7e</code></a>Change <code>REMOTE_PATH_PREFIX</code> to <code>remote=</code></li><li><ahref="https://github.com/github/codeql-action/commit/3654baa924bc6456db54002581cb7c1c877548c4"><code>3654baa</code></a>Merge remote-tracking branch 'origin/main' intombg/explicit-remote-prefix</li><li><ahref="https://github.com/github/codeql-action/commit/2d682ac05f1b3588aaff3814826bede39b9ba6bb"><code>2d682ac</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4017">#4017</a>from github/dependabot/github_actions/dot-github/wor…</li><li><ahref="https://github.com/github/codeql-action/commit/23f6a50753a88efd9b7ae8687b29f6bdb65f6250"><code>23f6a50</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4009">#4009</a>from github/mbg/action-state/additions</li><li><ahref="https://github.com/github/codeql-action/commit/1ee3c75d1988ab8621f01ebb165115c38d56df91"><code>1ee3c75</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4018">#4018</a>from github/dependabot/github_actions/dot-github/wor…</li><li><ahref="https://github.com/github/codeql-action/commit/e053684dc500899b0b5520edc8549ac0f1ed730b"><code>e053684</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4015">#4015</a>from github/dependabot/npm_and_yarn/npm-minor-fd2e83…</li><li><ahref="https://github.com/github/codeql-action/commit/6803c5671d2f87a83ed96e151c441b1cb3bdc66a"><code>6803c56</code></a>Merge pull request <ahref="https://redirect.github.com/github/codeql-action/issues/4019">#4019</a>from github/update-bundle/codeql-bundle-v2.26.1</li><li>Additional commits viewable in <ahref="https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9…7188fc363630916deb702c7fdcf4e481b751f97a">compareview</a></li></ul></details><br />Dependabot will resolve any conflicts with this PR as long as you don'talter it yourself. You can also trigger a rebase manually by commenting`@dependabot rebase`.[//]: # (dependabot-automerge-start)[//]: # (dependabot-automerge-end)—<details><summary>Dependabot commands and options</summary><br />You can trigger Dependabot actions by commenting on this PR:- `@dependabot rebase` will rebase this PR- `@dependabot recreate` will recreate this PR, overwriting any editsthat have been made to it- `@dependabot show <dependency name> ignore conditions` will show allof the ignore conditions of the specified dependency- `@dependabot ignore <dependency name> major version` will close thisgroup update PR and stop Dependabot creating any more for the specificdependency's major version (unless you unignore this specificdependency's major version or upgrade to it yourself)- `@dependabot ignore <dependency name> minor version` will close thisgroup update PR and stop Dependabot creating any more for the specificdependency's minor version (unless you unignore this specificdependency's minor version or upgrade to it yourself)- `@dependabot ignore <dependency name>` will close this group update PRand stop Dependabot creating any more for the specific dependency(unless you unignore this specific dependency or upgrade to it yourself)- `@dependabot unignore <dependency name>` will remove all of the ignoreconditions of the specified dependency- `@dependabot unignore <dependency name> <ignore condition>` willremove the ignore condition of the specified dependency and ignoreconditions</details>Signed-off-by: dependabot[bot] <support@github.com>Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> , GitHub build(deps): bump actions/setup-java from 5.5.0 to 5.6.0 (#2570)Bumps [actions/setup-java](https://github.com/actions/setup-java) from5.5.0 to 5.6.0.<details><summary>Release notes</summary><p><em>Sourced from <ahref="https://github.com/actions/setup-java/releases">actions/setup-java'sreleases</a>.</em></p><blockquote><h2>v5.6.0</h2><h2>What's Changed</h2><ul><li>Backport to v5: Add Maven compiler problem matcher for javacdiagnostics by <ahref="https://github.com/brunoborges"><code>@brunoborges</code></a> in<ahref="https://redirect.github.com/actions/setup-java/pull/1087">actions/setup-java#1087</a></li><li>feat: expose cache-primary-key output (<ahref="https://redirect.github.com/actions/setup-java/issues/597">#597</a>)[v5 backport] by <ahref="https://github.com/brunoborges"><code>@brunoborges</code></a> in<ahref="https://redirect.github.com/actions/setup-java/pull/1089">actions/setup-java#1089</a></li><li>dist: Cover Tencent Kona JDK 25 (<ahref="https://redirect.github.com/actions/setup-java/issues/1108">#1108</a>)[v5 backport] by <ahref="https://github.com/brunoborges"><code>@brunoborges</code></a> in<ahref="https://redirect.github.com/actions/setup-java/pull/1110">actions/setup-java#1110</a></li><li>Backport <ahref="https://redirect.github.com/actions/setup-java/issues/1111">#1111</a>:Preserve Maven toolchains across repeated setup-java runs (<ahref="https://redirect.github.com/actions/setup-java/issues/1099">#1099</a>)by <ahref="https://github.com/brunoborges"><code>@brunoborges</code></a> in<ahref="https://redirect.github.com/actions/setup-java/pull/1113">actions/setup-java#1113</a></li><li>Backport <ahref="https://redirect.github.com/actions/setup-java/issues/1097">#1097</a>/<ahref="https://redirect.github.com/actions/setup-java/issues/1098">#1098</a>to v5: cache Maven and Gradle wrapper distributions separately by <ahref="https://github.com/brunoborges"><code>@brunoborges</code></a> in<ahref="https://redirect.github.com/actions/setup-java/pull/1122">actions/setup-java#1122</a></li></ul><p><strong>Full Changelog</strong>: <ahref="https://github.com/actions/setup-java/compare/v5…v5.6.0">https://github.com/actions/setup-java/compare/v5…v5.6.0</a></p></blockquote></details><details><summary>Commits</summary><ul><li><ahref="https://github.com/actions/setup-java/commit/03ad4de0992f5dab5e18fcb136590ce7c4a0ac95"><code>03ad4de</code></a>Backport <ahref="https://redirect.github.com/actions/setup-java/issues/1097">#1097</a>/<ahref="https://redirect.github.com/actions/setup-java/issues/1098">#1098</a>:cache Maven and Gradle wrapper distributions separately…</li><li><ahref="https://github.com/actions/setup-java/commit/d229d2e858d9137cc0b3f118fa5184b9f0a44ac4"><code>d229d2e</code></a>Backport <ahref="https://redirect.github.com/actions/setup-java/issues/1111">#1111</a>:Preserve Maven toolchains across repeated setup-java runs (<ahref="https://redirect.github.com/actions/setup-java/issues/1">#1</a>…</li><li><ahref="https://github.com/actions/setup-java/commit/bbf0f6967066506f72571a96d5d6c67ca42ab460"><code>bbf0f69</code></a>dist: Cover Tencent Kona JDK 25 (<ahref="https://redirect.github.com/actions/setup-java/issues/1110">#1110</a>)</li><li><ahref="https://github.com/actions/setup-java/commit/513edc4f8710565e4ad696f3b7d8e3bda584a46c"><code>513edc4</code></a>feat: expose cache-primary-key output (<ahref="https://redirect.github.com/actions/setup-java/issues/597">#597</a>)[v5 backport] (<ahref="https://redirect.github.com/actions/setup-java/issues/1089">#1089</a>)</li><li><ahref="https://github.com/actions/setup-java/commit/62df799a9c6e3022bb466697c66c36e9a2dbf347"><code>62df799</code></a>Add Maven compiler problem matcher for javac diagnostics (<ahref="https://redirect.github.com/actions/setup-java/issues/1087">#1087</a>)</li><li><ahref="https://github.com/actions/setup-java/commit/176156a187714aaf460b0a3c8f21e8b4f784b978"><code>176156a</code></a>chore: bump version to 5.6.0 for v5 release line</li><li><ahref="https://github.com/actions/setup-java/commit/bf7b8deac240b9cee05eb15ccdb1d2f424a54b9f"><code>bf7b8de</code></a>build: rebuild dist for backported changes (<ahref="https://redirect.github.com/actions/setup-java/issues/1079">#1079</a>,<ahref="https://redirect.github.com/actions/setup-java/issues/1083">#1083</a>,<ahref="https://redirect.github.com/actions/setup-java/issues/1084">#1084</a>)</li><li><ahref="https://github.com/actions/setup-java/commit/0173e6dd1b6e53ac3f6d68d220fa24cce79ae77c"><code>0173e6d</code></a>Infer distribution from asdf .tool-versions vendor prefix (<ahref="https://redirect.github.com/actions/setup-java/issues/1084">#1084</a>)</li><li><ahref="https://github.com/actions/setup-java/commit/f45cd82b67042e9e5c24cef950ea0c61736241c6"><code>f45cd82</code></a>Rename jdkFile input to jdk-file with deprecated alias (<ahref="https://redirect.github.com/actions/setup-java/issues/1083">#1083</a>)</li><li><ahref="https://github.com/actions/setup-java/commit/e2863ad49937c063e5a23922d1971a105f4f0140"><code>e2863ad</code></a>Map Zulu x86 architecture to i686 for Azul Metadata API (<ahref="https://redirect.github.com/actions/setup-java/issues/1079">#1079</a>)</li><li>Additional commits viewable in <ahref="https://github.com/actions/setup-java/compare/0f481fcb613427c0f801b606911222b5b6f3083a…03ad4de0992f5dab5e18fcb136590ce7c4a0ac95">compareview</a></li></ul></details><br />[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)Dependabot will resolve any conflicts with this PR as long as you don'talter it yourself. You can also trigger a rebase manually by commenting`@dependabot rebase`.[//]: # (dependabot-automerge-start)[//]: # (dependabot-automerge-end)—<details><summary>Dependabot commands and options</summary><br />You can trigger Dependabot actions by commenting on this PR:- `@dependabot rebase` will rebase this PR- `@dependabot recreate` will recreate this PR, overwriting any editsthat have been made to it- `@dependabot show <dependency name> ignore conditions` will show allof the ignore conditions of the specified dependency- `@dependabot ignore this major version` will close this PR and stopDependabot creating any more for this major version (unless you reopenthe PR or upgrade to it yourself)- `@dependabot ignore this minor version` will close this PR and stopDependabot creating any more for this minor version (unless you reopenthe PR or upgrade to it yourself)- `@dependabot ignore this dependency` will close this PR and stopDependabot creating any more for this dependency (unless you reopen thePR or upgrade to it yourself)</details>Signed-off-by: dependabot[bot] <support@github.com>Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> , GitHub fix(dio): preserve shared Future errors across interceptors (#2567)Closes #2565## ProblemDio 5.10.0 introduced a regression in the interceptor execution model. Acustom interceptor that deduplicates concurrent requests by sharing a`Completer` can expose an uncaught `DioException`, leave the duplicaterequest pending, or dispatch the same request more than once when theadapter fails immediately.The failure is not caused by request deduplication itself. It is causedby the interaction between deduplication and the per-callback errorzones introduced by #2499.## Root CauseInterceptor callbacks intentionally have public `void` return types:“`dartvoid onRequest(RequestOptions options, RequestInterceptorHandler handler)“`Dart still allows an async implementation or callback to produce aruntime `Future<void>`, but the public static type does not expose thatFuture. Before #2499, an async exception thrown before `next`,`resolve`, or `reject` could therefore leave the handler's completerpending forever.#2499 addressed that hang by invoking every callback inside a newlyforked `Zone` with a custom `handleUncaughtError`. If the handler wasincomplete, the zone converted the uncaught error into a handler error;if the handler was already complete, it forwarded the error to theparent zone. This preserved the public `void` API and did not awaitcallbacks.The new zone boundary changed Dart's Future error-delivery semantics.Dart Future errors do not cross between distinct error zones in the sameway as ordinary values. The deterministic #2565 sequence is:“`textRequest A: callback runs in error zone A creates the shared Completer calls handler.next() proceeds to the adapterRequest B: callback runs in error zone B finds A's Completer registers an onError listener on its FutureAdapter: A fails immediately A's onError completes the shared Completer with completeError()Result: the Future belongs to error zone A, but B's listener belongs to B B's listener is not delivered the shared error A's handler is already complete, so Dio forwards the error as uncaught B's handler never completes“`The regression is the per-callback error-zone isolation; the immediateadapter failure is the deterministic timing trigger that exposes it inthis reproduction. This fix removes the callback-specific zones createdby Dio; it does not make a shared Future safe when application codedeliberately creates and listens to it across unrelated external errorzones, which remain governed by Dart's normal error-zone rules. Beforethe implementation, a test-only probe reproduced two `onRequest`callbacks, one adapter fetch, zero joined-error deliveries, one uncaughterror, and a timed-out pending request on the base implementation. Thecommitted regression test asserts the repaired behavior after the fix.## Implementation### 1. Capture runtime callback Futures without changing the APIA private library typedef, `_InterceptorCallback<T, V>`, returns`Object?`. `Interceptor` now has private virtual `_invokeRequest`,`_invokeResponse`, and `_invokeError` entry points that dynamicallyinvoke the public `on*` method:“`dartfinal dynamic callback = onRequest;return callback(options, handler);“`This is deliberate:- A normal `Interceptor` subclass can override `Future<void>onRequest/onResponse/onError`; dynamic invocation retains the runtimeFuture even though the base API is `void`.- The public method signatures and public callback typedefs remainunchanged.- The private entry points are used only by the internal requestpipeline.The wrapper compatibility path is kept explicit. `InterceptorsWrapper`and `QueuedInterceptorsWrapper` still expose their existing public `voidon*` methods. The wrapper mixin dynamically invokes theconstructor-supplied callback and observes its runtime result there. Itno longer uses private mixin overrides that bypass a subclass's public`onRequest`, `onResponse`, or `onError` override. This preservesdownstream wrapper-subclass behavior while retaining support for asyncconstructor callbacks.### 2. Observe, do not await, the returned Future`_observeInterceptorCallback` is registered synchronously immediatelyafter callback invocation, in the callback's existing zone:“`textinvoke callback -> obtain runtime result -> if result is a Future, attach a success no-op and an error listener -> return handler.future to the interceptor pipeline“`The callback Future is never awaited and is never used as the pipelinecompletion signal. Handler completion remains the only normal signalthat advances the request, response, or error chain.When the observed Future fails:| Callback stage | Handler is incomplete | Handler is already complete || — | — | — || Request | `handler.reject(assureDioException(error, …, stackTrace),true)` | Report through the callback's existing zone || Response | `handler.reject(assureDioException(error, …, stackTrace),true)` | Report through the callback's existing zone || Error | `handler.next(assureDioException(error, …, stackTrace))` |Report through the callback's existing zone |The original `StackTrace` is preserved in all conversions. The errorlistener consumes the original Future error and handles it through theinterceptor handler, so the derived listener Future does not create asecond uncaught error.If the callback has already completed its handler and then its returnedFuture fails, the error is deliberately sent to the zone captured whenthe listener was registered. This preserves #2499's late-errorvisibility for fire-and-forget behavior without allowing Dio to completea handler a second time. A detached Future that the callback neitherreturns nor handles remains outside Dio's ownership and is notreclassified as a handler failure. If the callback also never completesits handler, Dio cannot use that detached Future to unblock the request,so the request can still remain pending. This is an explicit ownershipboundary rather than an attempt to catch every asynchronous task startedby user code.### 3. Preserve normal and queued pipeline timingFor normal interceptors, `DioMixin.fetch` invokes the private `_invoke*`method inside the existing pipeline Future, observes the runtime result,and returns the handler Future. It no longer forks a callback-specificerror zone.For queued interceptors, `QueuedInterceptor._handleQueue` receives thematching private `_invoke*` method. The callback is still called insidethe existing synchronous try block, its returned Future is observedimmediately, and queue advancement still occurs only through handlercompletion or cancellation. FIFO behavior and the separaterequest/response/error queues are unchanged.The effective timing is therefore:“`textBefore: pipeline -> fork a new error zone -> invoke callback -> wait for handler callback Future errors are routed through the new zoneAfter: pipeline -> invoke callback in the existing zone -> attach an error listener synchronously -> wait for handler callback Future is observed but never awaited“`This removes the cross-request error-zone boundary while preservinghandler-driven ordering. Awaiting the callback Future was intentionallyavoided because the await-based approach in #2139 changed microtaskordering and broke following interceptor behavior reported in #2167;#2169 reverted #2139.## API and Compatibility Boundaries- No public method return type changed.- `InterceptorSendCallback`, `InterceptorSuccessCallback`, and`InterceptorErrorCallback` remain public `void Function(…)` typedefs.- No public symbol was removed or renamed.- No Dart SDK lower-bound increase or Dart 3-only language feature wasintroduced.- Existing synchronous callbacks and handler methods retain theirbehavior.- Async callbacks remain unawaited; only their returned errors are nowobserved explicitly.- Subclasses of `Interceptor`, `InterceptorsWrapper`,`QueuedInterceptor`, and `QueuedInterceptorsWrapper` are all covered.- Wrapper subclasses continue to dispatch through their public `on*`methods instead of being bypassed by an internal closure path.The wrapper-subclass checks are compatibility guards, not a newuser-visible behavior. A temporary separate CHANGELOG bullet forpreserving those overrides was intentionally removed in `6b42fa2`; thefinal changelog contains only the #2565 user-facing fix.## TestsThe regression and compatibility coverage includes:- A deterministic #2565 test with an immediate failing adapter and ashared deduplication Future. It asserts both requests terminate, onlyone adapter fetch occurs, no error escapes the test's surrounding zonein the same error-zone setup, and no pending handler remains.- Direct `Interceptor` subclasses with async `onRequest`, `onResponse`,and `onError` overrides that throw after an await.- `InterceptorsWrapper` and `QueuedInterceptorsWrapper` subclassesoverriding all three public `on*` methods synchronously, with asyncwrapper-subclass coverage on the request path.- Async constructor callbacks covering request, response, and errorpaths.- Queued request, response, and error failures, including queue releasefor a following request.- Existing behavior for callbacks that call their handler and laterfail, callbacks that must not be awaited, duplicate handler calls, andfollowing error interceptors.The focused VM and Chrome suites each pass all 52 tests.## VerificationLocally, `melos run format`, `melos run analyze`, and `dart analyze–fatal-infos` passed. CI run 29642622254 passed on min, beta, andstable SDK matrices, including VM, Chrome, Firefox, Flutter, APK build,and coverage.The final coverage report is:| File | Base | New | Difference || — | —: | —: | —: || `dio/lib/src/dio_mixin.dart` | 94.25% | 94.49% | +0.24% || `dio/lib/src/interceptor.dart` | 99.34% | 99.46% | +0.12% || Overall | 85.73% | 85.95% | +0.22% |A full local `melos run test` was attempted, but network-dependent VMand browser tests encountered external HTTP 502, CORS, and timeoutfailures. The CI workflow starts local httpbun containers on each GitHubActions runner and completed successfully.## UnverifiedThe minimum Dart 2.18 SDK was not installed locally; the remote min SDKworkflow passed. Local Firefox and Flutter targets were unavailable orblocked by local configuration, but both passed in the remote CImatrices.## AI AttributionImplementation, tests, commit, and local review by Codex.———Co-authored-by: Codex <noreply@openai.com> , GitHub
Check out DIO Installing and Example
https://pub.dev/packages/dio
Provides the list of the opensource Flutter apps collection with GitHub repository.