2023-02-27 07:12:45 +00:00
|
|
|
import 'dart:async';
|
|
|
|
|
|
|
|
|
|
import 'package:dio/dio.dart';
|
|
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
|
|
|
|
|
|
import '../../app.dart';
|
|
|
|
|
|
|
|
|
|
class HttpUtil {
|
|
|
|
|
static HttpUtil _instance = HttpUtil._internal();
|
|
|
|
|
|
|
|
|
|
factory HttpUtil() => _instance;
|
|
|
|
|
|
|
|
|
|
late Dio dio;
|
|
|
|
|
CancelToken cancelToken = new CancelToken();
|
|
|
|
|
|
|
|
|
|
HttpUtil._internal() {
|
|
|
|
|
BaseOptions options = new BaseOptions(
|
|
|
|
|
baseUrl: Constants.BASE_URL,
|
2023-10-25 10:19:17 +00:00
|
|
|
connectTimeout: Duration(seconds: 4),
|
|
|
|
|
receiveTimeout: Duration(seconds: 5),
|
2023-02-27 07:12:45 +00:00
|
|
|
headers: {},
|
|
|
|
|
contentType: 'application/json; charset=utf-8',
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
dio = new Dio(options);
|
|
|
|
|
|
|
|
|
|
// CookieJar cookieJar = CookieJar();
|
|
|
|
|
// dio.interceptors.add(CookieManager(cookieJar));
|
|
|
|
|
|
|
|
|
|
dio.interceptors.add(InterceptorsWrapper(
|
|
|
|
|
onRequest: (options, handler) {
|
|
|
|
|
return handler.next(options);
|
|
|
|
|
},
|
|
|
|
|
onResponse: (response, handler) {
|
|
|
|
|
return handler.next(response);
|
|
|
|
|
},
|
|
|
|
|
onError: (DioError e, handler) {
|
2023-10-25 10:19:17 +00:00
|
|
|
// ErrorEntity eInfo = createErrorEntity(e);
|
2023-02-27 07:12:45 +00:00
|
|
|
|
2023-10-25 10:19:17 +00:00
|
|
|
switch (e.response!.statusCode) {
|
2023-02-27 07:12:45 +00:00
|
|
|
case 401: // No permission to log in again
|
|
|
|
|
setLoginStatus(false);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
}
|
|
|
|
|
return handler.next(e);
|
|
|
|
|
},
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-25 10:19:17 +00:00
|
|
|
// ErrorEntity createErrorEntity(DioError error) {
|
|
|
|
|
// switch (error.type) {
|
|
|
|
|
// case DioErrorType.cancel:
|
|
|
|
|
// return ErrorEntity(code: -1, message: 'Request cancellation');
|
|
|
|
|
// case DioErrorType.connectTimeout:
|
|
|
|
|
// return ErrorEntity(code: -1, message: 'Connection timed out');
|
|
|
|
|
// case DioErrorType.sendTimeout:
|
|
|
|
|
// return ErrorEntity(code: -1, message: 'Request timed out');
|
|
|
|
|
// case DioErrorType.receiveTimeout:
|
|
|
|
|
// return ErrorEntity(code: -1, message: 'Response timeout');
|
|
|
|
|
// case DioErrorType.response:
|
|
|
|
|
// {
|
|
|
|
|
// try {
|
|
|
|
|
// int? errCode = error.response?.statusCode;
|
|
|
|
|
// switch (errCode) {
|
|
|
|
|
// case 400:
|
|
|
|
|
// return ErrorEntity(code: errCode, message: 'Request syntax error');
|
|
|
|
|
// case 401:
|
|
|
|
|
// return ErrorEntity(code: errCode, message: 'Username or password incorrect');
|
|
|
|
|
// case 403:
|
|
|
|
|
// return ErrorEntity(code: errCode, message: 'Server refused to execute');
|
|
|
|
|
// case 404:
|
|
|
|
|
// return ErrorEntity(code: errCode, message: 'Can not reach server');
|
|
|
|
|
// case 405:
|
|
|
|
|
// return ErrorEntity(code: errCode, message: 'Request method is forbidden');
|
|
|
|
|
// case 405:
|
|
|
|
|
// return ErrorEntity(code: errCode, message: 'User already registered');
|
|
|
|
|
// case 500:
|
|
|
|
|
// return ErrorEntity(code: errCode, message: 'Server internal error');
|
|
|
|
|
// case 502:
|
|
|
|
|
// return ErrorEntity(code: errCode, message: 'Invalid request');
|
|
|
|
|
// case 503:
|
|
|
|
|
// return ErrorEntity(code: errCode, message: 'Server hung up');
|
|
|
|
|
// case 505:
|
|
|
|
|
// return ErrorEntity(code: errCode, message: 'Does not support HTTP protocol request');
|
|
|
|
|
// default:
|
|
|
|
|
// {
|
|
|
|
|
// // return ErrorEntity(code: errCode, message: 'Unknown error');
|
|
|
|
|
// return ErrorEntity(
|
|
|
|
|
// code: errCode,
|
|
|
|
|
// message: error.response?.statusMessage,
|
|
|
|
|
// );
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// } on Exception catch (_) {
|
|
|
|
|
// return ErrorEntity(code: -1, message: 'Unknown error');
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// default:
|
|
|
|
|
// {
|
|
|
|
|
// return ErrorEntity(code: -1, message: error.message);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
2023-02-27 07:12:45 +00:00
|
|
|
|
|
|
|
|
void cancelRequests(CancelToken token) {
|
|
|
|
|
token.cancel('cancelled');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<Map<String, dynamic>> getAuthorizationHeader() async {
|
|
|
|
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
|
|
|
Map<String, dynamic> headers;
|
|
|
|
|
String? accessToken = prefs.getString(Constants.TOKEN);
|
|
|
|
|
headers = {
|
|
|
|
|
'Authorization': 'Bearer $accessToken',
|
|
|
|
|
'Accept': 'application/json',
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
};
|
|
|
|
|
return headers;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// restful get
|
|
|
|
|
/// refresh false
|
|
|
|
|
/// noCache true
|
|
|
|
|
/// list false
|
|
|
|
|
/// cacheKey
|
|
|
|
|
/// cacheDisk
|
|
|
|
|
Future get({
|
|
|
|
|
required String path,
|
|
|
|
|
Map<String, dynamic>? queryParameters,
|
|
|
|
|
Options? options,
|
|
|
|
|
bool refresh = false,
|
|
|
|
|
bool noCache = false,
|
|
|
|
|
bool list = false,
|
|
|
|
|
String cacheKey = '',
|
|
|
|
|
bool cacheDisk = false,
|
|
|
|
|
}) async {
|
|
|
|
|
Options requestOptions = options ?? Options();
|
|
|
|
|
if (requestOptions.extra == null) {
|
|
|
|
|
requestOptions.extra = Map();
|
|
|
|
|
}
|
|
|
|
|
requestOptions.extra!.addAll({
|
|
|
|
|
'refresh': refresh,
|
|
|
|
|
'noCache': noCache,
|
|
|
|
|
'list': list,
|
|
|
|
|
'cacheKey': cacheKey,
|
|
|
|
|
'cacheDisk': cacheDisk,
|
|
|
|
|
});
|
|
|
|
|
requestOptions.headers = requestOptions.headers ?? {};
|
|
|
|
|
Map<String, dynamic>? authorization = await getAuthorizationHeader();
|
|
|
|
|
requestOptions.headers!.addAll(authorization);
|
|
|
|
|
|
2023-10-25 10:19:17 +00:00
|
|
|
var response =
|
|
|
|
|
await dio.get(path, queryParameters: queryParameters, options: requestOptions, cancelToken: cancelToken);
|
2023-02-27 07:12:45 +00:00
|
|
|
|
|
|
|
|
return response.data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// restful post
|
|
|
|
|
Future post(
|
|
|
|
|
String path, {
|
|
|
|
|
dynamic data,
|
|
|
|
|
Map<String, dynamic>? queryParameters,
|
|
|
|
|
Options? options,
|
|
|
|
|
}) async {
|
|
|
|
|
Options requestOptions = options ?? Options();
|
|
|
|
|
requestOptions.headers = requestOptions.headers ?? {};
|
|
|
|
|
requestOptions.headers?.addAll({'Accept': 'application/json'});
|
|
|
|
|
Map<String, dynamic>? authorization = await getAuthorizationHeader();
|
|
|
|
|
requestOptions.headers!.addAll(authorization);
|
|
|
|
|
|
|
|
|
|
var response = await dio.post(
|
|
|
|
|
path,
|
|
|
|
|
data: data,
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
options: requestOptions,
|
|
|
|
|
cancelToken: cancelToken,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return response.data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// restful put
|
|
|
|
|
Future put(
|
|
|
|
|
String path, {
|
|
|
|
|
dynamic data,
|
|
|
|
|
Map<String, dynamic>? queryParameters,
|
|
|
|
|
Options? options,
|
|
|
|
|
}) async {
|
|
|
|
|
Options requestOptions = options ?? Options();
|
|
|
|
|
requestOptions.headers = requestOptions.headers ?? {};
|
|
|
|
|
Map<String, dynamic>? authorization = await getAuthorizationHeader();
|
|
|
|
|
requestOptions.headers!.addAll(authorization);
|
|
|
|
|
var response = await dio.put(
|
|
|
|
|
path,
|
|
|
|
|
data: data,
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
options: requestOptions,
|
|
|
|
|
cancelToken: cancelToken,
|
|
|
|
|
);
|
|
|
|
|
return response.data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// restful patch
|
|
|
|
|
Future patch(
|
|
|
|
|
String path, {
|
|
|
|
|
dynamic data,
|
|
|
|
|
Map<String, dynamic>? queryParameters,
|
|
|
|
|
Options? options,
|
|
|
|
|
}) async {
|
|
|
|
|
Options requestOptions = options ?? Options();
|
|
|
|
|
requestOptions.headers = requestOptions.headers ?? {};
|
|
|
|
|
Map<String, dynamic>? authorization = await getAuthorizationHeader();
|
|
|
|
|
requestOptions.headers!.addAll(authorization);
|
|
|
|
|
var response = await dio.patch(
|
|
|
|
|
path,
|
|
|
|
|
data: data,
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
options: requestOptions,
|
|
|
|
|
cancelToken: cancelToken,
|
|
|
|
|
);
|
|
|
|
|
return response.data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// restful delete
|
|
|
|
|
Future delete(
|
|
|
|
|
String path, {
|
|
|
|
|
dynamic data,
|
|
|
|
|
Map<String, dynamic>? queryParameters,
|
|
|
|
|
Options? options,
|
|
|
|
|
}) async {
|
|
|
|
|
Options requestOptions = options ?? Options();
|
|
|
|
|
requestOptions.headers = requestOptions.headers ?? {};
|
|
|
|
|
Map<String, dynamic>? authorization = await getAuthorizationHeader();
|
|
|
|
|
requestOptions.headers!.addAll(authorization);
|
|
|
|
|
var response = await dio.delete(
|
|
|
|
|
path,
|
|
|
|
|
data: data,
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
options: requestOptions,
|
|
|
|
|
cancelToken: cancelToken,
|
|
|
|
|
);
|
|
|
|
|
return response.data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// restful post form
|
2023-10-25 10:19:17 +00:00
|
|
|
Future postForm(
|
2023-02-27 07:12:45 +00:00
|
|
|
String path, {
|
|
|
|
|
required Map<String, dynamic> data,
|
|
|
|
|
Map<String, dynamic>? queryParameters,
|
|
|
|
|
Options? options,
|
|
|
|
|
}) async {
|
|
|
|
|
Options requestOptions = options ?? Options();
|
|
|
|
|
requestOptions.headers = requestOptions.headers ?? {};
|
|
|
|
|
Map<String, dynamic>? authorization = await getAuthorizationHeader();
|
|
|
|
|
requestOptions.headers!.addAll(authorization);
|
|
|
|
|
var response = await dio.post(
|
|
|
|
|
path,
|
|
|
|
|
data: FormData.fromMap(data),
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
options: requestOptions,
|
|
|
|
|
cancelToken: cancelToken,
|
|
|
|
|
);
|
|
|
|
|
return response.data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// restful post Stream
|
|
|
|
|
/*Future postStream(
|
|
|
|
|
String path, {
|
|
|
|
|
dynamic data,
|
|
|
|
|
int dataLength = 0,
|
|
|
|
|
Map<String, dynamic>? queryParameters,
|
|
|
|
|
Options? options,
|
|
|
|
|
}) async {
|
|
|
|
|
Options requestOptions = options ?? Options();
|
|
|
|
|
requestOptions.headers = requestOptions.headers ?? {};
|
|
|
|
|
Map<String, dynamic>? authorization = getAuthorizationHeader();
|
|
|
|
|
if (authorization != null) {
|
|
|
|
|
requestOptions.headers!.addAll(authorization);
|
|
|
|
|
}
|
|
|
|
|
requestOptions.headers!.addAll({
|
|
|
|
|
Headers.contentLengthHeader: dataLength.toString(),
|
|
|
|
|
});
|
|
|
|
|
var response = await dio.post(
|
|
|
|
|
path,
|
|
|
|
|
data: Stream.fromIterable(data.map((e) => [e])),
|
|
|
|
|
queryParameters: queryParameters,
|
|
|
|
|
options: requestOptions,
|
|
|
|
|
cancelToken: cancelToken,
|
|
|
|
|
);
|
|
|
|
|
return response.data;
|
|
|
|
|
} */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Exception handling
|
|
|
|
|
class ErrorEntity implements Exception {
|
|
|
|
|
int? code;
|
|
|
|
|
String? message;
|
|
|
|
|
|
|
|
|
|
ErrorEntity({this.code, this.message});
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
String toString() {
|
|
|
|
|
if (message == null) return 'Exception';
|
|
|
|
|
return 'Exception: code $code, $message';
|
|
|
|
|
}
|
|
|
|
|
}
|