@@ -239,7 +239,7 @@ impl<'a> PathSegmentsMut<'a> {
239
239
I :: Item : AsRef < str > ,
240
240
{
241
241
let scheme_type = SchemeType :: from ( self . url . scheme ( ) ) ;
242
- let path_start = self . url . path_start as usize ;
242
+ let mut path_start = self . url . path_start as usize ;
243
243
self . url . mutate ( |parser| {
244
244
parser. context = parser:: Context :: PathSegmentSetter ;
245
245
for segment in segments {
@@ -253,7 +253,44 @@ impl<'a> PathSegmentsMut<'a> {
253
253
{
254
254
parser. serialization . push ( '/' ) ;
255
255
}
256
- let mut has_host = true ; // FIXME account for this?
256
+
257
+ let mut path_empty = false ;
258
+
259
+ // Check ':' and then see if the next character is '/'
260
+ let mut has_host = if let Some ( index) = parser. serialization . find ( ":" ) {
261
+ if parser. serialization . len ( ) > index + 1
262
+ && parser. serialization . as_bytes ( ) . get ( index + 1 ) == Some ( & b'/' )
263
+ {
264
+ let rest = & parser. serialization [ ( index + ":/" . len ( ) ) ..] ;
265
+ let host_part = rest. split ( '/' ) . next ( ) . unwrap_or ( "" ) ;
266
+ path_empty = rest. is_empty ( ) ;
267
+ !host_part. is_empty ( ) && !host_part. contains ( '@' )
268
+ } else {
269
+ false
270
+ }
271
+ } else {
272
+ false
273
+ } ;
274
+
275
+ // For cases where normalization is applied across both the serialization and the path.
276
+ // Append "/." immediately after the scheme (up to ":")
277
+ // This is done if three conditions are met.
278
+ // https://url.spec.whatwg.org/#url-serializing
279
+ // 1. The host is null
280
+ // 2. The url's path length is greater than 1
281
+ // 3. the first segment of the URL's path is an empty string
282
+ if !has_host && segment. len ( ) > 1 && path_empty {
283
+ if let Some ( index) = parser. serialization . find ( ":" ) {
284
+ if parser. serialization . len ( ) == index + 2
285
+ && parser. serialization . as_bytes ( ) . get ( index + 1 ) == Some ( & b'/' )
286
+ {
287
+ // Append an extra '/' to ensure that "/./path" becomes "/.//path"
288
+ parser. serialization . insert_str ( index + ":" . len ( ) , "/./" ) ;
289
+ path_start += "/." . len ( ) ;
290
+ }
291
+ }
292
+ }
293
+
257
294
parser. parse_path (
258
295
scheme_type,
259
296
& mut has_host,
@@ -262,6 +299,7 @@ impl<'a> PathSegmentsMut<'a> {
262
299
) ;
263
300
}
264
301
} ) ;
302
+ self . url . path_start = path_start as u32 ;
265
303
self
266
304
}
267
305
}
0 commit comments