2
2
// SPDX-License-Identifier: Apache-2.0
3
3
// SPDX-License-Identifier: MIT
4
4
5
- use std:: { collections :: HashMap , future:: Future , pin:: Pin , sync:: Arc , time:: Duration } ;
5
+ use std:: { future:: Future , pin:: Pin , str :: FromStr , sync:: Arc , time:: Duration } ;
6
6
7
- use http:: { header, HeaderName , Method , StatusCode } ;
7
+ use http:: { header, HeaderMap , HeaderName , HeaderValue , Method , StatusCode } ;
8
8
use reqwest:: { redirect:: Policy , NoProxy } ;
9
9
use serde:: { Deserialize , Serialize } ;
10
10
use tauri:: {
@@ -176,7 +176,7 @@ pub async fn fetch<R: Runtime>(
176
176
let ClientConfig {
177
177
method,
178
178
url,
179
- headers,
179
+ headers : headers_raw ,
180
180
data,
181
181
connect_timeout,
182
182
max_redirections,
@@ -185,7 +185,17 @@ pub async fn fetch<R: Runtime>(
185
185
186
186
let scheme = url. scheme ( ) ;
187
187
let method = Method :: from_bytes ( method. as_bytes ( ) ) ?;
188
- let headers: HashMap < String , String > = HashMap :: from_iter ( headers) ;
188
+
189
+ let mut headers = HeaderMap :: new ( ) ;
190
+ for ( h, v) in headers_raw {
191
+ let name = HeaderName :: from_str ( & h) ?;
192
+ #[ cfg( not( feature = "unsafe-headers" ) ) ]
193
+ if is_unsafe_header ( & name) {
194
+ continue ;
195
+ }
196
+
197
+ headers. append ( name, HeaderValue :: from_str ( & v) ?) ;
198
+ }
189
199
190
200
match scheme {
191
201
"http" | "https" => {
@@ -228,45 +238,38 @@ pub async fn fetch<R: Runtime>(
228
238
229
239
let mut request = builder. build ( ) ?. request ( method. clone ( ) , url) ;
230
240
231
- for ( name, value) in & headers {
232
- let name = HeaderName :: from_bytes ( name. as_bytes ( ) ) ?;
233
- #[ cfg( not( feature = "unsafe-headers" ) ) ]
234
- if is_unsafe_header ( & name) {
235
- continue ;
236
- }
237
-
238
- request = request. header ( name, value) ;
239
- }
240
-
241
241
// POST and PUT requests should always have a 0 length content-length,
242
242
// if there is no body. https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
243
243
if data. is_none ( ) && matches ! ( method, Method :: POST | Method :: PUT ) {
244
- request = request . header ( header:: CONTENT_LENGTH , 0 ) ;
244
+ headers . append ( header:: CONTENT_LENGTH , HeaderValue :: from_str ( "0" ) ? ) ;
245
245
}
246
246
247
- if headers. contains_key ( header:: RANGE . as_str ( ) ) {
247
+ if headers. contains_key ( header:: RANGE ) {
248
248
// https://fetch.spec.whatwg.org/#http-network-or-cache-fetch step 18
249
249
// If httpRequest’s header list contains `Range`, then append (`Accept-Encoding`, `identity`)
250
- request = request . header ( header:: ACCEPT_ENCODING , "identity" ) ;
250
+ headers . append ( header:: ACCEPT_ENCODING , HeaderValue :: from_str ( "identity" ) ? ) ;
251
251
}
252
252
253
- if !headers. contains_key ( header:: USER_AGENT . as_str ( ) ) {
254
- request = request . header ( header:: USER_AGENT , HTTP_USER_AGENT ) ;
253
+ if !headers. contains_key ( header:: USER_AGENT ) {
254
+ headers . append ( header:: USER_AGENT , HeaderValue :: from_str ( HTTP_USER_AGENT ) ? ) ;
255
255
}
256
256
257
- if cfg ! ( feature = "unsafe-headers" )
258
- && !headers. contains_key ( header:: ORIGIN . as_str ( ) )
259
- {
257
+ // ensure we have an Origin header set
258
+ if cfg ! ( not( feature = "unsafe-headers" ) ) || !headers. contains_key ( header:: ORIGIN ) {
260
259
if let Ok ( url) = webview. url ( ) {
261
- request =
262
- request. header ( header:: ORIGIN , url. origin ( ) . ascii_serialization ( ) ) ;
260
+ headers. append (
261
+ header:: ORIGIN ,
262
+ HeaderValue :: from_str ( & url. origin ( ) . ascii_serialization ( ) ) ?,
263
+ ) ;
263
264
}
264
265
}
265
266
266
267
if let Some ( data) = data {
267
268
request = request. body ( data) ;
268
269
}
269
270
271
+ request = request. headers ( headers) ;
272
+
270
273
let fut = async move { request. send ( ) . await . map_err ( Into :: into) } ;
271
274
let mut resources_table = webview. resources_table ( ) ;
272
275
let rid = resources_table. add_request ( Box :: pin ( fut) ) ;
0 commit comments