28
28
import java .io .InputStream ;
29
29
import java .net .HttpURLConnection ;
30
30
import java .net .SocketTimeoutException ;
31
- import java .net .URL ;
32
- import java .net .URLConnection ;
33
31
import java .util .HashMap ;
34
32
import java .util .Map ;
35
33
import java .util .UUID ;
34
+ import java .util .List ;
35
+
36
+ import java .net .URL ;
37
+ import java .net .URLConnection ;
36
38
37
39
/**
38
40
* Helper class meant to be used with the android.webkit.WebView class to enable hosting assets,
@@ -53,6 +55,7 @@ public class WebViewLocalServer {
53
55
public final static String httpsScheme = "https" ;
54
56
public final static String fileStart = "/_app_file_" ;
55
57
public final static String contentStart = "/_app_content_" ;
58
+ public final static String proxyStart = "/_local_proxy_" ;
56
59
57
60
private final UriMatcher uriMatcher ;
58
61
private final AndroidProtocolHandler protocolHandler ;
@@ -219,18 +222,29 @@ public WebResourceResponse shouldInterceptRequest(Uri uri, WebResourceRequest re
219
222
synchronized (uriMatcher ) {
220
223
handler = (PathHandler ) uriMatcher .match (uri );
221
224
}
225
+
222
226
if (handler == null ) {
223
227
return null ;
224
228
}
225
229
226
230
if (isLocalFile (uri ) || uri .getAuthority ().equals (this .authority )) {
227
231
Log .d ("SERVER" , "Handling local request: " + uri .toString ());
228
- return handleLocalRequest (uri , handler , request );
232
+
233
+ if (isLocalProxySource (uri )) {
234
+ return handleLocalProxyRequest (uri , request );
235
+ } else {
236
+ return handleLocalRequest (uri , handler , request );
237
+ }
229
238
} else {
230
239
return handleProxyRequest (uri , handler );
231
240
}
232
241
}
233
242
243
+ private boolean isLocalProxySource (Uri uri ) {
244
+ String path = uri .getPath ();
245
+ return path .startsWith (proxyStart );
246
+ }
247
+
234
248
private boolean isLocalFile (Uri uri ) {
235
249
String path = uri .getPath ();
236
250
if (path .startsWith (contentStart ) || path .startsWith (fileStart )) {
@@ -239,6 +253,44 @@ private boolean isLocalFile(Uri uri) {
239
253
return false ;
240
254
}
241
255
256
+ private WebResourceResponse handleLocalProxyRequest (Uri uri , WebResourceRequest request ) {
257
+ String fixedUri = uri .toString ().replaceFirst ("http://localhost/_local_proxy_/" , "" ); // Fix the url by removing the proxy schema
258
+
259
+ try {
260
+ URL httpsUrl = new URL (fixedUri );
261
+ URLConnection connection = httpsUrl .openConnection ();
262
+ HttpURLConnection httpConnection = (HttpURLConnection )connection ;
263
+
264
+ Map <String , String > headers = new HashMap <String , String >();
265
+ if (request != null && request .getRequestHeaders ().get ("Range" ) != null ) {
266
+ String rangeString = request .getRequestHeaders ().get ("Range" );
267
+ httpConnection .addRequestProperty ("Range" , rangeString );
268
+
269
+ String contentHeader = connection .getHeaderFields ().get ("Content-Length" ).get (0 );
270
+
271
+ int contentLength = Integer .parseInt (contentHeader );
272
+ String [] parts = rangeString .split ("=" );
273
+ String [] streamParts = parts [1 ].split ("-" );
274
+ String fromRange = streamParts [0 ];
275
+ int range = contentLength - 1 ;
276
+
277
+ headers .put ("Accept-Ranges" , "bytes" );
278
+ headers .put ("Content-Length" , contentHeader );
279
+ headers .put ("Content-Range" , "bytes " + fromRange + "-" + range + "/" + contentLength );
280
+ }
281
+
282
+ // Bypass CORS
283
+ headers .put ("Access-Control-Allow-Origin" , "*" );
284
+ headers .put ("Access-Control-Allow-Methods" , "GET, POST, DELETE, PUT, OPTIONS" );
285
+ headers .put ("Access-Control-Allow-Headers" , "agent, user-data, Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers" );
286
+
287
+ return new WebResourceResponse (connection .getContentType (), connection .getContentEncoding (),
288
+ httpConnection .getResponseCode (), httpConnection .getResponseMessage (), headers , httpConnection .getInputStream ());
289
+
290
+ } catch (Exception e ) {
291
+ return null ;
292
+ }
293
+ }
242
294
243
295
private WebResourceResponse handleLocalRequest (Uri uri , PathHandler handler , WebResourceRequest request ) {
244
296
String path = uri .getPath ();
@@ -265,6 +317,7 @@ private WebResourceResponse handleLocalRequest(Uri uri, PathHandler handler, Web
265
317
return createWebResourceResponse (mimeType , handler .getEncoding (),
266
318
statusCode , handler .getReasonPhrase (), tempResponseHeaders , responseStream );
267
319
}
320
+
268
321
if (isLocalFile (uri )) {
269
322
InputStream responseStream = new LollipopLazyInputStream (handler , uri );
270
323
String mimeType = getMimeType (path , responseStream );
0 commit comments