Skip to content

Commit

Permalink
Merge pull request #5 from thongdn-it/isolate_http
Browse files Browse the repository at this point in the history
[isolate_http] Publish v2.2.0
  • Loading branch information
thongdn-it authored Jun 13, 2022
2 parents 1a65ae7 + 250424b commit b76a401
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 36 deletions.
12 changes: 8 additions & 4 deletions isolate_http/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
# [2.2.0] - 13/06/2022

- Add log CURL.
- Add `contentLength` for IsolateHttpRequest, IsolateHttpResponse.

# [2.1.1] - 23/09/2021

* [Fix] missing `content-type` header in post method.
- [Fix] missing `content-type` header in post method.

# [2.1.0] - 12/09/2021

* Support timeout, debug label.
- Support timeout, debug label.

# [2.0.0] - 03/09/2021

* Support null-safety.
- Support null-safety.

# [1.0.0] - 01/09/2021

* Initial package.
- Initial package.
27 changes: 20 additions & 7 deletions isolate_http/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@ IsolateHttp provides a way to launch [http package][http_pub_url] with [IsolateF
Performing a `GET` request:

```dart
final _response = await IsolateHttp().get('https://example.com/product',
final _isolateHttp = IsolateHttp();
```

```dart
final _response = await _isolateHttp.get('https://example.com/product',
headers: {'Authorization': 'abc='});
print(_response);
```

Performing a `POST` request:

```dart
final _response = await IsolateHttp().post('https://example.com/product',
final _response = await _isolateHttp.post('https://example.com/product',
headers: {'Authorization': 'abc='},
body: {'size': 'XL', 'price': 236},
files: [
Expand All @@ -29,19 +33,29 @@ print(_response);
Performing a `DELETE` request:

```dart
final _response = await IsolateHttp().delete('https://example.com/product/1',
final _response = await _isolateHttp.delete('https://example.com/product/1',
headers: {'Authorization': 'abc='});
print(_response);
```

*** You can set a timeout and debug label for your request when creating an IsolateHttp like:
\*\*\* You can set a timeout and debug label for your request when creating an IsolateHttp like:

```dart
IsolateHttp(timeout: Duration(seconds: 30), debugLabel: 'get_products')
final _isolateHttp = IsolateHttp(timeout: Duration(seconds: 30), debugLabel: 'get_products')
```

If timeout, its returns you an IsolateHttpResponse with status code 408 (Request Timeout).

### Log Curl

```dart
_isolateHttp.listener = (curl) {
if (kDebugMode) {
log('Isolate Http -> Curl: ----------------\n$curl\n----------------');
}
};
```

## Author

IsolateHttp is developed by Thong Dang. You can contact me at [email protected]
Expand All @@ -50,8 +64,7 @@ If you like my project, you can support me [![Buy Me A Coffee][buy_me_a_coffee_i

Thank you! ❤️

[//]: # (reference links)

[//]: # 'reference links'
[http_pub_url]: https://pub.dev/packages/http
[isolate_flutter_pub_url]: https://pub.dev/packages/isolate_flutter
[pub_url]: https://pub.dev/packages/isolate_http
Expand Down
19 changes: 15 additions & 4 deletions isolate_http/example/main.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import 'dart:developer';
import 'package:flutter/foundation.dart';

import 'package:isolate_http/isolate_http.dart';

void main(List<String> args) async {
// https://developers.google.com/books
final _response = await IsolateHttp(
timeout: Duration(seconds: 60), debugLabel: 'search_book')
.get('https://www.googleapis.com/auth/books/v1/volumes',
query: {'q': 'flutter'});
final _isolateHttp =
IsolateHttp(timeout: Duration(seconds: 60), debugLabel: 'search_book');
final _response = await _isolateHttp.get(
'https://www.googleapis.com/auth/books/v1/volumes',
query: {'q': 'flutter'});
if (_response?.statusCode == 200) {
final _bodyJson = _response?.bodyJson;
print(_bodyJson);
} else {
print('Request failed with status: ${_response?.statusCode}.');
}

// Log Curl
_isolateHttp.listener = (curl) {
if (kDebugMode) {
log('Isolate Http -> Curl: ----------------\n$curl\n----------------');
}
};
}
34 changes: 29 additions & 5 deletions isolate_http/lib/src/isolate_http.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import 'package:http/http.dart';

import 'package:isolate_flutter/isolate_flutter.dart';

import 'package:isolate_http/src/http_file.dart';
import 'package:isolate_http/src/http_method.dart';
import 'package:isolate_http/src/isolate_http_request.dart';
import 'package:isolate_http/src/isolate_http_response.dart';
import 'log_utils.dart';
import 'http_file.dart';
import 'http_method.dart';
import 'isolate_http_request.dart';
import 'isolate_http_response.dart';

/// Isolate Http
///
Expand All @@ -16,6 +17,23 @@ class IsolateHttp {
final Duration? _timeout;
final String? _debugLabel;

Function(String)? _logCurlListener;
set listener(Function(String)? listener) {
_logCurlListener = listener;
}

void _logCurl(IsolateHttpRequest isolateRequest) async {
if (_logCurlListener != null) {
final _request = await isolateRequest.toRequest();
if (_request != null) {
final _curl = LogUtils.getCurl(_request);
_logCurlListener!(_curl);
} else {
throw ArgumentError('request is null.');
}
}
}

/// Create an IsolateHttp
///
/// [timeout] time limit for an request.
Expand All @@ -32,6 +50,7 @@ class IsolateHttp {
{Map<String, String>? query, Map<String, String>? headers}) async {
final _isolateHttpRequest = IsolateHttpRequest(url,
method: HttpMethod.head, query: query, headers: headers);
_logCurl(_isolateHttpRequest);
return send(_isolateHttpRequest);
}

Expand All @@ -40,6 +59,7 @@ class IsolateHttp {
{Map<String, String>? query, Map<String, String>? headers}) async {
final _isolateHttpRequest = IsolateHttpRequest(url,
method: HttpMethod.get, query: query, headers: headers);
_logCurl(_isolateHttpRequest);
return send(_isolateHttpRequest);
}

Expand All @@ -55,6 +75,7 @@ class IsolateHttp {
headers: headers,
body: body,
files: files);
_logCurl(_isolateHttpRequest);
return send(_isolateHttpRequest);
}

Expand All @@ -70,6 +91,7 @@ class IsolateHttp {
headers: headers,
body: body,
files: files);
_logCurl(_isolateHttpRequest);
return send(_isolateHttpRequest);
}

Expand All @@ -80,6 +102,7 @@ class IsolateHttp {
Map<String, dynamic>? body}) async {
final _isolateHttpRequest = IsolateHttpRequest(url,
method: HttpMethod.delete, query: query, headers: headers, body: body);
_logCurl(_isolateHttpRequest);
return send(_isolateHttpRequest);
}

Expand Down Expand Up @@ -109,7 +132,8 @@ Future<IsolateHttpResponse?> _call(
final streamedResponse = await _request.send();
final httpResponse = await Response.fromStream(streamedResponse);
final _isolateHttpResponse = IsolateHttpResponse(
httpResponse.body, httpResponse.statusCode, httpResponse.headers);
httpResponse.body, httpResponse.statusCode, httpResponse.headers,
request: isolateHttpRequest, contentLength: httpResponse.contentLength);
return _isolateHttpResponse;
}
return null;
Expand Down
32 changes: 22 additions & 10 deletions isolate_http/lib/src/isolate_http_request.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import 'dart:convert';

import 'package:http/http.dart';

import 'package:isolate_http/src/http_file.dart';
import 'package:isolate_http/src/http_method.dart';
import 'http_file.dart';
import 'http_method.dart';

/// The request using for Isolate Http.
class IsolateHttpRequest {
Expand All @@ -28,6 +28,20 @@ class IsolateHttpRequest {
/// List of files to be uploaded of the request.
final List<HttpFile>? files;

/// The size of the request body, in bytes.
///
/// This defaults to `null`, which indicates that the size of the request is
/// not known in advance. May not be assigned a negative value.
int? get contentLength => _contentLength;
int? _contentLength;

set contentLength(int? value) {
if (value != null && value < 0) {
throw ArgumentError('Invalid content length $value.');
}
_contentLength = value;
}

/// The request using for Isolate Http.
///
/// [url] The url to which the request will be sent.
Expand All @@ -41,14 +55,12 @@ class IsolateHttpRequest {
/// [body] The body of the request.
///
/// [files] List of files (HttpFile) to be uploaded of the request.
IsolateHttpRequest(
this.url, {
this.method = HttpMethod.get,
this.query,
this.headers,
this.body,
this.files,
});
IsolateHttpRequest(this.url,
{this.method = HttpMethod.get,
this.query,
this.headers,
this.body,
this.files});

/// Convert [url] and [query] to full link request (Uri)
Uri? get uri {
Expand Down
13 changes: 12 additions & 1 deletion isolate_http/lib/src/isolate_http_response.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'dart:convert';

import 'isolate_http_request.dart';

/// The response using for Isolate Http.
class IsolateHttpResponse {
/// The body of the response as a String.
Expand All @@ -11,14 +13,23 @@ class IsolateHttpResponse {
/// The status code of the response as int.
final int statusCode;

/// The (frozen) request that triggered this response.
final IsolateHttpRequest? request;

/// The size of the response body, in bytes.
///
/// If the size of the request is not known in advance, this is `null`.
final int? contentLength;

/// The response using for Isolate Http.
///
/// [body] The body of the response as a String.
///
/// [statusCode] The status code of the response as int.
///
/// [headers] The headers of the response as a Map<String, String>.
IsolateHttpResponse(this.body, this.statusCode, this.headers);
IsolateHttpResponse(this.body, this.statusCode, this.headers,
{this.contentLength, this.request});

/// Return the body as as Json (dynamic).
dynamic get bodyJson => jsonDecode(body);
Expand Down
39 changes: 39 additions & 0 deletions isolate_http/lib/src/log_utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import 'dart:convert';

import 'package:http/http.dart';

abstract class LogUtils {
static String getCurl(BaseRequest request) {
List<String> components = ['curl -i'];
if (request.method.toUpperCase() != 'GET') {
components.add('-X ${request.method.toUpperCase()}');
}

for (var _key in request.headers.keys) {
if (_key != 'Cookie') {
components.add('-H "$_key: ${request.headers[_key]}"');
}
}

if (request is Request) {
if (request.body.isNotEmpty == true) {
final data = request.body.replaceAll('"', '\\"');
components.add('-d "$data"');
}
} else if (request is MultipartRequest) {
if (request.fields.isNotEmpty == true) {
final data = jsonEncode(request.fields).replaceAll('"', '\\"');
components.add('-d "$data"');
}
if (request.files.isNotEmpty == true) {
for (var _file in request.files) {
components.add('-F ${_file.field}=@/path/to/${_file.filename}');
}
}
}

components.add('"${request.url.toString()}"');

return components.join(' \\\n\t');
}
}
10 changes: 5 additions & 5 deletions isolate_http/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
name: isolate_http
description: IsolateHttp provides a way to launch 'http' library in Isolate with IsolatesFlutter.
version: 2.1.1
description: IsolateHttp provides a way to launch 'http' library in Isolate with IsolatesFlutter.
version: 2.2.0
homepage: https://github.com/thongdn-it/isolate_flutter/tree/master/isolate_http
repository: https://github.com/thongdn-it/isolate_flutter/tree/master/isolate_http

environment:
sdk: ">=2.12.0 <3.0.0"
sdk: '>=2.12.0 <3.0.0'

dependencies:
flutter:
sdk: flutter

isolate_flutter: ^2.0.0
http: ^0.13.0
http_parser: ^4.0.0

dev_dependencies:
lints: ^1.0.1
lints: ^1.0.1

0 comments on commit b76a401

Please sign in to comment.