!7 static S password; static S dir = "/storage/sdcard0"; p { password = loadSecretTextFile("password"); // looks in JavaX-Secret/#1005938/password serveHttp(7777); run("#1000842"); // upload server on 8888 } static NanoHTTPD.Response serve(S uri, NanoHTTPD.Method method, Map header, Map params, Map files) { print("Serving HTML."); File d = new File(dir); File sub = new File(dir, dropPrefix("/", uri)); print("File: " + sub.getAbsolutePath() + ", exists: " + sub.exists()); S html; if (!sub.exists()) html = "Not found: " + quote(f2s(sub)) + " (uri: " + quote(uri) + ")"; else if (sub.isFile()) ret serveFile(sub); else { S setPW = params.get("setpw"); if (empty(password) && nempty(setPW)) { saveSecretTextFile("password", password = setPW); ret serveHTML("Password set."); } else if (neq(password, params.get("pw"))) ret serveHTML("No..."); html = fileLinks(findAllFiles(sub), d); } ret serveHTML(htitle("Phone Server.") + p(href("http://" + getMyIP() + ":8888", "Upload stuff")) + h3(sub.getAbsolutePath()) + html); } static S fileLinks(L files, File rootDir) { new L l; for (File f : files) { S path = getRelPath(f, rootDir); l.add(href(urlencode(dropPrefix("/", path)), path)); } ret ul(l); } static S getRelPath(File f, File root) ctex { ret dropPrefix(root.getCanonicalPath(), f.getCanonicalPath()); }