1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 package jnlp.sample.servlet;
38
39 import javax.servlet.ServletConfig;
40 import javax.servlet.ServletException;
41 import javax.servlet.http.HttpServlet;
42 import javax.servlet.http.HttpServletRequest;
43 import javax.servlet.http.HttpServletResponse;
44 import java.io.IOException;
45 import java.util.ResourceBundle;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 public class JnlpDownloadServlet
66 extends HttpServlet
67 {
68
69
70 private static ResourceBundle _resourceBundle = null;
71
72
73 private static final String PARAM_JNLP_EXTENSION = "jnlp-extension";
74
75 private static final String PARAM_JAR_EXTENSION = "jar-extension";
76
77
78 private Logger _log = null;
79
80 private JnlpFileHandler _jnlpFileHandler = null;
81
82 private JarDiffHandler _jarDiffHandler = null;
83
84 private ResourceCatalog _resourceCatalog = null;
85
86
87
88
89 public void init( ServletConfig config )
90 throws ServletException
91 {
92 super.init( config );
93
94
95 _log = new Logger( config, getResourceBundle() );
96 _log.addDebug( "Initializing" );
97
98
99 JnlpResource.setDefaultExtensions( config.getInitParameter( PARAM_JNLP_EXTENSION ),
100 config.getInitParameter( PARAM_JAR_EXTENSION ) );
101
102 _jnlpFileHandler = new JnlpFileHandler( config.getServletContext(), _log );
103 _jarDiffHandler = new JarDiffHandler( config.getServletContext(), _log );
104 _resourceCatalog = new ResourceCatalog( config.getServletContext(), _log );
105 }
106
107 public static synchronized ResourceBundle getResourceBundle()
108 {
109 if ( _resourceBundle == null )
110 {
111 _resourceBundle = ResourceBundle.getBundle( "jnlp/sample/servlet/resources/strings" );
112 }
113 return _resourceBundle;
114 }
115
116
117 public void doHead( HttpServletRequest request, HttpServletResponse response )
118 throws ServletException, IOException
119 {
120 handleRequest( request, response, true );
121 }
122
123
124
125
126 public void doGet( HttpServletRequest request, HttpServletResponse response )
127 throws ServletException, IOException
128 {
129 handleRequest( request, response, false );
130 }
131
132 private void handleRequest( HttpServletRequest request, HttpServletResponse response, boolean isHead )
133 throws IOException
134 {
135 String requestStr = request.getRequestURI();
136 if ( request.getQueryString() != null )
137 {
138 requestStr += "?" + request.getQueryString().trim();
139 }
140
141
142 DownloadRequest dreq = new DownloadRequest( getServletContext(), request );
143 if ( _log.isInformationalLevel() )
144 {
145 _log.addInformational( "servlet.log.info.request", requestStr );
146 _log.addInformational( "servlet.log.info.useragent", request.getHeader( "User-Agent" ) );
147 }
148 if ( _log.isDebugLevel() )
149 {
150 _log.addDebug( dreq.toString() );
151 }
152
153 long ifModifiedSince = request.getDateHeader( "If-Modified-Since" );
154
155
156 try
157 {
158
159 validateRequest( dreq );
160
161
162 JnlpResource jnlpres = locateResource( dreq );
163 _log.addDebug( "JnlpResource: " + jnlpres );
164
165 if ( _log.isInformationalLevel() )
166 {
167 _log.addInformational( "servlet.log.info.goodrequest", jnlpres.getPath() );
168 }
169
170 DownloadResponse dres;
171
172 if ( isHead )
173 {
174
175 int cl = jnlpres.getResource().openConnection().getContentLength();
176
177
178 dres = DownloadResponse.getHeadRequestResponse( jnlpres.getMimeType(), jnlpres.getVersionId(),
179 jnlpres.getLastModified(), cl );
180
181 }
182 else if ( ifModifiedSince != -1 && ( ifModifiedSince / 1000 ) >= ( jnlpres.getLastModified() / 1000 ) )
183 {
184
185
186
187
188
189
190
191 _log.addDebug( "return 304 Not modified" );
192 dres = DownloadResponse.getNotModifiedResponse();
193
194 }
195 else
196 {
197
198
199 dres = constructResponse( jnlpres, dreq );
200 }
201
202 dres.sendRespond( response );
203
204 }
205 catch ( ErrorResponseException ere )
206 {
207 if ( _log.isInformationalLevel() )
208 {
209 _log.addInformational( "servlet.log.info.badrequest", requestStr );
210 }
211 if ( _log.isDebugLevel() )
212 {
213 _log.addDebug( "Response: " + ere.toString() );
214 }
215
216 ere.getDownloadResponse().sendRespond( response );
217 }
218 catch ( Throwable e )
219 {
220 _log.addFatal( "servlet.log.fatal.internalerror", e );
221 response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
222 }
223 }
224
225
226
227
228
229 private void validateRequest( DownloadRequest dreq )
230 throws ErrorResponseException
231 {
232 String path = dreq.getPath();
233 if ( path.endsWith( ResourceCatalog.VERSION_XML_FILENAME ) || path.indexOf( "__" ) != -1 )
234 {
235 throw new ErrorResponseException( DownloadResponse.getNoContentResponse() );
236 }
237 }
238
239
240
241
242
243 private JnlpResource locateResource( DownloadRequest dreq )
244 throws IOException, ErrorResponseException
245 {
246 if ( dreq.getVersion() == null )
247 {
248 return handleBasicDownload( dreq );
249 }
250 else
251 {
252 return handleVersionRequest( dreq );
253 }
254 }
255
256 private JnlpResource handleBasicDownload( DownloadRequest dreq )
257 throws ErrorResponseException, IOException
258 {
259 _log.addDebug( "Basic Protocol lookup" );
260
261 if ( dreq.getPath() == null || dreq.getPath().endsWith( "/" ) )
262 {
263 throw new ErrorResponseException( DownloadResponse.getNoContentResponse() );
264 }
265
266 JnlpResource jnlpres = new JnlpResource( getServletContext(), dreq.getPath() );
267 if ( !jnlpres.exists() )
268 {
269 throw new ErrorResponseException( DownloadResponse.getNoContentResponse() );
270 }
271 return jnlpres;
272 }
273
274 private JnlpResource handleVersionRequest( DownloadRequest dreq )
275 throws IOException, ErrorResponseException
276 {
277 _log.addDebug( "Version-based/Extension based lookup" );
278 return _resourceCatalog.lookupResource( dreq );
279 }
280
281
282
283
284
285 private DownloadResponse constructResponse( JnlpResource jnlpres, DownloadRequest dreq )
286 throws IOException
287 {
288 String path = jnlpres.getPath();
289 if ( jnlpres.isJnlpFile() )
290 {
291
292 boolean supportQuery = JarDiffHandler.isJavawsVersion( dreq, "1.5+" );
293 _log.addDebug( "SupportQuery in Href: " + supportQuery );
294
295
296 if ( supportQuery )
297 {
298 return _jnlpFileHandler.getJnlpFileEx( jnlpres, dreq );
299 }
300 else
301 {
302 return _jnlpFileHandler.getJnlpFile( jnlpres, dreq );
303 }
304 }
305
306
307 if ( dreq.getCurrentVersionId() != null && jnlpres.isJarFile() )
308 {
309 DownloadResponse response = _jarDiffHandler.getJarDiffEntry( _resourceCatalog, dreq, jnlpres );
310 if ( response != null )
311 {
312 _log.addInformational( "servlet.log.info.jardiff.response" );
313 return response;
314 }
315 }
316
317
318 JnlpResource jr =
319 new JnlpResource( getServletContext(), jnlpres.getName(), jnlpres.getVersionId(), jnlpres.getOSList(),
320 jnlpres.getArchList(), jnlpres.getLocaleList(), jnlpres.getPath(),
321 jnlpres.getReturnVersionId(), dreq.getEncoding() );
322
323 _log.addDebug( "Real resource returned: " + jr );
324
325
326 return DownloadResponse.getFileDownloadResponse( jr.getResource(), jr.getMimeType(), jr.getLastModified(),
327 jr.getReturnVersionId() );
328 }
329 }
330
331