@@ -239,7 +239,7 @@ impl<'a> PathSegmentsMut<'a> {
239239 I :: Item : AsRef < str > ,
240240 {
241241 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 ;
243243 self . url . mutate ( |parser| {
244244 parser. context = parser:: Context :: PathSegmentSetter ;
245245 for segment in segments {
@@ -253,7 +253,44 @@ impl<'a> PathSegmentsMut<'a> {
253253 {
254254 parser. serialization . push ( '/' ) ;
255255 }
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+
257294 parser. parse_path (
258295 scheme_type,
259296 & mut has_host,
@@ -262,6 +299,7 @@ impl<'a> PathSegmentsMut<'a> {
262299 ) ;
263300 }
264301 } ) ;
302+ self . url . path_start = path_start as u32 ;
265303 self
266304 }
267305}
0 commit comments