1 package com.squareup.okhttp.sample; 2 3 import com.squareup.okhttp.internal.Util; 4 import com.squareup.okhttp.mockwebserver.Dispatcher; 5 import com.squareup.okhttp.mockwebserver.MockResponse; 6 import com.squareup.okhttp.mockwebserver.MockWebServer; 7 import com.squareup.okhttp.mockwebserver.RecordedRequest; 8 import java.io.File; 9 import java.io.FileInputStream; 10 import java.io.FileNotFoundException; 11 import java.io.IOException; 12 import java.io.InputStream; 13 import java.security.GeneralSecurityException; 14 import java.security.KeyStore; 15 import java.security.SecureRandom; 16 import javax.net.ssl.KeyManagerFactory; 17 import javax.net.ssl.SSLContext; 18 import javax.net.ssl.TrustManagerFactory; 19 import okio.Buffer; 20 import okio.Okio; 21 22 public class SampleServer extends Dispatcher { 23 private final SSLContext sslContext; 24 private final String root; 25 private final int port; 26 SampleServer(SSLContext sslContext, String root, int port)27 public SampleServer(SSLContext sslContext, String root, int port) { 28 this.sslContext = sslContext; 29 this.root = root; 30 this.port = port; 31 } 32 run()33 public void run() throws IOException { 34 MockWebServer server = new MockWebServer(); 35 server.useHttps(sslContext.getSocketFactory(), false); 36 server.setDispatcher(this); 37 server.start(port); 38 } 39 dispatch(RecordedRequest request)40 @Override public MockResponse dispatch(RecordedRequest request) { 41 String path = request.getPath(); 42 try { 43 if (!path.startsWith("/") || path.contains("..")) throw new FileNotFoundException(); 44 45 File file = new File(root + path); 46 return file.isDirectory() 47 ? directoryToResponse(path, file) 48 : fileToResponse(path, file); 49 } catch (FileNotFoundException e) { 50 return new MockResponse() 51 .setStatus("HTTP/1.1 404") 52 .addHeader("content-type: text/plain; charset=utf-8") 53 .setBody("NOT FOUND: " + path); 54 } catch (IOException e) { 55 return new MockResponse() 56 .setStatus("HTTP/1.1 500") 57 .addHeader("content-type: text/plain; charset=utf-8") 58 .setBody("SERVER ERROR: " + e); 59 } 60 } 61 directoryToResponse(String basePath, File directory)62 private MockResponse directoryToResponse(String basePath, File directory) { 63 if (!basePath.endsWith("/")) basePath += "/"; 64 65 StringBuilder response = new StringBuilder(); 66 response.append(String.format("<html><head><title>%s</title></head><body>", basePath)); 67 response.append(String.format("<h1>%s</h1>", basePath)); 68 for (String file : directory.list()) { 69 response.append(String.format("<div class='file'><a href='%s'>%s</a></div>", 70 basePath + file, file)); 71 } 72 response.append("</body></html>"); 73 74 return new MockResponse() 75 .setStatus("HTTP/1.1 200") 76 .addHeader("content-type: text/html; charset=utf-8") 77 .setBody(response.toString()); 78 } 79 fileToResponse(String path, File file)80 private MockResponse fileToResponse(String path, File file) throws IOException { 81 return new MockResponse() 82 .setStatus("HTTP/1.1 200") 83 .setBody(fileToBytes(file)) 84 .addHeader("content-type: " + contentType(path)); 85 } 86 fileToBytes(File file)87 private Buffer fileToBytes(File file) throws IOException { 88 Buffer result = new Buffer(); 89 result.writeAll(Okio.source(file)); 90 return result; 91 } 92 contentType(String path)93 private String contentType(String path) { 94 if (path.endsWith(".png")) return "image/png"; 95 if (path.endsWith(".jpg")) return "image/jpeg"; 96 if (path.endsWith(".jpeg")) return "image/jpeg"; 97 if (path.endsWith(".gif")) return "image/gif"; 98 if (path.endsWith(".html")) return "text/html; charset=utf-8"; 99 if (path.endsWith(".txt")) return "text/plain; charset=utf-8"; 100 return "application/octet-stream"; 101 } 102 main(String[] args)103 public static void main(String[] args) throws Exception { 104 if (args.length != 4) { 105 System.out.println("Usage: SampleServer <keystore> <password> <root file> <port>"); 106 return; 107 } 108 109 String keystoreFile = args[0]; 110 String password = args[1]; 111 String root = args[2]; 112 int port = Integer.parseInt(args[3]); 113 114 SSLContext sslContext = sslContext(keystoreFile, password); 115 SampleServer server = new SampleServer(sslContext, root, port); 116 server.run(); 117 } 118 sslContext(String keystoreFile, String password)119 private static SSLContext sslContext(String keystoreFile, String password) 120 throws GeneralSecurityException, IOException { 121 KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); 122 InputStream in = new FileInputStream(keystoreFile); 123 try { 124 keystore.load(in, password.toCharArray()); 125 } finally { 126 Util.closeQuietly(in); 127 } 128 KeyManagerFactory keyManagerFactory = 129 KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 130 keyManagerFactory.init(keystore, password.toCharArray()); 131 132 TrustManagerFactory trustManagerFactory = 133 TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 134 trustManagerFactory.init(keystore); 135 136 SSLContext sslContext = SSLContext.getInstance("TLS"); 137 sslContext.init( 138 keyManagerFactory.getKeyManagers(), 139 trustManagerFactory.getTrustManagers(), 140 new SecureRandom()); 141 142 return sslContext; 143 } 144 } 145