001/* 002 * Stallion Core: A Modern Web Framework 003 * 004 * Copyright (C) 2015 - 2016 Stallion Software LLC. 005 * 006 * This program is free software: you can redistribute it and/or modify it under the terms of the 007 * GNU General Public License as published by the Free Software Foundation, either version 2 of 008 * the License, or (at your option) any later version. This program is distributed in the hope that 009 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 011 * License for more details. You should have received a copy of the GNU General Public License 012 * along with this program. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>. 013 * 014 * 015 * 016 */ 017 018package io.stallion.requests; 019 020import static io.stallion.utils.Literals.*; 021import static io.stallion.Context.*; 022 023import java.io.*; 024import java.net.URL; 025import java.nio.charset.StandardCharsets; 026import java.nio.file.FileSystems; 027import java.nio.file.Files; 028import java.util.List; 029import java.util.Map; 030 031import io.stallion.services.Log; 032import io.stallion.utils.GeneralUtils; 033 034import javax.servlet.ServletOutputStream; 035 036/** 037 * A collection of methods for sending static assets files as a buffered servlet responses. 038 */ 039public class ServletFileSender { 040 private StResponse response; 041 private IRequest request; 042 043 public ServletFileSender(IRequest request, StResponse response) { 044 this.request = request; 045 this.response = response; 046 } 047 048 public void sendContentResponse(String content, String fullPath) { 049 sendContentResponse(content, 0, fullPath); 050 } 051 052 public void sendContentResponse(String content, long modifyTime, String fullPath) { 053 byte[] bytes = content.getBytes(StandardCharsets.UTF_8); 054 InputStream stream = new ByteArrayInputStream(bytes); 055 sendAssetResponse(stream, modifyTime, bytes.length, fullPath); 056 } 057 058 public void sendResource(URL url, String path) { 059 try { 060 int length = url.openConnection().getContentLength(); 061 sendAssetResponse(url.openStream(), 0, length, url.toString()); 062 } catch (Exception e) { 063 throw new RuntimeException(e); 064 } 065 } 066 067 068 public void sendAssetResponse(File file) { 069 try { 070 sendAssetResponse(new FileInputStream(file), file.lastModified(), file.length(), file.getAbsolutePath()); 071 } catch (FileNotFoundException e) { 072 throw new RuntimeException(e); 073 } 074 } 075 076 public void sendAssetResponse(InputStream stream, long modifyTime, long contentLength, String fullPath) { 077 try { 078 // Set the caching headers 079 Long duration = 60 * 60 * 24 * 365 * 10L; // 10 years 080 Long durationMils = duration * 1000; 081 response.addHeader("Cache-Control", "max-age=" + duration); 082 response.setDateHeader("Expires", System.currentTimeMillis() + durationMils); 083 if (modifyTime > 0) { 084 response.setDateHeader("Last-Modified", modifyTime); 085 } 086 087 // Set the Content-type 088 String contentType = GeneralUtils.guessMimeType(fullPath); 089 if (empty(contentType)) { 090 contentType = Files.probeContentType(FileSystems.getDefault().getPath(fullPath)); 091 } 092 response.setContentType(contentType); 093 094 095 Integer BUFF_SIZE = 8192; 096 if (response.getHttpServletResponse() != null) { 097 response.getHttpServletResponse().setBufferSize(BUFF_SIZE); 098 //response.getHttpServletResponse(). 099 } 100 byte[] buffer = new byte[BUFF_SIZE]; 101 ServletOutputStream os = response.getOutputStream(); 102 response.setContentLength((int) contentLength); 103 104 try { 105 int byteRead = 0; 106 int readCount = 0; 107 int totalRead = 0; 108 while (true) { 109 byteRead = stream.read(buffer); 110 if (byteRead == -1) { 111 break; 112 } 113 //totalRead += byteRead; 114 //Log.info("Bytes sent {0}", totalRead); 115 os.write(buffer, 0, byteRead); 116 } 117 //os.flush(); 118 } catch (Exception e) { 119 e.printStackTrace(); 120 } finally { 121 //os.close(); 122 stream.close(); 123 } 124 } catch (IOException e) { 125 throw new RuntimeException(e); 126 } 127 128 } 129 130 131}