KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > knowgate > http > HttpBinaryServlet


1 /*
2   Copyright (C) 2003 Know Gate S.L. All rights reserved.
3                       C/Oña, 107 1º2 28050 Madrid (Spain)
4
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions
7   are met:
8
9   1. Redistributions of source code must retain the above copyright
10      notice, this list of conditions and the following disclaimer.
11
12   2. The end-user documentation included with the redistribution,
13      if any, must include the following acknowledgment:
14      "This product includes software parts from hipergate
15      (http://www.hipergate.org/)."
16      Alternately, this acknowledgment may appear in the software itself,
17      if and wherever such third-party acknowledgments normally appear.
18
19   3. The name hipergate must not be used to endorse or promote products
20      derived from this software without prior written permission.
21      Products derived from this software may not be called hipergate,
22      nor may hipergate appear in their name, without prior written
23      permission.
24
25   This library is distributed in the hope that it will be useful,
26   but WITHOUT ANY WARRANTY; without even the implied warranty of
27   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
28
29   You should have received a copy of hipergate License with this code;
30   if not, visit http://www.hipergate.org or mail to info@hipergate.org
31 */

32
33 package com.knowgate.http;
34
35 import java.io.*;
36 import javax.servlet.*;
37 import javax.servlet.http.*;
38
39 import java.lang.System JavaDoc;
40 import java.util.Properties JavaDoc;
41
42 import java.sql.DriverManager JavaDoc;
43 import java.sql.SQLException JavaDoc;
44 import java.sql.Connection JavaDoc;
45 import java.sql.PreparedStatement JavaDoc;
46 import java.sql.ResultSet JavaDoc;
47
48 import com.knowgate.debug.DebugFile;
49 import com.knowgate.acl.ACL;
50 import com.knowgate.dataobjs.DB;
51 import com.knowgate.hipergate.*;
52 import com.knowgate.misc.Environment;
53
54 import com.enterprisedt.net.ftp.*;
55
56 /**
57  * <p>Send Disk Binary File To HttpServletResponse OutputStream</p>
58  * @author Sergio Montoro ten
59  * @version 2.1
60  */

