diff --git a/OsmAnd/src/net/osmand/plus/server/ApiRouter.java b/OsmAnd/src/net/osmand/plus/server/ApiRouter.java deleted file mode 100644 index 53f5febcd5..0000000000 --- a/OsmAnd/src/net/osmand/plus/server/ApiRouter.java +++ /dev/null @@ -1,115 +0,0 @@ -package net.osmand.plus.server; - -import android.util.Log; -import android.webkit.MimeTypeMap; -import fi.iki.elonen.NanoHTTPD; -import net.osmand.PlatformUtil; -import net.osmand.plus.OsmandApplication; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; - -import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse; - -public class ApiRouter { - private static final String FOLDER_NAME = "server"; - private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(ApiRouter.class); - private final Map endpoints = new HashMap<>(); - private OsmandApplication application; - - public OsmandApplication getApplication() { - return application; - } - - public void setApplication(OsmandApplication application) { - this.application = application; - for (String s : endpoints.keySet()) { - endpoints.get(s).setApplication(application); - } - } - - public NanoHTTPD.Response getStatic(String uri) { - InputStream is; - String mimeType = parseMimeType(uri); - if (application != null) { - try { - is = application.getAssets().open(FOLDER_NAME + uri); - if (is.available() == 0) { - return ErrorResponses.response404; - } - return newFixedLengthResponse( - NanoHTTPD.Response.Status.OK, - mimeType, - is, - is.available()); - } catch (IOException e) { - return ErrorResponses.response404; - } - } - return ErrorResponses.response500; - } - - public NanoHTTPD.Response route(NanoHTTPD.IHTTPSession session) { - Log.d("SERVER", "URI: " + session.getUri()); - String uri = session.getUri(); - if (uri.equals("/")) { - return getStatic("/go.html"); - } - if (isApiUrl(uri)) { - return routeApi(session); - } - return getStatic(uri); - } - - public void register(String path, ApiEndpoint endpoint) { - endpoint.setApplication(application); - endpoints.put(path, endpoint); - } - - private NanoHTTPD.Response routeApi(NanoHTTPD.IHTTPSession session) { - String uri = session.getUri(); - int pathEnd = uri.indexOf("/", 1); - if (pathEnd != -1) { - uri = uri.substring(0, pathEnd); - } - ApiEndpoint endpoint = endpoints.get(uri); - if (endpoint != null) { - return endpoint.process(session); - } - return ErrorResponses.response404; - } - - private boolean isApiUrl(String uri) { - for (String endpoint : endpoints.keySet()) { - int stringLength = endpoint.length(); - if (uri.startsWith(endpoint) && - (uri.length() == endpoint.length() || uri.charAt(stringLength) == '/')) { - return true; - } - } - return false; - } - - - private String parseMimeType(String url) { - String type = "text/plain"; - if (url.endsWith(".js")) return "text/javascript"; - String extension = MimeTypeMap.getFileExtensionFromUrl(url); - if (extension != null) { - type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); - } - return type; - } - - public static class ErrorResponses { - public static NanoHTTPD.Response response404 = - newFixedLengthResponse(NanoHTTPD.Response.Status.NOT_FOUND, - NanoHTTPD.MIME_PLAINTEXT, "404 Not Found"); - - public static NanoHTTPD.Response response500 = - newFixedLengthResponse(NanoHTTPD.Response.Status.INTERNAL_ERROR, - NanoHTTPD.MIME_PLAINTEXT, "500 Internal Server Error"); - } -} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java b/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java index a7eec56277..36685218e4 100644 --- a/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java +++ b/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java @@ -1,15 +1,23 @@ package net.osmand.plus.server; +import android.util.Log; +import android.webkit.MimeTypeMap; import fi.iki.elonen.NanoHTTPD; +import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.server.endpoints.TileEndpoint; import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; public class OsmAndHttpServer extends NanoHTTPD { - public static int PORT = 24990; + private static final String FOLDER_NAME = "server"; + private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(OsmAndHttpServer.class); + public static final int PORT = 24990; public static String HOSTNAME = "0.0.0.0"; - private final ApiRouter router = new ApiRouter(); + private final Map endpoints = new HashMap<>(); private OsmandApplication application; public OsmAndHttpServer() throws IOException { @@ -24,15 +32,95 @@ public class OsmAndHttpServer extends NanoHTTPD { public void setApplication(OsmandApplication application) { this.application = application; - router.setApplication(application); - } - - private void registerEndpoints() { - router.register("/tile", new TileEndpoint(application)); + for (String s : endpoints.keySet()) { + endpoints.get(s).setApplication(application); + } } @Override public Response serve(IHTTPSession session) { - return router.route(session); + Log.d("SERVER", "URI: " + session.getUri()); + String uri = session.getUri(); + if (uri.equals("/")) { + return getStatic("/go.html"); + } + if (isApiUrl(uri)) { + return routeApi(session); + } + return getStatic(uri); + } + + private NanoHTTPD.Response routeApi(NanoHTTPD.IHTTPSession session) { + String uri = session.getUri(); + int pathEnd = uri.indexOf("/", 1); + if (pathEnd != -1) { + uri = uri.substring(0, pathEnd); + } + ApiEndpoint endpoint = endpoints.get(uri); + if (endpoint != null) { + return endpoint.process(session); + } + return ErrorResponses.response404; + } + + private boolean isApiUrl(String uri) { + for (String endpoint : endpoints.keySet()) { + int stringLength = endpoint.length(); + if (uri.startsWith(endpoint) && + (uri.length() == endpoint.length() || uri.charAt(stringLength) == '/')) { + return true; + } + } + return false; + } + + private void registerEndpoints() { + register("/tile", new TileEndpoint(application)); + } + + private void register(String path, ApiEndpoint endpoint) { + endpoint.setApplication(application); + endpoints.put(path, endpoint); + } + + private NanoHTTPD.Response getStatic(String uri) { + InputStream is; + String mimeType = parseMimeType(uri); + if (application != null) { + try { + is = application.getAssets().open(FOLDER_NAME + uri); + if (is.available() == 0) { + return ErrorResponses.response404; + } + return newFixedLengthResponse( + NanoHTTPD.Response.Status.OK, + mimeType, + is, + is.available()); + } catch (IOException e) { + return ErrorResponses.response404; + } + } + return ErrorResponses.response500; + } + + private String parseMimeType(String url) { + String type = "text/plain"; + if (url.endsWith(".js")) return "text/javascript"; + String extension = MimeTypeMap.getFileExtensionFromUrl(url); + if (extension != null) { + type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); + } + return type; + } + + public static class ErrorResponses { + public static NanoHTTPD.Response response404 = + newFixedLengthResponse(NanoHTTPD.Response.Status.NOT_FOUND, + NanoHTTPD.MIME_PLAINTEXT, "404 Not Found"); + + public static NanoHTTPD.Response response500 = + newFixedLengthResponse(NanoHTTPD.Response.Status.INTERNAL_ERROR, + NanoHTTPD.MIME_PLAINTEXT, "500 Internal Server Error"); } } diff --git a/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java b/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java index f0a5b598b4..d3ff591ab7 100644 --- a/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java +++ b/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java @@ -9,7 +9,7 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.render.MapRenderRepositories; import net.osmand.plus.resources.AsyncLoadingThread; import net.osmand.plus.server.ApiEndpoint; -import net.osmand.plus.server.ApiRouter; +import net.osmand.plus.server.OsmAndHttpServer; import org.apache.commons.logging.Log; import java.io.ByteArrayInputStream; @@ -35,20 +35,6 @@ public class TileEndpoint implements ApiEndpoint { @Override public NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session) { - try { - return tileApiCall(session); - } catch (Exception e) { - LOG.error("Exception", e); - } - return ApiRouter.ErrorResponses.response500; - } - - @Override - public void setApplication(OsmandApplication application) { - this.application = application; - } - - private synchronized NanoHTTPD.Response tileApiCall(NanoHTTPD.IHTTPSession session) { int zoom; double lat; double lon; @@ -57,6 +43,27 @@ public class TileEndpoint implements ApiEndpoint { zoom = s.nextInt(); lat = s.nextDouble(); lon = s.nextDouble(); + Bitmap bitmap = requestTile(lat, lon, zoom); + if (bitmap == null) { + return OsmAndHttpServer.ErrorResponses.response500; + } + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); + byte[] byteArray = stream.toByteArray(); + ByteArrayInputStream str = new ByteArrayInputStream(byteArray); + return newFixedLengthResponse( + NanoHTTPD.Response.Status.OK, + "image/png", + str, + str.available()); + } + + @Override + public void setApplication(OsmandApplication application) { + this.application = application; + } + + private synchronized Bitmap requestTile(double lat, double lon, int zoom) { Future> future; final RotatedTileBox rotatedTileBox = new RotatedTileBox.RotatedTileBoxBuilder() .setLocation(lat, lon) @@ -67,8 +74,10 @@ public class TileEndpoint implements ApiEndpoint { @Override public Pair call() throws Exception { Bitmap bmp; + int sleepTime = 500; while ((bmp = map.get(rotatedTileBox)) == null) { - Thread.sleep(500); + Thread.sleep(sleepTime); + sleepTime += 500; } return Pair.create(rotatedTileBox, bmp); } @@ -82,21 +91,12 @@ public class TileEndpoint implements ApiEndpoint { try { Pair pair = future.get(); Bitmap bitmap = pair.second; - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); - byte[] byteArray = stream.toByteArray(); - ByteArrayInputStream str = new ByteArrayInputStream(byteArray); - return newFixedLengthResponse( - NanoHTTPD.Response.Status.OK, - "image/png", - str, - str.available()); + return bitmap; } catch (ExecutionException e) { LOG.error("Execution exception", e); - return ApiRouter.ErrorResponses.response500; } catch (InterruptedException e) { LOG.error("Interrupted exception", e); - return ApiRouter.ErrorResponses.response500; } + return null; } }