001/* 002 * Download.java 003 * $Id: Download.java 1226 2018-03-03 06:21:05Z tgutwin $ 004 * $HeadURL$ 005 * $Revision$ 006 * $LastChangedDate: 2018-03-02 22:21:05 -0800 (Fri, 02 Mar 2018) $ 007 * $LastChangedBy: tgutwin $ 008 * Copyright (c) 2002-2005 Tom B. Gutwin P.Eng. 009 * 010 * This program is free software; you can redistribute it and/or 011 * modify it under the terms of the GNU General Public License 012 * as published by the Free Software Foundation; either version 2 013 * of the License, or any later version. 014 * 015 * This program is distributed in the hope that it will be useful, 016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 018 * GNU General Public License for more details. 019 * 020 * You should have received a copy of the GNU General Public License 021 * along with this program; if not, write to the Free Software 022 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 023 */ 024package ca.bc.webarts.servlet; 025 026import ca.bc.webarts.widgets.AstroVersion; 027 028import ca.bc.webarts.tools.Log; 029import com.oreilly.servlet.ParameterParser; 030 031import com.oreilly.servlet.ServletUtils; 032 033import java.io.BufferedOutputStream; 034import java.io.IOException; 035import java.io.File; 036import java.io.FileNotFoundException; 037import java.io.FileWriter; 038import java.net.InetAddress; 039import java.net.UnknownHostException; 040import java.util.*; 041import javax.activation.*; 042import javax.mail.*; 043import javax.mail.internet.*; 044 045import javax.servlet.*; 046import javax.servlet.http.*; 047 048 049/** 050 * This is a servlet that provides Logged downloading of a resource. 051 * http://www.webarts.bc.ca/Download?resource=http://hobbes.nmsu.edu/pub/java/mmedia/AutoUpdate_jOggPlayer110b.zip 052 * <p> 053 * 054 * For more information on servlets, see <a 055 * href="http://java.sun.com/products/java-server/servlets/index.html"> 056 * http://java.sun.com/products/java-server/servlets/index.html</a> 057 * 058 * @author tgutwin 059 * @created July 17, 2002 060 */ 061public class Download extends HttpServlet 062{ 063 // implements SingleThreadModel 064 065 /* 066 * <!-- configure Download Servlet with init parameters --> 067 * <servlet servlet-name='Download' servlet-class='ca.bc.webarts.servlet.Download'> 068 * <init-param info='A tool to download a resource and log its download.'/> 069 * <init-param serverUrl='Aurora1.webarts.bc.ca'/> 070 * <init-param serverPort='80'/> 071 * <init-param downloadLogFilename='log/downloadLog.txt'/> 072 * </servlet> 073 * <servlet-mapping url-pattern='/Download' servlet-name='Download'/> 074 */ 075 /** Description of the Field */ 076 private final static String SYSTEM_FILE_SEPERATOR = File.separator; 077 /** Version String. */ 078 private final static String SERVLET_VERSION = "a0.4"; 079 080 /** Build String. (yymmddhhss) */ 081 private final static String BUILD_TAG = "0503051701"; 082 083 /** Description of the Field */ 084 private static Calendar calendar_ = Calendar.getInstance(); 085 086 /** This servers name. */ 087 private static String webServerHostName_ = ""; 088 /** Log File Name. */ 089 private final static String DEFAULT_LOG_FILE = 090 SYSTEM_FILE_SEPERATOR + 091 "var" + 092 SYSTEM_FILE_SEPERATOR + 093 "log" + 094 SYSTEM_FILE_SEPERATOR + 095 calendar_.get(calendar_.YEAR) + "-" + 096 calendar_.get(calendar_.DAY_OF_YEAR) + "_" + 097 "DownloadLoggerLog.txt"; 098 099 /** Download Log File Name. */ 100 private final static String DEFAULT_DOWNLOAD_LOG_FILE = 101 SYSTEM_FILE_SEPERATOR + 102 "var" + 103 SYSTEM_FILE_SEPERATOR + 104 "log" + 105 SYSTEM_FILE_SEPERATOR + 106 calendar_.get(calendar_.YEAR) + "-" + 107 calendar_.get(calendar_.DAY_OF_YEAR) + "_" + 108 "DownloadLog.txt"; 109 110 /** Description of the Field */ 111 String title_ = ""; 112 /** The url to the resource to download. */ 113 String downloadUrl_ = ""; 114 /** 115 * This gets assigned if a Subversion repository based file is requested: 116 * it will hold the URL for the repo. 117 **/ 118 String svnRepoURL_ = ""; 119 /** This gets assigned if a Subversion repository based file is requested: 120 * it will hold the sub dir to visit to retrieve the file. */ 121 String svnDir_ = ""; 122 /** This gets assigned if a Subversion repository based file is requested: 123 * it will hold the file to retrieve. */ 124 String svnFile_ = ""; 125 /** This gets assigned if a Subversion repository based file is requested: 126 * it will hold the revision number for the file to retrieve. */ 127 String svnFileRev_ = ""; 128 /** This gets assigned if a Subversion repository based file is requested: 129 * to be gzipped. */ 130 boolean svnFileGzip_ = false; 131 /** 132 * The html header string (<head>) that is included on all folder view 133 * pages. It is the place where any javascript fuction are included. 134 */ 135 String scriptHead_ = 136 "<HEAD>\n" + 137 "<META HTTP-EQUIV=\"Content-Type\" " + 138 "CONTENT=\"text/html;CHARSET=iso-8859-1\">\n" + 139 "<META HTTP-EQUIV=\"refresh\" content=\"1;URL=" + 140 downloadUrl_ + "\">" + 141 "<TITLE>" + title_ + "</TITLE>\n" + 142 "<SCRIPT LANGUAGE=\"JavaScript\">\n" + 143 "<!-- Begin\nvar compose_window = null;\n" + 144 "function NewWindow(mypage, myname, w, h, scroll)\n{\n " + 145 " var winl = (screen.width - w) / 2;\n " + 146 " var wint = (screen.height - h) / 2;\n " + 147 " winprops = 'height='+h+',width='+w+',top='+wint+',left='+winl+'," + 148 " scrollbars='+scroll+',resizable'\n " + 149 " win = window.open('', myname, winprops)\n compose_window = win;\n " + 150 " win.document.open();\n win.document.clear;\n " + 151 " win.document.write(mypage)\n " + 152 " if (parseInt(navigator.appVersion) >= 4) {\n" + 153 " win.window.focus();\n" + 154 " }\n " + 155 "}\n\n" + 156 "// End -->\n" + 157 "</script>\n" + 158 "</HEAD>\n"; 159 160 /** Body Content. */ 161 String bodyContent_ = "<BODY>" + 162 "" + 163 "</BODY>"; 164 165 /** The default download log filename */ 166 String initDownloadLogFilename_ = DEFAULT_DOWNLOAD_LOG_FILE; 167 168 /** Description of the Field */ 169 File downloadLogFile_ = null; 170 171 /** The debug logger. */ 172 private static Log log = null; 173 // new Log(Log.CONSOLE, Log.FULL); 174 175 176 /** 177 * This method handles the "GET" submission and goes and gets the 178 * download file. 179 * 180 * @param req Description of the Parameter 181 * @param res Description of the Parameter 182 * @exception ServletException Description of the Exception 183 * @exception IOException Description of the Exception 184 */ 185 public void doGet(HttpServletRequest req, HttpServletResponse res) 186 throws ServletException, IOException 187 { 188 final String methodName = "doGet"; 189 log.startMethod(methodName); 190 // get the session 191 //HttpSession ssn = req.getSession(true); 192 ParameterParser parser = new ParameterParser(req); 193 194 String logFileName = parser.getStringParameter("logfile", DEFAULT_LOG_FILE); 195 if (log == null) 196 { 197 System.out.println("TBGDEBUG: Creating Log File:" + logFileName); 198 log = Log.createLog(Log.FULL, logFileName); 199 } 200 downloadUrl_ = parser.getStringParameter("resource", ""); 201 svnRepoURL_ = parser.getStringParameter("repo", ""); 202 svnDir_ = parser.getStringParameter("dir", ""); 203 svnFile_ = parser.getStringParameter("file", ""); 204 svnFileRev_ = parser.getStringParameter("rev", ""); 205 svnFileGzip_ = parser.getBooleanParameter("gzip", false); 206 207 log("DEBUG: DownloadLogFile: "+downloadLogFile_); 208 if (!downloadUrl_.equals("")) 209 { 210 doDownload(req, res); 211 } 212 else if (!svnRepoURL_.equals("") && 213 !svnDir_.equals("") && 214 !svnFile_.equals("")) 215 { 216 streamSVNBytes(req, res, svnFileGzip_); 217 } 218 else 219 { 220 ServletOutputStream out = res.getOutputStream(); 221 res.setContentType("text/html"); 222 out.println("<html>\n"); 223 out.println("<head>\n"); 224 out.println("<META HTTP-EQUIV=\"refresh\" content=\"2;URL=\"javascript:history.go(-2);\">\n"); 225 out.println("</head>\n"); 226 out.println("<body>\n"); 227 out.println("Incorrect Download parameters:<br />"); 228 out.println(" resource = "+downloadUrl_+"<br />"); 229 out.println(" repo = "+svnRepoURL_+"<br />"); 230 out.println(" dir = "+svnDir_+"<br />"); 231 out.println(" file = "+svnFile_+"<br />"); 232 out.println(""); 233 out.println("\n</body>\n</html>"); 234 } 235 236 log.endMethod(); 237 } 238 239 240 /** 241 * Gets the ServletInfo attribute of the JavaMailServlet object 242 * 243 * @return The ServletInfo value 244 */ 245 public String getServletInfo() 246 { 247 final String methodName = "getServletInfo"; 248 log.startMethod(methodName); 249 250 log.endMethod(); 251 return "WebARTS Design download servlet. Version:" + SERVLET_VERSION + 252 " Build:" + BUILD_TAG; 253 } 254 255 256 /** 257 * The one time servlet init stuff goes here. 258 **/ 259 public void init() 260 { 261 System.out.println("Initializing webarts.servlet.Download"); 262 263 // First get our Debug Logger running 264 String initDebugLog = getInitParameter("debugLogFilename").trim(); 265 if (initDebugLog == null || 266 initDebugLog.equals("")) 267 { 268 initDebugLog = DEFAULT_LOG_FILE; 269 } 270 if (log == null) 271 { 272 System.out.println("TBGDEBUG: Creating Log File: " + initDebugLog); 273 log = Log.createLog(Log.FULL, initDebugLog); 274 } 275 276 // Now on with the Servlet Init 277 final String methodName = "init"; 278 log.startMethod(methodName); 279 String initServer = getInitParameter("serverUrl"); 280 String initServerPort = getInitParameter("serverPort"); 281 initDownloadLogFilename_ = getInitParameter("downloadLogFilename").trim(); 282 String portNum = ""; 283 284 if (initDownloadLogFilename_ == null || 285 initDownloadLogFilename_.equals("")) 286 { 287 initDownloadLogFilename_ = DEFAULT_DOWNLOAD_LOG_FILE; 288 //downloadLogFile_ = new File(initDownloadLogFilename_); 289 } 290 if (initServerPort != null && !initServerPort.equals("")) 291 { 292 portNum = ":" + initServerPort; 293 } 294 if (initServer != null && !initServer.equals("")) 295 { 296 webServerHostName_ = initServer + portNum; 297 } 298 else 299 { 300 try 301 { 302 webServerHostName_ = InetAddress.getLocalHost().getHostName(); 303 } 304 catch (UnknownHostException ex) 305 { 306 webServerHostName_ = "localhost"; 307 } 308 } 309 310 log.debug("Download Logging File = "+initDownloadLogFilename_); 311 log.endMethod(); 312 } 313 314 315 /** Override to close the Log * */ 316 public void destroy() 317 { 318 super.destroy(); 319 final String methodName = "destroy"; 320 if (log != null) 321 { 322 log.startMethod(methodName); 323 log.endMethod(); 324 log.close(); 325 } 326 } 327 328 329 /** 330 * This method handles the "POST" submission. 331 * 332 * @param req Description of Parameter 333 * @param res Description of Parameter 334 * @exception ServletException Description of Exception 335 * @exception IOException Description of Exception 336 */ 337 public void doPost(HttpServletRequest req, HttpServletResponse res) 338 throws ServletException, IOException 339 { 340 final String methodName = "doPost"; 341 log.startMethod(methodName); 342 log.endMethod(); 343 } 344 345 346 /** 347 * This method goes and performs the actual download of a resource file. 348 * 349 * @param req Description of Parameter 350 * @param res Description of Parameter 351 * @exception ServletException Description of Exception 352 * @exception IOException Description of Exception 353 */ 354 private void doDownload(HttpServletRequest req, HttpServletResponse res) 355 throws ServletException, IOException 356 { 357 final String methodName = "doDownload"; 358 log.startMethod(methodName); 359 360 log.debug("Attempting download of " + downloadUrl_); 361 ServletOutputStream out = res.getOutputStream(); 362 res.setContentType("text/html"); 363 out.println("<html>\n"); 364 out.println(getHead()); 365 out.println(getDownloadBody()); 366 out.println("</html>"); 367 368 logTheDownload(req, downloadUrl_); 369 370 log.endMethod(); 371 } 372 373 374 /** 375 * This method goes and performs the download/streaming of the svn file. 376 * 377 * @param req Description of Parameter 378 * @param res Description of Parameter 379 * @exception ServletException Description of Exception 380 * @exception IOException Description of Exception 381 */ 382 private void streamSVNBytes(HttpServletRequest req, HttpServletResponse res, boolean compressGzip) 383 throws ServletException, IOException 384 { 385 final String methodName = "streamSVNBytes"; 386 log.startMethod(methodName); 387 388 AstroVersion astroVersion = new AstroVersion(); 389 if (!svnDir_.endsWith("/")) svnDir_ = svnDir_+"/"; 390 String svnResource = svnRepoURL_+svnDir_+svnFile_; 391 log.debug("Attempting Subversion stream of " + svnResource); 392 ServletOutputStream out = res.getOutputStream(); 393 // Get the "Accepting-Encoding" header from the HTTP request. 394 // Note that request is an HttpServletRequest instance 395 String encoding = req.getHeader("Accept-Encoding"); 396 boolean supportsGzip =false; 397 // Now, check to see if the browser supports the GZIP compression 398 if (encoding != null) 399 { 400 if (encoding.toLowerCase().indexOf("gzip") > -1) 401 supportsGzip = true; 402 } 403 java.io.OutputStream outStream = null; 404 if (compressGzip || supportsGzip) 405 { 406 outStream = new java.util.zip.GZIPOutputStream(out); 407 } 408 else 409 { 410 outStream = new BufferedOutputStream(out); 411 } 412 try 413 { 414 byte[] revCatBytes = astroVersion.getFileBytes(svnRepoURL_, 415 svnDir_+svnFile_, 416 svnFileRev_ ); 417 String mimeType = astroVersion.getMimeType(svnFile_); 418 int bytesToSend = revCatBytes.length; 419 if (compressGzip) 420 res.setContentType("application/x-gzip"); 421 else 422 { 423 if(supportsGzip) 424 res.setHeader("Content-Encoding", "gzip"); 425 res.setContentType(mimeType); 426 } 427 outStream.write(revCatBytes, 0, revCatBytes.length); 428 } 429 catch (IOException ioEx) 430 { 431 ioEx.printStackTrace(); 432 res.setContentType("text/html"); 433 out.println("<html>\n"); 434 out.println(getHead()); 435 out.println("Sorry, Problems reading the file: "+svnFile_); 436 out.println("</html>"); 437 } 438 catch (Exception ex) 439 { 440 ex.printStackTrace(); 441 res.setContentType("text/html"); 442 out.println("<html>\n"); 443 out.println(getHead()); 444 out.println("Sorry, Problems getting file info: "+svnFile_); 445 out.println("</html>"); 446 447 } 448 finally 449 { 450 if (outStream != null) outStream.close(); 451 } 452 453 logTheDownload(req, svnResource); 454 455 log.endMethod(); 456 } 457 458 459 /** 460 * Writes the log info to the file 461 * 462 * @param req Description of the Parameter 463 * @param downloadUrl Description of the Parameter 464 */ 465 private void logTheDownload(HttpServletRequest req, String downloadUrl) 466 { 467 final String methodName = "logTheDownload"; 468 log.startMethod(methodName); 469 try 470 { 471 /* 472 Sat Mar 05 21:56:30 PST 2005: svn://aurora1/open/trunk/www/astroVersion/images/barg8.png: 473 warp2.webarts.bc.ca (10.0.0.252): Host=www.webarts.bc.ca, User-Agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0, 474 */ 475 /* 476 209.89.88.215 - - [21/Feb/2005:00:00:14 -0800] "GET /favicon.ico HTTP/1.0" 404 1224 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0" 477 */ 478 // Instantiate the Log File Writer 479 FileWriter fo = new FileWriter(initDownloadLogFilename_, true); 480 481 // Get all the required client/request info that will be logged 482 java.util.Enumeration headerNamesEnum = req.getHeaderNames(); 483 String currName = ""; 484 String currIp = req.getRemoteAddr(); 485 InetAddress inetAddr = InetAddress.getByName(currIp); 486 String currHostname = inetAddr.getHostName(); 487 488 // Build the Log Entry 489 StringBuffer logEntry = new StringBuffer(); 490 logEntry.append(currIp + " - - "); 491 logEntry.append("["+(new java.util.Date()).toString() + "] "); 492 logEntry.append("\"GET "+downloadUrl + " HTTP/1.0\" 200 9999 "); 493 494 while (headerNamesEnum.hasMoreElements()) 495 { 496 currName = (String) headerNamesEnum.nextElement(); 497 if (currName.equals("User-Agent") || 498 currName.equals("Referer")) // host is also valid 499 { 500 //logEntry.append(currName); 501 //logEntry.append("="); 502 logEntry.append(" \""+req.getHeader(currName)); 503 logEntry.append("\""); 504 } 505 } 506 logEntry.append("\n"); 507 currName = logEntry.toString(); 508 fo.write(currName); 509 fo.close(); 510 fo = null; 511 } 512 catch (java.io.FileNotFoundException fnfe) 513 { 514 log.minor("Download Log File Not Found. " + initDownloadLogFilename_); 515 } 516 catch (java.io.IOException ioe) 517 { 518 log.minor("Log File IO Exception. " + initDownloadLogFilename_); 519 } 520 521 log.endMethod(); 522 } 523 524 525 /** 526 * Gets the head attribute of the Download object 527 * 528 * @return The head value 529 */ 530 private String getHead() 531 { 532 return "<HEAD>\n" + 533 "<META HTTP-EQUIV=\"Content-Type\" " + 534 "CONTENT=\"text/html;CHARSET=iso-8859-1\">\n" + 535 "<META HTTP-EQUIV=\"refresh\" content=\"1;URL=" + 536 downloadUrl_ + "\">" + 537 "<TITLE>" + title_ + "</TITLE>\n" + 538 "<SCRIPT LANGUAGE=\"JavaScript\">\n" + 539 "<!-- Begin\nvar compose_window = null;\n" + 540 "function NewWindow(mypage, myname, w, h, scroll)\n{\n " + 541 " var winl = (screen.width - w) / 2;\n " + 542 " var wint = (screen.height - h) / 2;\n " + 543 " winprops = 'height='+h+',width='+w+',top='+wint+',left='+winl+'," + 544 " scrollbars='+scroll+',resizable'\n " + 545 " win = window.open('', myname, winprops)\n compose_window = win;\n " + 546 " win.document.open();\n win.document.clear;\n " + 547 " win.document.write(mypage)\n " + 548 " if (parseInt(navigator.appVersion) >= 4) {\n" + 549 " win.window.focus();\n" + 550 " }\n " + 551 "}\n\n" + 552 "// End -->\n" + 553 "</script>\n" + 554 "</HEAD>\n"; 555 } 556 557 558 /** 559 * Gets the body attribute of the Download object 560 * 561 * @return The body value 562 */ 563 private String getDownloadBody() 564 { 565 return "<BODY>" + 566 "You should automatically start the download of the file:<BR>" + 567 "<A href=\"" + downloadUrl_ + "\">" + downloadUrl_ + "</A>" + 568 "<p><b><a href=\"javascript:history.go(-1)\">«Back to Previous Window</a>" + 569 "</b>\n</body>"; 570 } 571} 572