61 public class HttpBinaryServlet extends HttpServlet {
62
63   public static long pipe(InputStream in, OutputStream out, int chunkSize)
64     throws IOException {
65     if( chunkSize < 1 ) throw new IOException("Invalid chunk size.");
66
67     byte[] buf = new byte[chunkSize];
68     long tot = 0;
69     int n;
70     while( (n=in.read(buf)) != -1 ) {
71       out.write(buf,0,n);
72       tot += n;
73     }
74     out.flush();
75
76     return tot;
77   } // pipe()
78

79  // -----------------------------------------------------------
80

81  private boolean isVoid(String JavaDoc sParam) {
82    if (null==sParam)
83      return true;
84    else
85      return (sParam.length()==0);
86  }
87
88  /**
89   * <p>Initialize Servlet Parameters</p>
90   * Take Database Driver, Conenction URL and User from /WEB-INF/web.xml.<br>
91   * If any parameter is not found then look it up at hipergate.cnf Properties
92   * file using Environment singleton.
93   * @throws ServletException
94   * @throws UnavailableException If jdbcDriverClassName parameter is not found
95   * and driver property at hipergate.cnf is not found or if jdbcURL parameter
96   * is not found and dburl property at hipergate.cnf is not found.
97   * @see com.knowgate.misc.Environment
98   */

99  public void init() throws ServletException {
100
101    ServletConfig config = getServletConfig();
102
103    jdbcDriverClassName = config.getInitParameter("jdbcDriverClassName");
104
105    jdbcURL = config.getInitParameter("jdbcURL");
106    dbUserName = config.getInitParameter("dbUserName");
107    dbUserPassword = config.getInitParameter("dbUserPassword");
108
109    if (isVoid(jdbcDriverClassName) || isVoid(jdbcURL) || isVoid(dbUserName) || isVoid(dbUserPassword)) {
110      Properties JavaDoc env = Environment.getProfile("hipergate");
111
112      if (isVoid(jdbcDriverClassName))
113        jdbcDriverClassName = env.getProperty("driver");
114
115      if (isVoid(jdbcURL))
116        jdbcURL = env.getProperty("dburl");
117
118      if (isVoid(dbUserName))
119        dbUserName = env.getProperty("dbuser");
120
121      if (isVoid(dbUserPassword))
122        dbUserPassword = env.getProperty("dbpassword");
123    }
124
125    if (jdbcDriverClassName == null || jdbcURL == null)
126      throw new UnavailableException("Init params missing");
127  } // init()
128

129  // -----------------------------------------------------------
130

131  /**
132   * <p>Send disk binary file held in a Product to HttpServletResponse OutputStream</p>
133   * @param id_user Requester User GUID.
134   * @param id_product GUID of Requested Product.
135   * @param id_location GUID of Requested ProductLocation.
136   * @param id_category (Optional) GUID from Category that contains the Product to serve.
137   * If a Category is provided then the User permissions over that Category are checked
138   * before serving the file.
139   * @return Throught response.sendError()<br>
140   * <table border=1 cellpadding=4>
141   * <tr><td><b>HttpServletResponse Error Code</b></td><td><b>Description</b></td></tr>
142   * <tr><td>SC_INTERNAL_SERVER_ERROR</td><td>Database driver not found</td></tr>
143   * <tr><td>SC_FORBIDDEN</td><td>User does not have read permissions for requested file</td></tr>
144   * <tr><td>SC_NOT_FOUND</td><td>Cannot find file</td></tr>
145   * </table>
146   * @throws IOException
147   * @throws FileNotFoundException
148   * @throws ServletException
149   * @see com.knowgate.acl.ACLUser
150   * @see com.knowgate.hipergate.Product
151   * @see com.knowgate.hipergate.Category
152   */

153  public void doGet(HttpServletRequest request, HttpServletResponse response)
154     throws IOException, FileNotFoundException, ServletException
155     {
156     int iACLMask;
157     boolean bFound;
158     Class JavaDoc oDriver;
159     Connection JavaDoc oConn = null;
160     PreparedStatement JavaDoc oStmt;
161     ResultSet JavaDoc oRSet;
162     File myFile;
163     Category oCatg;
164     String JavaDoc gu_category;
165     String JavaDoc id_location;
166     String JavaDoc xprotocol = "file://";
167     String JavaDoc xpath = null;
168     String JavaDoc xfile = null;
169     String JavaDoc xoriginalfile = null;
170     String JavaDoc mimetype = null;
171
172     if (DebugFile.trace) {
173       DebugFile.writeln("Begin HttpBinaryServlet.doGet()");
174       DebugFile.incIdent();
175     }
176
177     try {
178       oDriver = Class.forName(jdbcDriverClassName);
179     }
180     catch (ClassNotFoundException JavaDoc ignore) {
181       oDriver = null;
182       if (DebugFile.trace) DebugFile.writeln("Class.forName(" + jdbcDriverClassName + ") : " + ignore.getMessage());
183       response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Database driver not found");
184     }
185
186     if (null==oDriver) return;
187
188     try {
189       if (DebugFile.trace) DebugFile.writeln("DriverManager.getConnection(" + jdbcURL + "," + dbUserName + ", ...)");
190
191       oConn = DriverManager.getConnection(jdbcURL,dbUserName,dbUserPassword);
192
193       // Si el archivo a recuperar está contenido dentro de una categoría,
194
// verificar los permisos del usuario sobre dicha categoría
195
gu_category = request.getParameter("id_category");
196       if (gu_category!=null)
197         if (gu_category.length()>0) {
198           oCatg = new Category();
199           oCatg.put(DB.gu_category, gu_category);
200           iACLMask = oCatg.getUserPermissions(oConn, request.getParameter("id_user"));
201           oCatg = null;
202         }
203         else
204           iACLMask = ACL.PERMISSION_LIST|ACL.PERMISSION_READ|ACL.PERMISSION_ADD|ACL.PERMISSION_MODIFY|ACL.PERMISSION_SEND;
205       else
206         iACLMask = ACL.PERMISSION_LIST|ACL.PERMISSION_READ|ACL.PERMISSION_ADD|ACL.PERMISSION_MODIFY|ACL.PERMISSION_SEND;
207
208       if ((iACLMask&ACL.PERMISSION_READ)==0) {
209         bFound = false;
210         response.sendError(HttpServletResponse.SC_FORBIDDEN, "User does not have read permissions for requested file");
211       }
212       else {
213         id_location = request.getParameter("id_location");
214         if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement(SELECT l." + DB.xprotocol + ", l." + DB.xhost + ", l." + DB.xport + ", l." + DB.xpath + ", l." + DB.xfile + ", l." + DB.xoriginalfile + ", t." + DB.mime_type + ",l." + DB.gu_location + ",l." + DB.dt_uploaded + " FROM " + DB.k_prod_locats + " l, " + DB.k_lu_prod_types + " t WHERE l." + DB.gu_product + "='" + request.getParameter("id_product") + "' AND l." + DB.id_prod_type + "=t." + DB.id_prod_type + " ORDER BY l." + DB.dt_uploaded + " DESC");
215
216         oStmt = oConn.prepareStatement("SELECT l." + DB.xprotocol + ", l." + DB.xhost + ", l." + DB.xport + ", l." + DB.xpath + ", l." + DB.xfile + ", l." + DB.xoriginalfile + ", t." + DB.mime_type + ",l." + DB.gu_location + ",l." + DB.dt_uploaded + " FROM " + DB.k_prod_locats + " l, " + DB.k_lu_prod_types + " t WHERE l." + DB.gu_product + "=? AND l." + DB.id_prod_type + "=t." + DB.id_prod_type + " ORDER BY l." + DB.dt_uploaded + " DESC", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
217         oStmt.setString(1, request.getParameter("id_product"));
218         oRSet = oStmt.executeQuery();
219         bFound = oRSet.next();
220
221         if (DebugFile.trace) {
222           if (bFound)
223             DebugFile.writeln("found product " + request.getParameter("id_product"));
224           else
225             DebugFile.writeln("product " + request.getParameter("id_product") + " not found");
226         }
227
228         if ((null!=id_location) && bFound) {
229           bFound = false;
230           do {
231             if (id_location.equals(oRSet.getString(8))) {
232               bFound = true;
233               break;
234             } // fi (id_location==oRSet.get(gu_location))
235
} while (oRSet.next());
236
237           if (DebugFile.trace) {
238             if (bFound)
239               DebugFile.writeln("found location " + id_location);
240             else
241               DebugFile.writeln("location " + id_location + " not found");
242           }
243         } // fi (id_location)
244

245         if (bFound) {
246           xprotocol = oRSet.getString(1).toLowerCase();
247           xpath = oRSet.getString(4);
248
249           if (xprotocol.equalsIgnoreCase("ftp://")) {
250             if (!xpath.endsWith("/")) xpath += "/";
251           }
252           else {
253             if (!xpath.endsWith(java.io.File.separator)) xpath += java.io.File.separator;
254           }
255
256           xfile = oRSet.getString(5);
257           xoriginalfile = oRSet.getString(6);
258           mimetype = oRSet.getString(7);
259
260           if (DebugFile.trace) DebugFile.writeln(xoriginalfile + " " + (mimetype == null ? "" : mimetype));
261         } // fi (bFound)
262

263         oRSet.close();
264         oRSet = null;
265         oStmt.close();
266         oStmt = null;
267
268         if (!bFound) {
269           response.sendError(HttpServletResponse.SC_NOT_FOUND, "Cannot find requested file");
270         }
271       }
272
273       oConn.close();
274       oConn = null;
275     }
276     catch (SQLException JavaDoc e) {
277       if (DebugFile.trace) DebugFile.writeln(e.getMessage());
278       bFound = false;
279       response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
280     }
281     try { if(null!=oConn) if(!oConn.isClosed()) oConn.close(); }
282     catch (SQLException JavaDoc e) { if (DebugFile.trace) DebugFile.writeln(e.getMessage()); }
283
284     if (!bFound) {
285       if (DebugFile.trace) DebugFile.decIdent();
286       return;
287     }
288
289     // Do initial test to see if we need to send a 404 error.
290

291     if (DebugFile.trace) DebugFile.writeln("new File(" + xpath+xfile + ")");
292
293     if (xprotocol.equals("ftp://")) {
294       if (null!=mimetype) response.setContentType(mimetype);
295       response.setHeader("Content-Disposition","attachment; filename=\"" + (xoriginalfile==null ? xfile : xoriginalfile) + "\"");
296
297       boolean bLogged = false;
298       FTPClient oFTP = null;
299
300       try {
301         oFTP = new FTPClient(Environment.getProfileVar("hipergate", "fileserver", "localhost"));
302
303         oFTP.login(Environment.getProfileVar("hipergate", "fileuser", "anonymous"), Environment.getProfileVar("hipergate", "filepassword", ""));
304
305         bLogged = true;
306
307         oFTP.get(response.getOutputStream(), xpath+xfile);
308
309         oFTP.quit();
310
311         bLogged = false;
312       }
313       catch (FTPException ftpe) {
314         if (oFTP!=null && bLogged) {
315           try {oFTP.quit(); } catch (Exception JavaDoc ignore) {}
316         }
317         response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ftpe.getMessage());
318         if (DebugFile.trace) DebugFile.decIdent();
319         return;
320       }
321     }
322     else {
323       myFile = new File(xpath+xfile);
324       if( !myFile.canRead() ) {
325           response.sendError(HttpServletResponse.SC_NOT_FOUND, "Cannot find file " + xfile);
326           if (DebugFile.trace) DebugFile.decIdent();
327           return;
328       } // fi(myFile.canRead)
329

330       // Send some basic http headers to support binary d/l.
331
if (DebugFile.trace) DebugFile.writeln("setContentLength(" + myFile.length() + ")");
332
333       response.setContentLength((int)myFile.length());
334
335       if (DebugFile.trace && null!=mimetype) DebugFile.writeln("setContentType(" + mimetype + ")");
336
337       if (null!=mimetype) response.setContentType(mimetype);
338
339       if (DebugFile.trace) DebugFile.writeln("setHeader(Content-Disposition,attachment; filename=" + xoriginalfile);
340
341       response.setHeader("Content-Disposition","attachment; filename=\"" + xoriginalfile + "\"");
342
343       // Copy the file's bytes to the servlet output stream,
344
// being absolutely sure NOT to leak file handles even
345
// in the face of an exception (thus the try/finally block).
346
InputStream in = null;
347       try {
348         in = new BufferedInputStream(new FileInputStream(myFile));
349         pipe(in,response.getOutputStream(),2048);
350       }
351       finally {
352         if( in != null ) try {
353             in.close();
354         } catch( IOException ignore ) { if (DebugFile.trace) DebugFile.writeln("IOException " + ignore.getMessage()); }
355       }
356     } // fi (xprotocol)
357

358     if (DebugFile.trace) {
359       DebugFile.decIdent();
360       DebugFile.writeln("End HttpBinaryServlet.doGet()");
361     }
362   } // doGet()
363

364   private String JavaDoc jdbcDriverClassName;
365   private String JavaDoc jdbcURL;
366   private String JavaDoc dbUserName;
367   private String JavaDoc dbUserPassword;
368 }
Popular Tags