Skip to content

Commit

Permalink
Merge branch 'main' into fix-clone-boundary-issue
Browse files Browse the repository at this point in the history
  • Loading branch information
helloliuyiming authored Nov 10, 2024
2 parents c4cd938 + 5c5a926 commit f56e067
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 81 deletions.
2 changes: 1 addition & 1 deletion CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @cfug/devs
* @cfug/dio-core
1 change: 1 addition & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ linter:
unnecessary_await_in_return: true
unnecessary_breaks: true
unnecessary_late: true
unnecessary_library_name: false
unnecessary_parenthesis: true
8 changes: 4 additions & 4 deletions dio/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ See the [Migration Guide][] for the complete breaking changes list.**

## Unreleased

*None.*
- Update comments and strings with `MultipartFile`.
- Removes redundant warnings when composing request options on Web.

## 5.7.0

- Graceful handling of responses with nonzero `Content-Length`, `Content-Type` json, but empty body
- Empty responses are now transformed to `null`

- Graceful handling of responses with nonzero `Content-Length`, `Content-Type` that is json, and empty payload.
- Empty responses are now transformed to `null`.

## 5.6.0

Expand Down
20 changes: 10 additions & 10 deletions dio/README-ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ void getHttp() async {

## 示例

发起一个 `GET` 请求 :
### 发起一个 `GET` 请求 :

```dart
import 'package:dio/dio.dart';
Expand All @@ -130,19 +130,19 @@ void request() async {
}
```

发起一个 `POST` 请求:
### 发起一个 `POST` 请求:

```dart
response = await dio.post('/test', data: {'id': 12, 'name': 'dio'});
```

发起多个并发请求:
### 发起多个并发请求:

```dart
response = await Future.wait([dio.post('/info'), dio.get('/token')]);
```

下载文件:
### 下载文件:

```dart
response = await dio.download(
Expand All @@ -151,7 +151,7 @@ response = await dio.download(
);
```

以流的方式接收响应数据:
### 以流的方式接收响应数据:

```dart
final rs = await dio.get(
Expand All @@ -161,7 +161,7 @@ final rs = await dio.get(
print(rs.data.stream); // 响应流
```

以二进制数组的方式接收响应数据:
### 以二进制数组的方式接收响应数据:

```dart
final rs = await dio.get(
Expand All @@ -171,7 +171,7 @@ final rs = await dio.get(
print(rs.data); // 类型: List<int>
```

发送 `FormData`:
### 发送 `FormData`:

```dart
final formData = FormData.fromMap({
Expand All @@ -181,7 +181,7 @@ final formData = FormData.fromMap({
final response = await dio.post('/info', data: formData);
```

通过 `FormData` 上传多个文件:
### 通过 `FormData` 上传多个文件:

```dart
final formData = FormData.fromMap({
Expand All @@ -196,7 +196,7 @@ final formData = FormData.fromMap({
final response = await dio.post('/info', data: formData);
```

监听发送(上传)数据进度:
### 监听发送(上传)数据进度:

```dart
final response = await dio.post(
Expand All @@ -208,7 +208,7 @@ final response = await dio.post(
);
```

以流的形式提交二进制数据:
### 以流的形式提交二进制数据:

```dart
// Binary data
Expand Down
22 changes: 11 additions & 11 deletions dio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ in [here](https://github.com/cfug/dio/issues/347).

## Examples

Performing a `GET` request:
### Performing a `GET` request:

```dart
import 'package:dio/dio.dart';
Expand All @@ -114,19 +114,19 @@ void request() async {
}
```

Performing a `POST` request:
### Performing a `POST` request:

```dart
response = await dio.post('/test', data: {'id': 12, 'name': 'dio'});
```

Performing multiple concurrent requests:
### Performing multiple concurrent requests:

```dart
response = await Future.wait([dio.post('/info'), dio.get('/token')]);
```

Downloading a file:
### Downloading a file:

```dart
response = await dio.download(
Expand All @@ -135,7 +135,7 @@ response = await dio.download(
);
```

Get response stream:
### Get response stream:

```dart
final rs = await dio.get(
Expand All @@ -145,7 +145,7 @@ final rs = await dio.get(
print(rs.data.stream); // Response stream.
```

Get response with bytes:
### Get response with bytes:

```dart
final rs = await Dio().get<List<int>>(
Expand All @@ -155,7 +155,7 @@ final rs = await Dio().get<List<int>>(
print(rs.data); // Type: List<int>.
```

Sending a `FormData`:
### Sending a `FormData`:

```dart
final formData = FormData.fromMap({
Expand All @@ -165,7 +165,7 @@ final formData = FormData.fromMap({
final response = await dio.post('/info', data: formData);
```

Uploading multiple files to server by FormData:
### Uploading multiple files to server by FormData:

```dart
final formData = FormData.fromMap({
Expand All @@ -180,7 +180,7 @@ final formData = FormData.fromMap({
final response = await dio.post('/info', data: formData);
```

Listening the uploading progress:
### Listening the uploading progress:

```dart
final response = await dio.post(
Expand All @@ -192,7 +192,7 @@ final response = await dio.post(
);
```

Post binary data with Stream:
### Post binary data with Stream:

```dart
// Binary data
Expand Down Expand Up @@ -737,7 +737,7 @@ and replace the `BackgroundTransformer` by setting the `dio.transformer`.
### Transformer example

There is an example for [customizing Transformer](../example/lib/transformer.dart).
There is an example for [customizing Transformer](../example_dart/lib/transformer.dart).

## HttpClientAdapter

Expand Down
74 changes: 39 additions & 35 deletions dio/lib/src/multipart_file.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,18 @@ import 'utils.dart';
/// The type (alias) for specifying the content-type of the `MultipartFile`.
typedef DioMediaType = MediaType;

/// A file to be uploaded as part of a [MultipartRequest]. This doesn't need to
/// correspond to a physical file.
///
/// MultipartFile is based on stream, and a stream can be read only once,
/// so the same MultipartFile can't be read multiple times.
/// An upload content that is a part of `MultipartRequest`.
/// This doesn't need to correspond to a physical file.
class MultipartFile {
/// Creates a new [MultipartFile] from a chunked [Stream] of bytes. The length
/// of the file in bytes must be known in advance. If it's not, read the data
/// from the stream and use [MultipartFile.fromBytes] instead.
///
/// [contentType] currently defaults to `application/octet-stream`, but in the
/// future may be inferred from [filename].
/// [contentType] currently defaults to `application/octet-stream`,
/// but it may be inferred from [filename] in the future.
@Deprecated(
'MultipartFile.clone() will not work when the stream is provided, use the MultipartFile.fromStream instead.'
'MultipartFile() is not cloneable when the stream is consumed, '
'use MultipartFile.fromStream() instead.'
'This will be removed in 6.0.0',
)
MultipartFile(
Expand All @@ -37,12 +35,13 @@ class MultipartFile {
headers = caseInsensitiveKeyMap(headers),
contentType = contentType ?? MediaType('application', 'octet-stream');

/// Creates a new [MultipartFile] from a chunked [Stream] of bytes. The length
/// of the file in bytes must be known in advance. If it's not, read the data
/// from the stream and use [MultipartFile.fromBytes] instead.
/// Creates a new [MultipartFile] from a creation method that creates
/// chunked [Stream] of bytes. The length of the file in bytes must be known
/// in advance. If it's not, read the data from the stream and use
/// [MultipartFile.fromBytes] instead.
///
/// [contentType] currently defaults to `application/octet-stream`, but in the
/// future may be inferred from [filename].
/// [contentType] currently defaults to `application/octet-stream`,
/// but it may be inferred from [filename] in the future.
MultipartFile.fromStream(
Stream<List<int>> Function() data,
this.length, {
Expand All @@ -55,8 +54,8 @@ class MultipartFile {

/// Creates a new [MultipartFile] from a byte array.
///
/// [contentType] currently defaults to `application/octet-stream`, but in the
/// future may be inferred from [filename].
/// [contentType] currently defaults to `application/octet-stream`,
/// but it may be inferred from [filename] in the future.
factory MultipartFile.fromBytes(
List<int> value, {
String? filename,
Expand All @@ -76,8 +75,9 @@ class MultipartFile {
///
/// The encoding to use when translating [value] into bytes is taken from
/// [contentType] if it has a charset set. Otherwise, it defaults to UTF-8.
/// [contentType] currently defaults to `text/plain; charset=utf-8`, but in
/// the future may be inferred from [filename].
///
/// [contentType] currently defaults to `text/plain; charset=utf-8`,
/// but it may be inferred from [filename] in the future.
factory MultipartFile.fromString(
String value, {
String? filename,
Expand All @@ -90,7 +90,6 @@ class MultipartFile {
utf8,
);
contentType = contentType.change(parameters: {'charset': encoding.name});

return MultipartFile.fromBytes(
encoding.encode(value),
filename: filename,
Expand Down Expand Up @@ -131,26 +130,28 @@ class MultipartFile {
String? filename,
DioMediaType? contentType,
final Map<String, List<String>>? headers,
}) =>
multipartFileFromPath(
filePath,
filename: filename,
contentType: contentType,
headers: headers,
);
}) {
return multipartFileFromPath(
filePath,
filename: filename,
contentType: contentType,
headers: headers,
);
}

static MultipartFile fromFileSync(
String filePath, {
String? filename,
DioMediaType? contentType,
final Map<String, List<String>>? headers,
}) =>
multipartFileFromPathSync(
filePath,
filename: filename,
contentType: contentType,
headers: headers,
);
}) {
return multipartFileFromPathSync(
filePath,
filename: filename,
contentType: contentType,
headers: headers,
);
}

bool _isFinalized = false;

Expand All @@ -159,12 +160,15 @@ class MultipartFile {
throw StateError(
'The MultipartFile has already been finalized. '
'This typically means you are using '
'the same MultipartFile in repeated requests.',
'the same MultipartFile in repeated requests.\n'
'Use MultipartFile.clone() or create a new MultipartFile '
'for further usages.',
);
}
_isFinalized = true;
return _dataBuilder()
.map((e) => e is Uint8List ? e : Uint8List.fromList(e));
return _dataBuilder().map(
(e) => e is Uint8List ? e : Uint8List.fromList(e),
);
}

/// Clone MultipartFile, returning a new instance of the same object.
Expand Down
14 changes: 0 additions & 14 deletions dio/lib/src/options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -309,20 +309,6 @@ class Options {
ProgressCallback? onReceiveProgress,
StackTrace? sourceStackTrace,
}) {
if (data != null && kIsWeb) {
if (sendTimeout != null && sendTimeout! > Duration.zero) {
warningLog(
'sendTimeout cannot be used without a request body to send on Web',
StackTrace.current,
);
}
if (onSendProgress != null) {
warningLog(
'onSendProgress cannot be used without a request body to send on Web',
StackTrace.current,
);
}
}
final query = <String, dynamic>{};
query.addAll(baseOpt.queryParameters);
if (queryParameters != null) {
Expand Down
7 changes: 5 additions & 2 deletions dio/test/multipart_file_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,11 @@ void main() async {
expect(e, isA<StateError>());
expect(
(e as StateError).message,
'The MultipartFile has already been finalized. This typically '
'means you are using the same MultipartFile in repeated requests.',
'The MultipartFile has already been finalized. '
'This typically means you are using the same MultipartFile '
'in repeated requests.\n'
'Use MultipartFile.clone() or create a new MultipartFile '
'for further usages.',
);
}

Expand Down
Loading

0 comments on commit f56e067

Please sign in to comment.