|
@@ -1,73 +1,109 @@ |
1 |
1 |
|
package org.litesoft.ddt; |
2 |
2 |
|
|
3 |
|
- |
import org.litesoft.useragent.UserAgentFormFactorDeterminer; |
4 |
|
- |
import org.litesoft.useragent.UserAgentFormFactorDeterminerImpl; |
5 |
|
- |
|
|
3 |
+ |
import javax.servlet.ServletConfig; |
|
4 |
+ |
import javax.servlet.ServletContext; |
6 |
5 |
|
import javax.servlet.ServletException; |
7 |
|
- |
import javax.servlet.http.Cookie; |
8 |
6 |
|
import javax.servlet.http.HttpServlet; |
9 |
7 |
|
import javax.servlet.http.HttpServletRequest; |
10 |
8 |
|
import javax.servlet.http.HttpServletResponse; |
|
9 |
+ |
import java.io.Closeable; |
|
10 |
+ |
import java.io.File; |
|
11 |
+ |
import java.io.FileInputStream; |
11 |
12 |
|
import java.io.IOException; |
12 |
|
- |
import java.sql.Timestamp; |
|
13 |
+ |
import java.io.InputStream; |
|
14 |
+ |
import java.io.OutputStream; |
13 |
15 |
|
|
14 |
16 |
|
public class DeviceDesktopTestServlet extends HttpServlet { |
15 |
|
- |
public static final String FRONT_TO_TITLE = "<!DOCTYPE html><html lang='en' height='100%'>\n<head>\n<meta charset='UTF-8'/>\n<title>"; |
16 |
|
- |
public static final String TITLE_TO_HEADER_SEP = "</title>\n<script type='text/javascript' src='CookieSupport.js'></script>\n</head>\n<body height='100%'>\n<h1>--- "; |
17 |
|
- |
public static final String HEADER_TO_JS_SEP = " ---</h1>\n<div id='insertHere' height='100%'></div>\n<script type='text/javascript' src='"; |
18 |
|
- |
public static final String JS_TO_END = ".js'></script>\n</body>\n</html>"; |
|
17 |
+ |
private final IndexHtmlGenerator mIndexHtmlGenerator = new IndexHtmlGenerator(); |
19 |
18 |
|
|
20 |
|
- |
private static final UserAgentFormFactorDeterminer UAFFD = new UserAgentFormFactorDeterminerImpl(); |
|
19 |
+ |
private ServletContext mServletContext; |
21 |
20 |
|
|
22 |
21 |
|
@Override |
23 |
|
- |
protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { |
24 |
|
- |
System.out.println("ContextPath: " + request.getContextPath()); |
25 |
|
- |
System.out.println("ServletPath: " + request.getServletPath()); |
26 |
|
- |
System.out.println("PathInfo: " + request.getPathInfo()); |
27 |
|
- |
String zDeviceToken = getCookie(request, "DeviceToken"); |
28 |
|
- |
if (zDeviceToken != null) { |
29 |
|
- |
reply(resp, "LimitedMode"); |
|
22 |
+ |
public void init(ServletConfig config) throws ServletException { |
|
23 |
+ |
super.init(config); |
|
24 |
+ |
mServletContext = config.getServletContext(); |
|
25 |
+ |
} |
|
26 |
+ |
|
|
27 |
+ |
@Override |
|
28 |
+ |
protected void doGet(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException { |
|
29 |
+ |
String zPath = pRequest.getPathInfo(); |
|
30 |
+ |
if (zPath == null) { |
|
31 |
+ |
zPath = "/"; |
|
32 |
+ |
} |
|
33 |
+ |
if (zPath.endsWith("/")) { |
|
34 |
+ |
zPath += "index.html"; |
|
35 |
+ |
} |
|
36 |
+ |
if (zPath.endsWith("/index.html")) { |
|
37 |
+ |
mIndexHtmlGenerator.respond(zPath, pRequest, pResponse); |
30 |
38 |
|
return; |
31 |
39 |
|
} |
32 |
|
- |
String zUserAuthToken = getCookie(request, "UserAuthToken"); |
33 |
|
- |
if (zUserAuthToken != null) { |
34 |
|
- |
reply(resp, "FullMode"); |
35 |
|
- |
if (null != getCookie(request, "Restart")) { |
36 |
|
- |
new Thread(new Restart()).start(); |
37 |
|
- |
} |
|
40 |
+ |
File zFile = new File("." + zPath); |
|
41 |
+ |
if (!zFile.isFile()) { |
|
42 |
+ |
System.out.println("Can't find: " + zFile.getAbsolutePath()); |
|
43 |
+ |
pResponse.sendError(HttpServletResponse.SC_NOT_FOUND); |
|
44 |
+ |
return; |
|
45 |
+ |
} |
|
46 |
+ |
if (!zFile.canRead()) { |
|
47 |
+ |
System.out.println("Can't read: " + zFile.getAbsolutePath()); |
|
48 |
+ |
pResponse.sendError(HttpServletResponse.SC_FORBIDDEN); |
38 |
49 |
|
return; |
39 |
50 |
|
} |
40 |
|
- |
String zUserAgent = request.getHeader("user-agent"); |
41 |
|
- |
System.out.println("User Agent: " + zUserAgent); |
42 |
|
- |
reply(resp, "Login" + UAFFD.determine(zUserAgent)); |
43 |
|
- |
} |
44 |
51 |
|
|
45 |
|
- |
private void reply(HttpServletResponse resp, String pWhat) throws IOException { |
46 |
|
- |
resp.getWriter().println(FRONT_TO_TITLE + pWhat + TITLE_TO_HEADER_SEP + pWhat + HEADER_TO_JS_SEP + pWhat + JS_TO_END); |
47 |
|
- |
} |
|
52 |
+ |
// the w3c spec requires a maximum age of 1 year |
|
53 |
+ |
// Firefox 3+ needs 'public' to cache this resource when received via SSL |
|
54 |
+ |
pResponse.setHeader("Cache-Control", "public max-age=31536000"); |
|
55 |
+ |
|
|
56 |
+ |
// necessary to overwrite "Pragma: no-cache" header |
|
57 |
+ |
pResponse.setHeader("Pragma", "temp"); |
|
58 |
+ |
pResponse.setHeader("Pragma", ""); |
|
59 |
+ |
pResponse.setDateHeader("Expires", System.currentTimeMillis() + 31536000000l); |
|
60 |
+ |
|
|
61 |
+ |
// Get the MIME type |
|
62 |
+ |
String mimeType = mServletContext.getMimeType(zFile.getName().toLowerCase()); |
|
63 |
+ |
if (null == mimeType) { |
|
64 |
+ |
System.err.println("Could not get MIME type of " + zFile.getName()); |
|
65 |
+ |
mimeType = "application/octet-stream"; |
|
66 |
+ |
} |
|
67 |
+ |
// Set content type |
|
68 |
+ |
pResponse.setContentType(mimeType); |
48 |
69 |
|
|
49 |
|
- |
private static String getCookie(HttpServletRequest request, String pName) { |
50 |
|
- |
Cookie[] zCookies = request.getCookies(); |
51 |
|
- |
if (zCookies != null) { |
52 |
|
- |
for (Cookie zCookie : zCookies) { |
53 |
|
- |
if (zCookie.getName().equals(pName)) { |
54 |
|
- |
return zCookie.getValue(); |
55 |
|
- |
} |
|
70 |
+ |
// Set content size |
|
71 |
+ |
pResponse.setContentLength((int) zFile.length()); |
|
72 |
+ |
|
|
73 |
+ |
// Open the file and output streams |
|
74 |
+ |
InputStream in = new FileInputStream(zFile); |
|
75 |
+ |
try { |
|
76 |
+ |
OutputStream out = pResponse.getOutputStream(); |
|
77 |
+ |
try { |
|
78 |
+ |
copyStream(in, out); |
|
79 |
+ |
|
|
80 |
+ |
Closeable zCloseable = out; |
|
81 |
+ |
out = null; |
|
82 |
+ |
zCloseable.close(); |
|
83 |
+ |
} finally { |
|
84 |
+ |
closeQuietly(out); |
56 |
85 |
|
} |
|
86 |
+ |
} finally { |
|
87 |
+ |
closeQuietly(in); |
57 |
88 |
|
} |
58 |
|
- |
return null; |
59 |
89 |
|
} |
60 |
90 |
|
|
61 |
|
- |
private static class Restart implements Runnable { |
62 |
|
- |
@Override |
63 |
|
- |
public void run() { |
|
91 |
+ |
private static void closeQuietly(Closeable pClosable) { |
|
92 |
+ |
if (pClosable != null) { |
64 |
93 |
|
try { |
65 |
|
- |
Thread.sleep(2000); |
66 |
|
- |
} catch (InterruptedException e) { |
67 |
|
- |
e.printStackTrace(); |
|
94 |
+ |
pClosable.close(); |
|
95 |
+ |
} catch (IOException e) { |
|
96 |
+ |
// Whatever |
68 |
97 |
|
} |
69 |
|
- |
System.out.println("Restarting @: " + new Timestamp(System.currentTimeMillis())); |
70 |
|
- |
// TODO: XXX |
|
98 |
+ |
} |
|
99 |
+ |
} |
|
100 |
+ |
|
|
101 |
+ |
private static void copyStream(InputStream pIn, OutputStream pOut) |
|
102 |
+ |
throws IOException { |
|
103 |
+ |
// Copy the contents of the file to the output stream |
|
104 |
+ |
byte[] buf = new byte[1024]; |
|
105 |
+ |
for (int count; (count = pIn.read(buf)) > 0; ) { |
|
106 |
+ |
pOut.write(buf, 0, count); |
71 |
107 |
|
} |
72 |
108 |
|
} |
73 |
109 |
|
} |