1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.waarp.http.protocol.servlet;
22
23 import org.waarp.common.database.exception.WaarpDatabaseException;
24 import org.waarp.common.guid.LongUuid;
25 import org.waarp.common.logging.WaarpLogger;
26 import org.waarp.common.logging.WaarpLoggerFactory;
27 import org.waarp.common.utility.WaarpSystemUtil;
28 import org.waarp.http.protocol.HttpDownloadSession;
29
30 import javax.servlet.ServletException;
31 import javax.servlet.http.Cookie;
32 import javax.servlet.http.HttpServletRequest;
33 import javax.servlet.http.HttpServletResponse;
34 import java.io.IOException;
35 import java.lang.reflect.InvocationTargetException;
36 import java.util.Enumeration;
37 import java.util.HashMap;
38 import java.util.Map;
39 import java.util.concurrent.Callable;
40 import java.util.concurrent.ExecutionException;
41 import java.util.concurrent.ExecutorService;
42 import java.util.concurrent.Executors;
43 import java.util.concurrent.Future;
44
45
46
47
48 public class DownloadServlet extends AbstractServlet {
49 private static final long serialVersionUID = 2002L;
50 public static final String FILENAME = "filename";
51 public static final String IDENTIFIER = "identifier";
52 private static final WaarpLogger logger =
53 WaarpLoggerFactory.getLogger(DownloadServlet.class);
54 public static final String X_HASH_SHA_256 = "X-Hash-Sha-256";
55
56 @Override
57 protected final void doPost(final HttpServletRequest request,
58 final HttpServletResponse response) {
59 doGet(request, response);
60 }
61
62 @Override
63 protected final void doHead(final HttpServletRequest request,
64 final HttpServletResponse response) {
65 final Map<String, String> arguments = new HashMap<String, String>();
66 final Enumeration<String> names = request.getParameterNames();
67 while (names.hasMoreElements()) {
68 final String name = names.nextElement();
69 arguments.put(name, request.getParameter(name));
70 }
71 final String filename = getFilename(arguments);
72 logger.debug("RECVHEAD: {}", filename);
73 try {
74 final HttpDownloadSession session =
75 getDownloadSession(arguments, filename, true);
76 logger.debug("RECVHEAD SESSION: {}", session);
77 logger.debug("Check on going");
78 response.setHeader("Expires", "0");
79 response.setHeader("Cache-Control",
80 "must-revalidate, post-check=0, " + "pre-check=0");
81 if (session == null) {
82 logger.debug("Not found");
83 response.setStatus(404);
84 } else if (session.isTransmitting()) {
85 logger.debug("On going");
86 response.setStatus(202);
87 } else if (session.isFinished()) {
88 logger.debug("Done");
89 response.setHeader(X_HASH_SHA_256, session.getComputedHadh());
90 response.setStatus(200);
91 }
92 } catch (final ServletException e) {
93 logger.error(e.getMessage());
94 response.setStatus(400);
95 }
96 }
97
98 @Override
99 protected final void doGet(final HttpServletRequest request,
100 final HttpServletResponse response) {
101 final ExecutorService executor = Executors.newSingleThreadExecutor();
102 try {
103 final Map<String, String> arguments = new HashMap<String, String>();
104 final Enumeration<String> names = request.getParameterNames();
105 while (names.hasMoreElements()) {
106 final String name = names.nextElement();
107 arguments.put(name, request.getParameter(name));
108 }
109 final String filename = getFilename(arguments);
110 logger.debug("RECVGET: {}", filename);
111 try {
112 final HttpDownloadSession session =
113 getDownloadSession(arguments, filename, false);
114 logger.debug("SESSION: {}", session);
115 final Callable<String> hashCompute = new Callable<String>() {
116 @Override
117 public final String call() {
118 return session.getHash();
119 }
120 };
121 final Future<String> future = executor.submit(hashCompute);
122 response.setHeader("Content-Disposition",
123 "attachment; filename=\"" + session.getFinalName() +
124 "\"");
125 response.setHeader("Content-Description", "File Transfer");
126 response.setHeader("Content-Type", "application/octet-stream");
127 response.setHeader("Content-Transfer-Encoding", "binary");
128 response.setHeader("Expires", "0");
129 response.setHeader("Cache-Control",
130 "must-revalidate, post-check=0, " + "pre-check=0");
131
132 final Cookie cookie = new Cookie("fileDownload", "true");
133 cookie.setHttpOnly(true);
134 cookie.setSecure(true);
135 response.addCookie(cookie);
136 response.setHeader("Content-Length",
137 Long.toString(session.getFileSize()));
138 String hash = null;
139 try {
140 hash = future.get();
141 } catch (final InterruptedException e) {
142 logger.debug(e);
143 } catch (final ExecutionException e) {
144 logger.debug(e);
145 }
146 if (hash != null) {
147 response.setHeader(X_HASH_SHA_256, hash);
148
149 }
150 try {
151 if (session.tryWrite(response.getOutputStream())) {
152 session.downloadFinished();
153 logger.info("Download OK: {}", session);
154 response.setStatus(HttpServletResponse.SC_OK);
155 } else {
156 logger.info("NOT FOUND: {}", session);
157 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
158 }
159 } catch (final IOException e) {
160 logger.error("Error: {} {}", session, e.getMessage());
161 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
162 }
163 } catch (final ServletException e) {
164 logger.error(e.getMessage());
165 response.setStatus(400);
166 }
167 } finally {
168 executor.shutdown();
169 }
170 }
171
172 private String getFilename(final Map<String, String> arguments) {
173 return arguments.get(FILENAME);
174 }
175
176 private HttpDownloadSession getDownloadSession(
177 final Map<String, String> arguments, final String filename,
178 final boolean check) throws ServletException {
179 final String rulename = arguments.get(RULENAME);
180 if (rulename == null) {
181 throw new ServletException(INVALID_REQUEST_PARAMS);
182 }
183 String identifier = arguments.get(IDENTIFIER);
184 if (identifier == null) {
185 identifier = Long.toString(LongUuid.getLongUuid());
186 }
187 String comment = arguments.get(COMMENT);
188 if (comment == null) {
189 comment = "Web Download " + identifier;
190 }
191
192 try {
193 final HttpAuthent authent =
194 (HttpAuthent) WaarpSystemUtil.newInstance(authentClass);
195 authent.initializeAuthent(arguments);
196 if (check) {
197 try {
198 return new HttpDownloadSession(identifier, authent);
199 } catch (final WaarpDatabaseException e) {
200 logger.debug(e);
201 return null;
202 }
203 }
204 return new HttpDownloadSession(filename, rulename, identifier, comment,
205 authent);
206 } catch (final IllegalArgumentException e) {
207 throw new ServletException(
208 INVALID_REQUEST_PARAMS + ": " + e.getMessage());
209 } catch (final InvocationTargetException e) {
210 throw new ServletException(
211 INVALID_REQUEST_PARAMS + ": " + e.getMessage());
212 }
213 }
214 }