// we aren't really going to show any directories, just display our shared media private String listDirectory(String strUri, java.io.File f) { Uri uri = Uri.parse(strUri); int startIdx = 0; int length = 10; // String heading = "Directory " + uri; String heading = "CameraV Web Share"; StringBuilder msg = new StringBuilder( "<html><head><title>" + heading + "</title>" + "<link rel=\"stylesheet\" type=\"text/css\" href=\"/style.css\"/>" + "</head><body><h2>" + heading + "</h2>"); if (mListMedia != null && mListMedia.size() > 0) { if (mListMedia.size() > 0) { msg.append("<section class=\"files\">"); for (int i = startIdx; i < (startIdx + length) && i < mListMedia.size(); i++) { IMedia media = mListMedia.get(i); String pathMedia = media._id; StringBuffer desc = new StringBuffer(); desc.append("<b>").append(media.dcimEntry.fileAsset.name).append("</b><br/><br/>"); try { desc.append("<pre>").append(media.buildSummary(mContext, null)).append("</pre>"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } msg.append("<div class=\"thumbnailBorder\">"); msg.append("<a href=\"") .append(encodeUri(pathMedia)) .append("\"><img src=\"") .append(encodeUri(pathMedia + ".thumb")) .append("\"/></a><br/>"); msg.append("<a href=\"").append(encodeUri(pathMedia)).append("\">Download Media</a>"); msg.append(" | "); msg.append("<a href=\"") .append(encodeUri(pathMedia + ".j3m")) .append("\">Download J3M</a> "); msg.append(" | "); msg.append("<a href=\"") .append(encodeUri(pathMedia + ".csv")) .append("\">Download CSV</a>"); msg.append("<br/><br/>"); File curFile = new File(pathMedia); long len = curFile.length(); msg.append("<div class=\"desc\">"); msg.append(desc).append(" ("); if (len < 1024) { msg.append(len).append(" bytes"); } else if (len < 1024 * 1024) { msg.append(len / 1024).append(".").append(len % 1024 / 10 % 100).append(" KB"); } else { msg.append(len / (1024 * 1024)) .append(".") .append(len % (1024 * 1024) / 10 % 100) .append(" MB"); } msg.append(")</div></div>"); } msg.append("</section>"); } } msg.append("</body></html>"); return msg.toString(); }
private Response respond(Map<String, String> headers, String uri) { // Remove URL arguments uri = uri.trim().replace(File.separatorChar, '/'); if (uri.indexOf('?') >= 0) { uri = uri.substring(0, uri.indexOf('?')); } // Prohibit getting out of current directory if (uri.startsWith("src/main") || uri.endsWith("src/main") || uri.contains("../")) { return createResponse( Response.Status.FORBIDDEN, NanoHTTPD.MIME_PLAINTEXT, "FORBIDDEN: Won't serve ../ for security reasons."); } // Browsers get confused without '/' after the directory, send a redirect. java.io.File f = null; if (uri.length() > 0) { String[] uriParts = uri.split("\\."); String mediaId = uriParts[0].substring(1); IMedia media = getMediaFile(mediaId); if (media != null) { if (uriParts.length == 1) { if (media.dcimEntry.fileAsset.source == Storage.Type.IOCIPHER) f = new info.guardianproject.iocipher.File(media.dcimEntry.fileAsset.path); else // if file system f = new java.io.File(media.dcimEntry.fileAsset.path); } else if (uriParts[1].equals("thumb")) { if (media.dcimEntry.fileAsset.source == Storage.Type.IOCIPHER) f = new info.guardianproject.iocipher.File(media.dcimEntry.thumbnail.path); else // if file system f = new java.io.File(media.dcimEntry.thumbnail.path); } else if (uriParts[1].equals("j3m")) { String j3m; try { j3m = media.buildJ3M(mContext, false, null); String mime = "text/plain"; InputStream is = new StringBufferInputStream(j3m); Response res = createResponse(Response.Status.OK, mime, is); res.addHeader("Content-Length", "" + j3m.length()); return res; } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else if (uriParts[1].equals("csv")) { String j3m; try { j3m = media.buildCSV(mContext, null); String mime = "text/plain"; InputStream is = new StringBufferInputStream(j3m); Response res = createResponse(Response.Status.OK, mime, is); res.addHeader("Content-Length", "" + j3m.length()); return res; } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } else { boolean canServeUri = false; File homeDir = null; List<File> roots = getRootDirs(); for (int i = 0; !canServeUri && i < roots.size(); i++) { homeDir = roots.get(i); canServeUri = canServeUri(uri, homeDir); } if (!canServeUri) { return createResponse( Response.Status.NOT_FOUND, NanoHTTPD.MIME_PLAINTEXT, "Error 404, file not found."); } f = new info.guardianproject.iocipher.File(homeDir, uri); } } else { boolean canServeUri = false; File homeDir = null; List<File> roots = getRootDirs(); for (int i = 0; !canServeUri && i < roots.size(); i++) { homeDir = roots.get(i); canServeUri = canServeUri(uri, homeDir); } if (!canServeUri) { return createResponse( Response.Status.NOT_FOUND, NanoHTTPD.MIME_PLAINTEXT, "Error 404, file not found."); } f = new info.guardianproject.iocipher.File(homeDir, uri); } if (f.isDirectory() && !uri.endsWith("/")) { uri += "/"; Response res = createResponse( Response.Status.REDIRECT, NanoHTTPD.MIME_HTML, "<html><body>Redirected: <a href=\"" + uri + "\">" + uri + "</a></body></html>"); res.addHeader("Location", uri); return res; } if (f.isDirectory()) { // First look for index files (index.html, index.htm, etc) and if none found, list the // directory if readable. String indexFile = findIndexFileInDirectory(f); if (indexFile == null) { if (f.canRead()) { // No index file, list the directory if it is readable return createResponse(Response.Status.OK, NanoHTTPD.MIME_HTML, listDirectory(uri, f)); } else { return createResponse( Response.Status.FORBIDDEN, NanoHTTPD.MIME_PLAINTEXT, "FORBIDDEN: No directory listing."); } } else { return respond(headers, uri + indexFile); } } String mimeTypeForFile = getMimeTypeForFile(uri); WebServerPlugin plugin = mimeTypeHandlers.get(mimeTypeForFile); Response response = null; if (plugin != null) { response = plugin.serveFile(uri, headers, f, mimeTypeForFile); if (response != null && response instanceof InternalRewrite) { InternalRewrite rewrite = (InternalRewrite) response; return respond(rewrite.getHeaders(), rewrite.getUri()); } } else { response = serveFile(uri, headers, f, mimeTypeForFile); } return response != null ? response : createResponse( Response.Status.NOT_FOUND, NanoHTTPD.MIME_PLAINTEXT, "Error 404, file not found."); }