@@ -496,27 +496,21 @@ internal static string RedirectTo(string baseUri, string redirectUri)
496496
497497 internal static string MakeInitialUrl ( string targetUrl , string localUrl )
498498 {
499- // Uri class leaves only one slash for protocol for this case, prevent that
500- // i.e. we report streaming assets folder on Android as jar:file:///blabla, keep it that way
501- if ( targetUrl . StartsWith ( "jar:file://" ) )
502- return targetUrl ;
503-
504- // Prevent blob url slashes from being stripped (to blob:http:/... or blob:https:/...)
505- if ( targetUrl . StartsWith ( "blob:http" ) )
506- return targetUrl ;
507-
499+ bool prependingProtocol = false ;
508500 var localUri = new System . Uri ( localUrl ) ;
509501 Uri targetUri = null ;
510502
511503 if ( targetUrl [ 0 ] == '/' )
512504 {
513505 // Prepend scheme and (if needed) host
514506 targetUri = new Uri ( localUri , targetUrl ) ;
507+ prependingProtocol = true ;
515508 }
516509
517510 if ( targetUri == null && domainRegex . IsMatch ( targetUrl ) )
518511 {
519512 targetUrl = localUri . Scheme + "://" + targetUrl ;
513+ prependingProtocol = true ;
520514 }
521515
522516 FormatException ex = null ;
@@ -538,12 +532,18 @@ internal static string MakeInitialUrl(string targetUrl, string localUrl)
538532 try
539533 {
540534 targetUri = new System . Uri ( localUri , targetUrl ) ;
535+ prependingProtocol = true ;
541536 }
542537 catch ( FormatException )
543538 {
544539 throw ex ;
545540 }
546541
542+ return MakeUriString ( targetUri , targetUrl , prependingProtocol ) ;
543+ }
544+
545+ internal static string MakeUriString ( Uri targetUri , string targetUrl , bool prependingProtocol )
546+ {
547547 // for file://protocol pass in unescaped string so we can pass it to VFS
548548 if ( targetUrl . StartsWith ( "file://" , StringComparison . OrdinalIgnoreCase ) )
549549 {
@@ -559,7 +559,24 @@ internal static string MakeInitialUrl(string targetUrl, string localUrl)
559559
560560 // if URL contains '%', assume it is properly escaped, otherwise '%2f' gets unescaped as '/' (which may not be correct)
561561 // otherwise escape it, i.e. replaces spaces by '%20'
562- return targetUrl . Contains ( "%" ) ? targetUri . OriginalString : targetUri . AbsoluteUri ;
562+ if ( targetUrl . Contains ( "%" ) )
563+ return targetUri . OriginalString ;
564+
565+ // Special handling for URIs like jar:file (Android), blob:http (WebGL and similar
566+ // Uri.AbsoluteUri class in those cases results in jar:file/path, which is incorrect because of only one slash
567+ // Uri.Scheme also returns scheme part before the colon (jar, blob)
568+ // so if we didn't prepend the scheme and scheme has colon it it, construct the URI from it's parts
569+ var scheme = targetUri . Scheme ;
570+ if ( ! prependingProtocol && ( targetUrl . Length >= scheme . Length + 2 ) && targetUrl [ scheme . Length + 1 ] != '/' )
571+ {
572+ StringBuilder sb = new StringBuilder ( scheme , targetUrl . Length ) ;
573+ sb . Append ( ':' ) ;
574+ sb . Append ( targetUri . PathAndQuery ) ; // for these spec URIs path also has the part of URI to right of colon
575+ sb . Append ( targetUri . Fragment ) ;
576+ return sb . ToString ( ) ;
577+ }
578+
579+ return targetUri . AbsoluteUri ;
563580 }
564581 }
565582}
0 commit comments