|
@@ -1,23 +1,20 @@ |
1 |
1 |
|
// This Source Code is in the Public Domain per: http://unlicense.org |
2 |
2 |
|
package org.litesoft.servlets.filetransfer; |
3 |
3 |
|
|
4 |
|
- |
import java.io.*; |
5 |
|
- |
|
6 |
|
- |
import org.litesoft.commonfoundation.typeutils.*; |
7 |
|
- |
|
8 |
|
- |
import java.util.*; |
9 |
|
- |
import javax.servlet.*; |
10 |
|
- |
import javax.servlet.http.*; |
11 |
|
- |
|
12 |
4 |
|
import org.apache.commons.fileupload.*; |
13 |
5 |
|
import org.apache.commons.fileupload.servlet.*; |
14 |
6 |
|
import org.apache.commons.fileupload.util.*; |
|
7 |
+ |
import org.litesoft.commonfoundation.typeutils.*; |
15 |
8 |
|
import org.litesoft.filesinksource.*; |
16 |
9 |
|
import org.litesoft.logger.*; |
17 |
10 |
|
import org.litesoft.util.*; |
18 |
11 |
|
|
19 |
|
- |
public abstract class AbstractFileTransferServlet extends HttpServlet |
20 |
|
- |
{ |
|
12 |
+ |
import javax.servlet.*; |
|
13 |
+ |
import javax.servlet.http.*; |
|
14 |
+ |
import java.io.*; |
|
15 |
+ |
import java.util.*; |
|
16 |
+ |
|
|
17 |
+ |
public abstract class AbstractFileTransferServlet extends HttpServlet { |
21 |
18 |
|
private static final long serialVersionUID = 1L; |
22 |
19 |
|
|
23 |
20 |
|
protected static Logger LOGGER = LoggerFactory.getLogger( AbstractFileTransferServlet.class ); |
|
@@ -27,8 +24,7 @@ |
27 |
24 |
|
* <p/> |
28 |
25 |
|
* Otherwise, the Browser will be told to "ask" what to do with it! |
29 |
26 |
|
*/ |
30 |
|
- |
protected boolean isDirectViewContent( String pContentType ) |
31 |
|
- |
{ |
|
27 |
+ |
protected boolean isDirectViewContent( String pContentType ) { |
32 |
28 |
|
return pContentType.startsWith( "image/" ) || pContentType.startsWith( "text/" ); |
33 |
29 |
|
} |
34 |
30 |
|
|
|
@@ -37,15 +33,13 @@ |
37 |
33 |
|
* <p/> |
38 |
34 |
|
* Will only be called if isDirectViewContent( pContentType ) return false |
39 |
35 |
|
*/ |
40 |
|
- |
protected boolean isKnownContentType( String pContentType ) |
41 |
|
- |
{ |
|
36 |
+ |
protected boolean isKnownContentType( String pContentType ) { |
42 |
37 |
|
return pContentType.startsWith( "application/" ); |
43 |
38 |
|
} |
44 |
39 |
|
|
45 |
40 |
|
@Override |
46 |
41 |
|
public void init() |
47 |
|
- |
throws ServletException |
48 |
|
- |
{ |
|
42 |
+ |
throws ServletException { |
49 |
43 |
|
FileSinkAndSourceFactory.setInstance( initialize() ); |
50 |
44 |
|
} |
51 |
45 |
|
|
|
@@ -57,12 +51,10 @@ |
57 |
51 |
|
*/ |
58 |
52 |
|
@Override |
59 |
53 |
|
public void doGet( HttpServletRequest pReq, final HttpServletResponse pResp ) |
60 |
|
- |
throws ServletException, IOException |
61 |
|
- |
{ |
|
54 |
+ |
throws ServletException, IOException { |
62 |
55 |
|
String zPathInfo = pReq.getPathInfo(); |
63 |
56 |
|
String zOpaqueHandle = Strings.noEmpty( cleanFileName( zPathInfo ) ); |
64 |
|
- |
if ( zOpaqueHandle == null ) |
65 |
|
- |
{ |
|
57 |
+ |
if ( zOpaqueHandle == null ) { |
66 |
58 |
|
pResp.sendError( HttpServletResponse.SC_NOT_FOUND, "Null or zero length OpaqueHandle" ); |
67 |
59 |
|
return; |
68 |
60 |
|
} |
|
@@ -72,16 +64,13 @@ |
72 |
64 |
|
String zContentType = Strings.deNull( getServletContext().getMimeType( zFileName.toLowerCase() ) ); |
73 |
65 |
|
pResp.setContentType( zContentType ); |
74 |
66 |
|
long zSize = zFileInfo.getSize(); |
75 |
|
- |
if ( zSize < Integer.MAX_VALUE ) |
76 |
|
- |
{ |
|
67 |
+ |
if ( zSize < Integer.MAX_VALUE ) { |
77 |
68 |
|
pResp.setContentLength( (int) zSize ); |
78 |
69 |
|
} |
79 |
70 |
|
|
80 |
|
- |
if ( !isDirectViewContent( zContentType ) ) |
81 |
|
- |
{ |
|
71 |
+ |
if ( !isDirectViewContent( zContentType ) ) { |
82 |
72 |
|
pResp.setHeader( "Content-Disposition", "attachment;filename=" + zFileName ); // Only if want OS to ask disposition |
83 |
|
- |
if ( !isKnownContentType( zContentType ) ) |
84 |
|
- |
{ |
|
73 |
+ |
if ( !isKnownContentType( zContentType ) ) { |
85 |
74 |
|
LOGGER.info.log( "zName=", zFileName, " zContentType=", zContentType ); |
86 |
75 |
|
} |
87 |
76 |
|
} |
|
@@ -97,8 +86,7 @@ |
97 |
86 |
|
{ |
98 |
87 |
|
@Override |
99 |
88 |
|
public OutputStream createOutputStream() |
100 |
|
- |
throws IOException |
101 |
|
- |
{ |
|
89 |
+ |
throws IOException { |
102 |
90 |
|
return pResp.getOutputStream(); |
103 |
91 |
|
} |
104 |
92 |
|
} ); |
|
@@ -109,35 +97,28 @@ |
109 |
97 |
|
*/ |
110 |
98 |
|
@Override |
111 |
99 |
|
public void doPost( HttpServletRequest pReq, HttpServletResponse pResp ) |
112 |
|
- |
throws ServletException, IOException |
113 |
|
- |
{ |
|
100 |
+ |
throws ServletException, IOException { |
114 |
101 |
|
PrintWriter zPrintWriter = pResp.getWriter(); |
115 |
102 |
|
pResp.setContentType( "application/xml" ); |
116 |
|
- |
try |
117 |
|
- |
{ |
|
103 |
+ |
try { |
118 |
104 |
|
insureCharacterEncoding( pReq ); |
119 |
105 |
|
// Check that we have a file upload request |
120 |
|
- |
if ( ServletFileUpload.isMultipartContent( pReq ) ) |
121 |
|
- |
{ |
|
106 |
+ |
if ( ServletFileUpload.isMultipartContent( pReq ) ) { |
122 |
107 |
|
ServletFileUpload upload = new ServletFileUpload(); |
123 |
108 |
|
Map<String, String> zResults = new HashMap<String, String>(); |
124 |
109 |
|
// Parse the request |
125 |
110 |
|
FileItemIterator iter = upload.getItemIterator( pReq ); |
126 |
|
- |
while ( iter.hasNext() ) |
127 |
|
- |
{ |
|
111 |
+ |
while ( iter.hasNext() ) { |
128 |
112 |
|
FileItemStream item = iter.next(); |
129 |
113 |
|
String name = item.getFieldName(); |
130 |
|
- |
if ( !item.isFormField() ) |
131 |
|
- |
{ |
|
114 |
+ |
if ( !item.isFormField() ) { |
132 |
115 |
|
String zFileName = item.getName(); |
133 |
116 |
|
LOGGER.debug.log( "Upload file name before clean: ", zFileName ); |
134 |
117 |
|
zFileName = justFileName( zFileName ); |
135 |
118 |
|
FileSink zSink = FileSinkAndSourceFactory.getInstance().createFileSink( zFileName ); |
136 |
119 |
|
String zOpaqueHandle = zSink.put( item.openStream() ); // closes InputStream |
137 |
120 |
|
zResults.put( zFileName, zOpaqueHandle ); |
138 |
|
- |
} |
139 |
|
- |
else |
140 |
|
- |
{ |
|
121 |
+ |
} else { |
141 |
122 |
|
String zStreamAsString = Streams.asString( item.openStream() ); // closes InputStream |
142 |
123 |
|
LOGGER.warn.log( "Form field ", name, " with value ", zStreamAsString, " detected." ); |
143 |
124 |
|
} |
|
@@ -147,8 +128,7 @@ |
147 |
128 |
|
Collections.sort( zKeys ); |
148 |
129 |
|
|
149 |
130 |
|
zPrintWriter.println( "<success>" ); |
150 |
|
- |
for ( String zKey : zKeys ) |
151 |
|
- |
{ |
|
131 |
+ |
for ( String zKey : zKeys ) { |
152 |
132 |
|
String zValue = zResults.get( zKey ); |
153 |
133 |
|
zPrintWriter.println( " <file name=\"" + zKey + "\" handle=\"" + zValue + "\" />" ); |
154 |
134 |
|
} |
|
@@ -156,8 +136,7 @@ |
156 |
136 |
|
zPrintWriter.flush(); |
157 |
137 |
|
} |
158 |
138 |
|
} |
159 |
|
- |
catch ( Exception e ) |
160 |
|
- |
{ |
|
139 |
+ |
catch ( Exception e ) { |
161 |
140 |
|
LOGGER.warn.log( e ); |
162 |
141 |
|
zPrintWriter.println( "<fail>" ); |
163 |
142 |
|
String zFailOut = Throwables.printStackTraceToString( e ); |
|
@@ -169,36 +148,28 @@ |
169 |
148 |
|
} |
170 |
149 |
|
} |
171 |
150 |
|
|
172 |
|
- |
private String justFileName( String pFileName ) |
173 |
|
- |
{ |
|
151 |
+ |
private String justFileName( String pFileName ) { |
174 |
152 |
|
pFileName = "/" + cleanFileName( pFileName ); |
175 |
153 |
|
return pFileName.substring( pFileName.lastIndexOf( '/' ) + 1 ); |
176 |
154 |
|
} |
177 |
155 |
|
|
178 |
|
- |
private String cleanFileName( String pFileName ) |
179 |
|
- |
{ |
|
156 |
+ |
private String cleanFileName( String pFileName ) { |
180 |
157 |
|
pFileName = Strings.deNull( pFileName ).trim().replace( '\\', '/' ); |
181 |
|
- |
if ( (pFileName.length() >= 2) && Character.isLetter( pFileName.charAt( 0 ) ) && (':' == pFileName.charAt( 1 )) ) |
182 |
|
- |
{ |
|
158 |
+ |
if ( (pFileName.length() >= 2) && Character.isLetter( pFileName.charAt( 0 ) ) && (':' == pFileName.charAt( 1 )) ) { |
183 |
159 |
|
pFileName = pFileName.substring( 2 ).trim(); |
184 |
160 |
|
} |
185 |
|
- |
while ( pFileName.startsWith( "/" ) ) |
186 |
|
- |
{ |
|
161 |
+ |
while ( pFileName.startsWith( "/" ) ) { |
187 |
162 |
|
pFileName = pFileName.substring( 1 ).trim(); |
188 |
163 |
|
} |
189 |
164 |
|
return pFileName; |
190 |
165 |
|
} |
191 |
166 |
|
|
192 |
167 |
|
private void insureCharacterEncoding( HttpServletRequest pReq ) |
193 |
|
- |
throws UnsupportedEncodingException |
194 |
|
- |
{ |
|
168 |
+ |
throws UnsupportedEncodingException { |
195 |
169 |
|
String zEnc = pReq.getCharacterEncoding(); |
196 |
|
- |
if ( zEnc != null ) |
197 |
|
- |
{ |
|
170 |
+ |
if ( zEnc != null ) { |
198 |
171 |
|
LOGGER.debug.log( zEnc, " = pReq.getCharacterEncoding();" ); |
199 |
|
- |
} |
200 |
|
- |
else |
201 |
|
- |
{ |
|
172 |
+ |
} else { |
202 |
173 |
|
LOGGER.debug.log( "pReq.setCharacterEncoding( \"", FileUtils.UTF_8, "\" );" ); |
203 |
174 |
|
pReq.setCharacterEncoding( FileUtils.UTF_8 ); |
204 |
175 |
|
} |
|
@@ -210,8 +181,7 @@ |
210 |
181 |
|
* @return String describing this servlet. |
211 |
182 |
|
*/ |
212 |
183 |
|
@Override |
213 |
|
- |
public String getServletInfo() |
214 |
|
- |
{ |
|
184 |
+ |
public String getServletInfo() { |
215 |
185 |
|
return "File transfer servlet -- used to receive and send files"; |
216 |
186 |
|
} |
217 |
187 |
|
} |