4848public class WebViewLocalServer {
4949 private static String TAG = "WebViewAssetServer" ;
5050 private String basePath ;
51- /**
52- * capacitorapp.net is reserved by the Ionic team for use in local capacitor apps.
53- */
54- public final static String knownUnusedAuthority = "capacitorapp.net" ;
5551 private final static String httpScheme = "http" ;
5652 private final static String httpsScheme = "https" ;
53+ public final static String fileStart = "/_app_file_" ;
54+ public final static String contentStart = "/_app_content_" ;
5755
5856 private final UriMatcher uriMatcher ;
5957 private final AndroidProtocolHandler protocolHandler ;
6058 private final String authority ;
6159 // Whether we're serving local files or proxying (for example, when doing livereload on a
6260 // non-local endpoint (will be false in that case)
63- private final boolean isLocal ;
6461 private boolean isAsset ;
6562 // Whether to route all requests to paths without extensions back to `index.html`
6663 private final boolean html5mode ;
6764 private ConfigXmlParser parser ;
6865
69- public String getAuthority () { return authority ; }
70-
7166 /**
7267 * A handler that produces responses for paths on the virtual asset server.
7368 * <p>
@@ -169,18 +164,7 @@ public Uri getHttpsPrefix() {
169164 this .html5mode = html5mode ;
170165 this .parser = parser ;
171166 this .protocolHandler = new AndroidProtocolHandler (context .getApplicationContext ());
172- if (authority != null ) {
173- this .authority = authority ;
174- if (authority .startsWith ("localhost" )) {
175- this .isLocal = true ;
176- } else {
177- this .isLocal = false ;
178- }
179-
180- } else {
181- this .isLocal = true ;
182- this .authority = UUID .randomUUID ().toString () + "" + knownUnusedAuthority ;
183- }
167+ this .authority = authority ;
184168 }
185169
186170 private static Uri parseAndVerifyUrl (String url ) {
@@ -226,24 +210,40 @@ public WebResourceResponse shouldInterceptRequest(Uri uri) {
226210 return null ;
227211 }
228212
229- if (this .isLocal ) {
213+ if (isLocalFile ( uri ) || uri . getAuthority (). equals ( this .authority ) ) {
230214 Log .d ("SERVER" , "Handling local request: " + uri .toString ());
231215 return handleLocalRequest (uri , handler );
232216 } else {
233217 return handleProxyRequest (uri , handler );
234218 }
235219 }
236220
221+ private boolean isLocalFile (Uri uri ) {
222+ String path = uri .getPath ();
223+ if (path .startsWith (contentStart ) || path .startsWith (fileStart )) {
224+ return true ;
225+ }
226+ return false ;
227+ }
228+
237229 private WebResourceResponse handleLocalRequest (Uri uri , PathHandler handler ) {
238230 String path = uri .getPath ();
231+
232+ if (isLocalFile (uri )) {
233+ InputStream responseStream = new LollipopLazyInputStream (handler , uri );
234+ String mimeType = getMimeType (path , responseStream );
235+ return createWebResourceResponse (mimeType , handler .getEncoding (),
236+ handler .getStatusCode (), handler .getReasonPhrase (), handler .getResponseHeaders (), responseStream );
237+ }
238+
239239 if (path .equals ("/" ) || (!uri .getLastPathSegment ().contains ("." ) && html5mode )) {
240240 InputStream stream ;
241241 String launchURL = parser .getLaunchUrl ();
242242 String launchFile = launchURL .substring (launchURL .lastIndexOf ("/" ) + 1 , launchURL .length ());
243243 try {
244244 String startPath = this .basePath + "/" + launchFile ;
245245 if (isAsset ) {
246- stream = protocolHandler .openAsset (startPath , "" );
246+ stream = protocolHandler .openAsset (startPath );
247247 } else {
248248 stream = protocolHandler .openFile (startPath );
249249 }
@@ -367,10 +367,9 @@ void register(Uri uri, PathHandler handler) {
367367 *
368368 * @param assetPath the local path in the application's asset folder which will be made
369369 * available by the server (for example "/www").
370- * @return prefixes under which the assets are hosted.
371370 */
372- public AssetHostingDetails hostAssets (String assetPath ) {
373- return hostAssets (authority , assetPath , "" , true , true );
371+ public void hostAssets (String assetPath ) {
372+ hostAssets (authority , assetPath , "" , true , true );
374373 }
375374
376375
@@ -384,11 +383,10 @@ public AssetHostingDetails hostAssets(String assetPath) {
384383 * @param virtualAssetPath the path on the local server under which the assets should be hosted.
385384 * @param enableHttp whether to enable hosting using the http scheme.
386385 * @param enableHttps whether to enable hosting using the https scheme.
387- * @return prefixes under which the assets are hosted.
388386 */
389- public AssetHostingDetails hostAssets (final String assetPath , final String virtualAssetPath ,
387+ public void hostAssets (final String assetPath , final String virtualAssetPath ,
390388 boolean enableHttp , boolean enableHttps ) {
391- return hostAssets (authority , assetPath , virtualAssetPath , enableHttp ,
389+ hostAssets (authority , assetPath , virtualAssetPath , enableHttp ,
392390 enableHttps );
393391 }
394392
@@ -403,36 +401,39 @@ public AssetHostingDetails hostAssets(final String assetPath, final String virtu
403401 * @param virtualAssetPath the path on the local server under which the assets should be hosted.
404402 * @param enableHttp whether to enable hosting using the http scheme.
405403 * @param enableHttps whether to enable hosting using the https scheme.
406- * @return prefixes under which the assets are hosted.
407404 */
408- public AssetHostingDetails hostAssets (final String domain ,
405+ public void hostAssets (final String domain ,
409406 final String assetPath , final String virtualAssetPath ,
410407 boolean enableHttp , boolean enableHttps ) {
411408 this .isAsset = true ;
412409 this .basePath = assetPath ;
413- Uri .Builder uriBuilder = new Uri .Builder ();
414- uriBuilder .scheme (httpScheme );
415- uriBuilder .authority (domain );
416- uriBuilder .path (virtualAssetPath );
410+
411+ createHostingDetails ();
412+ }
413+
414+ private void createHostingDetails () {
415+ final String assetPath = this .basePath ;
417416
418417 if (assetPath .indexOf ('*' ) != -1 ) {
419418 throw new IllegalArgumentException ("assetPath cannot contain the '*' character." );
420419 }
421- if (virtualAssetPath .indexOf ('*' ) != -1 ) {
422- throw new IllegalArgumentException (
423- "virtualAssetPath cannot contain the '*' character." );
424- }
425-
426- Uri httpPrefix = null ;
427- Uri httpsPrefix = null ;
428420
429421 PathHandler handler = new PathHandler () {
430422 @ Override
431423 public InputStream handle (Uri url ) {
432- InputStream stream ;
433- String path = url .getPath (). replaceFirst ( virtualAssetPath , assetPath ) ;
424+ InputStream stream = null ;
425+ String path = url .getPath ();
434426 try {
435- stream = protocolHandler .openAsset (path , assetPath );
427+ if (path .startsWith (contentStart )) {
428+ stream = protocolHandler .openContentUrl (url );
429+ } else if (path .startsWith (fileStart ) || !isAsset ) {
430+ if (!path .startsWith (fileStart )) {
431+ path = basePath + url .getPath ();
432+ }
433+ stream = protocolHandler .openFile (path );
434+ } else {
435+ stream = protocolHandler .openAsset (assetPath + path );
436+ }
436437 } catch (IOException e ) {
437438 Log .e (TAG , "Unable to open asset URL: " + url );
438439 return null ;
@@ -442,18 +443,20 @@ public InputStream handle(Uri url) {
442443 }
443444 };
444445
445- if (enableHttp ) {
446- httpPrefix = uriBuilder .build ();
447- register (Uri .withAppendedPath (httpPrefix , "/" ), handler );
448- register (Uri .withAppendedPath (httpPrefix , "**" ), handler );
449- }
450- if (enableHttps ) {
451- uriBuilder .scheme (httpsScheme );
452- httpsPrefix = uriBuilder .build ();
453- register (Uri .withAppendedPath (httpsPrefix , "/" ), handler );
454- register (Uri .withAppendedPath (httpsPrefix , "**" ), handler );
455- }
456- return new AssetHostingDetails (httpPrefix , httpsPrefix );
446+ registerUriForScheme (httpScheme , handler , authority );
447+ registerUriForScheme (httpsScheme , handler , authority );
448+
449+ }
450+
451+ private void registerUriForScheme (String scheme , PathHandler handler , String authority ) {
452+ Uri .Builder uriBuilder = new Uri .Builder ();
453+ uriBuilder .scheme (scheme );
454+ uriBuilder .authority (authority );
455+ uriBuilder .path ("" );
456+ Uri uriPrefix = uriBuilder .build ();
457+
458+ register (Uri .withAppendedPath (uriPrefix , "/" ), handler );
459+ register (Uri .withAppendedPath (uriPrefix , "**" ), handler );
457460 }
458461
459462 /**
@@ -545,62 +548,16 @@ public InputStream handle(Uri url) {
545548 *
546549 * @param basePath the local path in the application's data folder which will be made
547550 * available by the server (for example "/www").
548- * @return prefixes under which the assets are hosted.
549551 */
550- public AssetHostingDetails hostFiles (String basePath ) {
551- return hostFiles (basePath , true , true );
552+ public void hostFiles (String basePath ) {
553+ hostFiles (basePath , true , true );
552554 }
553555
554- public AssetHostingDetails hostFiles (final String basePath , boolean enableHttp ,
556+ public void hostFiles (final String basePath , boolean enableHttp ,
555557 boolean enableHttps ) {
556558 this .isAsset = false ;
557559 this .basePath = basePath ;
558- Uri .Builder uriBuilder = new Uri .Builder ();
559- uriBuilder .scheme (httpScheme );
560- uriBuilder .authority (authority );
561- uriBuilder .path ("" );
562-
563- Uri httpPrefix = null ;
564- Uri httpsPrefix = null ;
565-
566- PathHandler handler = new PathHandler () {
567- @ Override
568- public InputStream handle (Uri url ) {
569- InputStream stream ;
570- try {
571- if (url .getPath ().startsWith ("/_file_/" )) {
572- stream = protocolHandler .openFile ( url .getPath ().replace ("/_file_/" , "" ));
573- } else {
574- stream = protocolHandler .openFile (basePath + url .getPath ());
575- }
576- } catch (IOException e ) {
577- Log .e (TAG , "Unable to open asset URL: " + url );
578- return null ;
579- }
580-
581- String mimeType = null ;
582- try {
583- mimeType = URLConnection .guessContentTypeFromStream (stream );
584- } catch (Exception ex ) {
585- Log .e (TAG , "Unable to get mime type" + url );
586- }
587-
588- return stream ;
589- }
590- };
591-
592- if (enableHttp ) {
593- httpPrefix = uriBuilder .build ();
594- register (Uri .withAppendedPath (httpPrefix , "/" ), handler );
595- register (Uri .withAppendedPath (httpPrefix , "**" ), handler );
596- }
597- if (enableHttps ) {
598- uriBuilder .scheme (httpsScheme );
599- httpsPrefix = uriBuilder .build ();
600- register (Uri .withAppendedPath (httpsPrefix , "/" ), handler );
601- register (Uri .withAppendedPath (httpsPrefix , "**" ), handler );
602- }
603- return new AssetHostingDetails (httpPrefix , httpsPrefix );
560+ createHostingDetails ();
604561 }
605562
606563 /**
0 commit comments