Optimize HTTP calls

This commit is contained in:
yuluo
2024-04-19 16:57:44 +08:00
parent bf57a504b7
commit c1def9e738
10 changed files with 48 additions and 35 deletions

15
Cargo.lock generated
View File

@@ -3019,7 +3019,7 @@ dependencies = [
"tokio", "tokio",
"tokio-native-tls", "tokio-native-tls",
"tokio-rustls 0.26.0", "tokio-rustls 0.26.0",
"tokio-socks", "tokio-socks 0.5.1-2",
"tokio-util", "tokio-util",
"toml 0.7.8", "toml 0.7.8",
"url", "url",
@@ -5347,6 +5347,7 @@ dependencies = [
"tokio", "tokio",
"tokio-native-tls", "tokio-native-tls",
"tokio-rustls 0.24.1", "tokio-rustls 0.24.1",
"tokio-socks 0.5.1",
"tokio-util", "tokio-util",
"tower-service", "tower-service",
"url", "url",
@@ -6606,6 +6607,18 @@ dependencies = [
"tokio-util", "tokio-util",
] ]
[[package]]
name = "tokio-socks"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0"
dependencies = [
"either",
"futures-util",
"thiserror",
"tokio",
]
[[package]] [[package]]
name = "tokio-util" name = "tokio-util"
version = "0.7.10" version = "0.7.10"

View File

@@ -10,8 +10,8 @@ import 'package:flutter_hbb/models/peer_model.dart';
import 'package:flutter_hbb/models/platform_model.dart'; import 'package:flutter_hbb/models/platform_model.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:bot_toast/bot_toast.dart'; import 'package:bot_toast/bot_toast.dart';
import 'package:http/http.dart' as http;
import '../utils/http_service.dart' as http;
import '../common.dart'; import '../common.dart';
final syncAbOption = 'sync-ab-with-recent-sessions'; final syncAbOption = 'sync-ab-with-recent-sessions';

View File

@@ -7,7 +7,7 @@ import 'package:flutter_hbb/models/peer_model.dart';
import 'package:flutter_hbb/models/platform_model.dart'; import 'package:flutter_hbb/models/platform_model.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'dart:convert'; import 'dart:convert';
import 'package:http/http.dart' as http; import '../utils/http_service.dart' as http;
class GroupModel { class GroupModel {
final RxBool groupLoading = false.obs; final RxBool groupLoading = false.obs;

View File

@@ -6,10 +6,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_hbb/common/hbbs/hbbs.dart'; import 'package:flutter_hbb/common/hbbs/hbbs.dart';
import 'package:flutter_hbb/models/ab_model.dart'; import 'package:flutter_hbb/models/ab_model.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import '../common.dart'; import '../common.dart';
import '../utils/http_service.dart' as httpR; import '../utils/http_service.dart' as http;
import 'model.dart'; import 'model.dart';
import 'platform_model.dart'; import 'platform_model.dart';
@@ -18,6 +17,7 @@ bool refreshingUser = false;
class UserModel { class UserModel {
final RxString userName = ''.obs; final RxString userName = ''.obs;
final RxBool isAdmin = false.obs; final RxBool isAdmin = false.obs;
bool get isLogin => userName.isNotEmpty; bool get isLogin => userName.isNotEmpty;
WeakReference<FFI> parent; WeakReference<FFI> parent;
@@ -136,7 +136,8 @@ class UserModel {
/// throw [RequestException] /// throw [RequestException]
Future<LoginResponse> login(LoginRequest loginRequest) async { Future<LoginResponse> login(LoginRequest loginRequest) async {
final url = await bind.mainGetApiServer(); final url = await bind.mainGetApiServer();
final resp = await httpR.post('$url/api/login', body: jsonEncode(loginRequest.toJson())); final resp = await http.post(Uri.parse('$url/api/login'),
body: jsonEncode(loginRequest.toJson()));
final Map<String, dynamic> body; final Map<String, dynamic> body;
try { try {

View File

@@ -1,13 +1,13 @@
import 'dart:convert'; import 'dart:convert';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import '../models/platform_model.dart'; import '../models/platform_model.dart';
export 'package:http/http.dart' show Response;
enum HttpMethod { get, post, put, delete } enum HttpMethod { get, post, put, delete }
class HttpService { class HttpService {
Future<http.Response> sendRequest( Future<http.Response> sendRequest(
String url, Uri url,
HttpMethod method, { HttpMethod method, {
Map<String, String>? headers, Map<String, String>? headers,
dynamic body, dynamic body,
@@ -23,12 +23,8 @@ class HttpService {
return await _pollFultterHttp(url, method, headers: headers, body: body); return await _pollFultterHttp(url, method, headers: headers, body: body);
} }
if (body is! String) {
throw Exception('Unsupported HTTP body type');
}
await bind.mainHttpRequest( await bind.mainHttpRequest(
url: url, url: url.toString(),
method: methodName.toLowerCase(), method: methodName.toLowerCase(),
body: body, body: body,
header: headersJson); header: headersJson);
@@ -38,26 +34,25 @@ class HttpService {
} }
Future<http.Response> _pollFultterHttp( Future<http.Response> _pollFultterHttp(
String url, Uri url,
HttpMethod method, { HttpMethod method, {
Map<String, String>? headers, Map<String, String>? headers,
dynamic body, dynamic body,
}) async { }) async {
var response = http.Response('', 400); // 默认响应 var response = http.Response('', 400); // 默认响应
Uri uri = Uri.parse(url);
switch (method) { switch (method) {
case HttpMethod.get: case HttpMethod.get:
response = await http.get(uri, headers: headers); response = await http.get(url, headers: headers);
break; break;
case HttpMethod.post: case HttpMethod.post:
response = await http.post(uri, headers: headers, body: body); response = await http.post(url, headers: headers, body: body);
break; break;
case HttpMethod.put: case HttpMethod.put:
response = await http.put(uri, headers: headers, body: body); response = await http.put(url, headers: headers, body: body);
break; break;
case HttpMethod.delete: case HttpMethod.delete:
response = await http.delete(uri, headers: headers, body: body); response = await http.delete(url, headers: headers, body: body);
break; break;
default: default:
throw Exception('Unsupported HTTP method'); throw Exception('Unsupported HTTP method');
@@ -91,23 +86,23 @@ class HttpService {
} }
} }
Future<http.Response> get(String url, {Map<String, String>? headers}) async { Future<http.Response> get(Uri url, {Map<String, String>? headers}) async {
return await HttpService().sendRequest(url, HttpMethod.get, headers: headers); return await HttpService().sendRequest(url, HttpMethod.get, headers: headers);
} }
Future<http.Response> post(String url, Future<http.Response> post(Uri url,
{Map<String, String>? headers, Object? body, Encoding? encoding}) async { {Map<String, String>? headers, Object? body, Encoding? encoding}) async {
return await HttpService() return await HttpService()
.sendRequest(url, HttpMethod.post, body: body, headers: headers); .sendRequest(url, HttpMethod.post, body: body, headers: headers);
} }
Future<http.Response> put(String url, Future<http.Response> put(Uri url,
{Map<String, String>? headers, Object? body, Encoding? encoding}) async { {Map<String, String>? headers, Object? body, Encoding? encoding}) async {
return await HttpService() return await HttpService()
.sendRequest(url, HttpMethod.put, body: body, headers: headers); .sendRequest(url, HttpMethod.put, body: body, headers: headers);
} }
Future<http.Response> delete(String url, Future<http.Response> delete(Uri url,
{Map<String, String>? headers, Object? body, Encoding? encoding}) async { {Map<String, String>? headers, Object? body, Encoding? encoding}) async {
return await HttpService() return await HttpService()
.sendRequest(url, HttpMethod.delete, body: body, headers: headers); .sendRequest(url, HttpMethod.delete, body: body, headers: headers);

View File

@@ -145,6 +145,7 @@ use hbb_common::{
}; };
// #[cfg(any(target_os = "android", target_os = "ios", feature = "cli"))] // #[cfg(any(target_os = "android", target_os = "ios", feature = "cli"))]
use hbb_common::{config::RENDEZVOUS_PORT, futures::future::join_all}; use hbb_common::{config::RENDEZVOUS_PORT, futures::future::join_all};
use hbb_common::log::debug;
use crate::hbbs_http::create_http_client_async; use crate::hbbs_http::create_http_client_async;
use crate::ui_interface::{get_option, set_option}; use crate::ui_interface::{get_option, set_option};
@@ -1090,10 +1091,11 @@ pub async fn post_request_sync(url: String, body: String, header: &str) -> Resul
pub async fn http_request_sync( pub async fn http_request_sync(
url: String, url: String,
method: String, method: String,
body: String, body: Option<String>,
header: String, header: String,
) -> ResultType<String> { ) -> ResultType<String> {
let http_client = create_http_client_async(); let http_client = create_http_client_async();
debug!("url: {}, method: {}, body: {:?}, header: {}", url, method, body,header);
let mut http_client = match method.as_str() { let mut http_client = match method.as_str() {
"get" => http_client.get(url), "get" => http_client.get(url),
"post" => http_client.post(url), "post" => http_client.post(url),
@@ -1106,14 +1108,16 @@ pub async fn http_request_sync(
if let Value::Object(obj) = v { if let Value::Object(obj) = v {
for (key, value) in obj.iter() { for (key, value) in obj.iter() {
http_client = http_client.header(key, value.as_str().unwrap_or_default()); http_client = http_client.header(key, value.as_str().unwrap_or_default());
println!("Key: {}, Value: {}", key, value);
} }
} else { } else {
return Err(anyhow!("HTTP header information parsing failed!")); return Err(anyhow!("HTTP header information parsing failed!"));
} }
if let Some(b) = body {
http_client = http_client.body(b);
}
let response = http_client let response = http_client
.body(body)
.timeout(std::time::Duration::from_secs(12)) .timeout(std::time::Duration::from_secs(12))
.send() .send()
.await?; .await?;
@@ -1142,6 +1146,7 @@ pub async fn http_request_sync(
// Convert map to JSON string // Convert map to JSON string
serde_json::to_string(&result).map_err(|e| anyhow!("Failed to serialize response: {}", e)) serde_json::to_string(&result).map_err(|e| anyhow!("Failed to serialize response: {}", e))
} }
#[inline] #[inline]
pub fn make_privacy_mode_msg_with_details( pub fn make_privacy_mode_msg_with_details(
state: back_notification::PrivacyModeState, state: back_notification::PrivacyModeState,

View File

@@ -878,7 +878,7 @@ pub fn main_get_api_server() -> String {
get_api_server() get_api_server()
} }
pub fn main_http_request(url: String, method: String, body: String, header: String) { pub fn main_http_request(url: String, method: String, body: Option<String>, header: String) {
http_request(url,method, body, header) http_request(url,method, body, header)
} }

View File

@@ -14,11 +14,9 @@ macro_rules! configure_http_client {
match proxy_result { match proxy_result {
Ok(proxy) => { Ok(proxy) => {
let proxy_setup = match &proxy.intercept { let proxy_setup = match &proxy.intercept {
ProxyScheme::Http { host, .. } => reqwest::Proxy::http(host), ProxyScheme::Http { host, .. } =>{ reqwest::Proxy::http(format!("http://{}", host))},
ProxyScheme::Https { host, .. } => reqwest::Proxy::https(host), ProxyScheme::Https { host, .. } => {reqwest::Proxy::https(format!("https://{}", host))},
ProxyScheme::Socks5 { addr, .. } => { ProxyScheme::Socks5 { addr, .. } => { reqwest::Proxy::all(&format!("socks5://{}", addr)) }
reqwest::Proxy::all(&format!("socks5://{}", addr))
}
}; };
match proxy_setup { match proxy_setup {

View File

@@ -548,7 +548,7 @@ impl UI {
change_id_shared(id, old_id); change_id_shared(id, old_id);
} }
fn http_request(&self, url: String, method: String, body: String, header: String) { fn http_request(&self, url: String, method: String, body: Option<String>, header: String) {
http_request(url, method, body, header) http_request(url, method, body, header)
} }

View File

@@ -24,6 +24,7 @@ use std::{
collections::HashMap, collections::HashMap,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use hbb_common::log::error;
use crate::common::SOFTWARE_UPDATE_URL; use crate::common::SOFTWARE_UPDATE_URL;
#[cfg(feature = "flutter")] #[cfg(feature = "flutter")]
@@ -717,12 +718,12 @@ pub fn change_id(id: String) {
} }
#[inline] #[inline]
pub fn http_request(url: String, method: String, body: String, header: String) { pub fn http_request(url: String, method: String, body: Option<String>, header: String) {
*ASYNC_JOB_STATUS.lock().unwrap() = " ".to_owned(); *ASYNC_JOB_STATUS.lock().unwrap() = " ".to_owned();
std::thread::spawn(move || { std::thread::spawn(move || {
*ASYNC_JOB_STATUS.lock().unwrap() = *ASYNC_JOB_STATUS.lock().unwrap() =
match crate::http_request_sync(url, method, body, header) { match crate::http_request_sync(url, method, body, header) {
Err(err) => err.to_string(), Err(err) => { error!("{}", err); err.to_string() },
Ok(text) => text, Ok(text) => text,
}; };
}); });