|
@@ -1,14 +1,13 @@ |
1 |
1 |
|
package org.litesoft.sandbox.csapp.server; |
2 |
2 |
|
|
3 |
|
- |
import java.io.*; |
4 |
|
- |
import javax.servlet.*; |
5 |
|
- |
import javax.servlet.http.*; |
6 |
|
- |
|
7 |
3 |
|
import org.apache.commons.fileupload.*; |
8 |
4 |
|
import org.apache.commons.fileupload.servlet.*; |
9 |
5 |
|
|
10 |
|
- |
public class UploadSmallFileReflectorServlet extends HttpServlet |
11 |
|
- |
{ |
|
6 |
+ |
import javax.servlet.*; |
|
7 |
+ |
import javax.servlet.http.*; |
|
8 |
+ |
import java.io.*; |
|
9 |
+ |
|
|
10 |
+ |
public class UploadSmallFileReflectorServlet extends HttpServlet { |
12 |
11 |
|
private static int secsToWait = 0; |
13 |
12 |
|
|
14 |
13 |
|
private static final long serialVersionUID = 1L; |
|
@@ -26,19 +25,16 @@ |
26 |
25 |
|
*/ |
27 |
26 |
|
@Override |
28 |
27 |
|
public void doPost( HttpServletRequest request, HttpServletResponse response ) |
29 |
|
- |
throws ServletException, IOException |
30 |
|
- |
{ |
|
28 |
+ |
throws ServletException, IOException { |
31 |
29 |
|
PrintWriter zPrintWriter = response.getWriter(); |
32 |
30 |
|
response.setContentType( "text/html" ); |
33 |
|
- |
try |
34 |
|
- |
{ |
|
31 |
+ |
try { |
35 |
32 |
|
insureCharacterEncoding( request ); |
36 |
33 |
|
|
37 |
34 |
|
SmallFileValidator.AcceptedResult results = parse( request ); |
38 |
35 |
|
|
39 |
36 |
|
int toWait = secsToWait; |
40 |
|
- |
switch ( secsToWait ) |
41 |
|
- |
{ |
|
37 |
+ |
switch ( secsToWait ) { |
42 |
38 |
|
case 0: |
43 |
39 |
|
secsToWait = 1; |
44 |
40 |
|
break; |
|
@@ -61,26 +57,22 @@ |
61 |
57 |
|
secsToWait = 0; |
62 |
58 |
|
break; |
63 |
59 |
|
} |
64 |
|
- |
System.out.println("Waiting: " + toWait); |
65 |
|
- |
if ( toWait != 0 ) |
66 |
|
- |
{ |
|
60 |
+ |
System.out.println( "Waiting: " + toWait ); |
|
61 |
+ |
if ( toWait != 0 ) { |
67 |
62 |
|
Thread.sleep( 1000 * toWait ); |
68 |
63 |
|
} |
69 |
64 |
|
|
70 |
65 |
|
reflectSuccess( zPrintWriter, results ); |
71 |
66 |
|
} |
72 |
|
- |
catch ( Exception e ) |
73 |
|
- |
{ |
|
67 |
+ |
catch ( Exception e ) { |
74 |
68 |
|
reflectError( zPrintWriter, e ); |
75 |
69 |
|
} |
76 |
|
- |
finally |
77 |
|
- |
{ |
|
70 |
+ |
finally { |
78 |
71 |
|
zPrintWriter.flush(); |
79 |
72 |
|
} |
80 |
73 |
|
} |
81 |
74 |
|
|
82 |
|
- |
private void reflectSuccess( PrintWriter writer, SmallFileValidator.AcceptedResult results ) |
83 |
|
- |
{ |
|
75 |
+ |
private void reflectSuccess( PrintWriter writer, SmallFileValidator.AcceptedResult results ) { |
84 |
76 |
|
String space = determineSeparator( SPACE_OPTIONS, 1, results.getFileName(), results.getDisplayText(), results.getEncodedContents() ); |
85 |
77 |
|
String newLine = determineSeparator( NEWLINE_OPTIONS, 1, results.getFileName(), results.getDisplayText(), results.getEncodedContents() ); |
86 |
78 |
|
String separator = determineSeparator( SEPARATOR_OPTIONS, 8, results.getFileName(), results.getDisplayText(), results.getEncodedContents() ); |
|
@@ -93,14 +85,11 @@ |
93 |
85 |
|
writer.println( separator ); |
94 |
86 |
|
} |
95 |
87 |
|
|
96 |
|
- |
private String encodeSpacesAndNewLinesAndEscapeHtml( String text, String space, String newLine ) |
97 |
|
- |
{ |
|
88 |
+ |
private String encodeSpacesAndNewLinesAndEscapeHtml( String text, String space, String newLine ) { |
98 |
89 |
|
StringBuilder sb = new StringBuilder(); |
99 |
|
- |
for ( int i = 0; i < text.length(); i++ ) |
100 |
|
- |
{ |
|
90 |
+ |
for ( int i = 0; i < text.length(); i++ ) { |
101 |
91 |
|
char c = text.charAt( i ); |
102 |
|
- |
switch ( c ) |
103 |
|
- |
{ |
|
92 |
+ |
switch ( c ) { |
104 |
93 |
|
case ' ': |
105 |
94 |
|
sb.append( space ); |
106 |
95 |
|
break; |
|
@@ -120,12 +109,9 @@ |
120 |
109 |
|
sb.append( """ ); |
121 |
110 |
|
break; |
122 |
111 |
|
default: |
123 |
|
- |
if ( (' ' < c) && (c <= 126) ) |
124 |
|
- |
{ |
|
112 |
+ |
if ( (' ' < c) && (c <= 126) ) { |
125 |
113 |
|
sb.append( c ); |
126 |
|
- |
} |
127 |
|
- |
else |
128 |
|
- |
{ |
|
114 |
+ |
} else { |
129 |
115 |
|
sb.append( "&#" ).append( (int) c ).append( ';' ); |
130 |
116 |
|
} |
131 |
117 |
|
break; |
|
@@ -134,103 +120,82 @@ |
134 |
120 |
|
return sb.toString(); |
135 |
121 |
|
} |
136 |
122 |
|
|
137 |
|
- |
private void reflectError( PrintWriter writer, Exception exception ) |
138 |
|
- |
{ |
|
123 |
+ |
private void reflectError( PrintWriter writer, Exception exception ) { |
139 |
124 |
|
// LOGGER.warn.log( exception ); |
140 |
125 |
|
writer.println( "Internal Error: " + exception.getMessage() ); |
141 |
126 |
|
exception.printStackTrace( writer ); |
142 |
127 |
|
} |
143 |
128 |
|
|
144 |
129 |
|
private SmallFileValidator.AcceptedResult parse( HttpServletRequest request ) |
145 |
|
- |
throws IOException, FileUploadException |
146 |
|
- |
{ |
|
130 |
+ |
throws IOException, FileUploadException { |
147 |
131 |
|
// Check that we have a file upload request |
148 |
|
- |
if ( !ServletFileUpload.isMultipartContent( request ) ) |
149 |
|
- |
{ |
|
132 |
+ |
if ( !ServletFileUpload.isMultipartContent( request ) ) { |
150 |
133 |
|
throw new UnsupportedOperationException( "Not Multipart Content" ); |
151 |
134 |
|
} |
152 |
135 |
|
|
153 |
136 |
|
FileNameDataPair results = null; |
154 |
137 |
|
|
155 |
138 |
|
// Parse the request |
156 |
|
- |
for ( FileItemIterator iterator = new ServletFileUpload().getItemIterator( request ); iterator.hasNext(); ) |
157 |
|
- |
{ |
|
139 |
+ |
for ( FileItemIterator iterator = new ServletFileUpload().getItemIterator( request ); iterator.hasNext(); ) { |
158 |
140 |
|
FileItemStream item = iterator.next(); |
159 |
|
- |
if ( item.isFormField() ) |
160 |
|
- |
{ |
|
141 |
+ |
if ( item.isFormField() ) { |
161 |
142 |
|
throw new UnsupportedOperationException( "Form Fields Not Supported" ); |
162 |
143 |
|
// LOGGER.warn.log( "Form field ", item.getFieldName(), " detected." ); |
163 |
144 |
|
} |
164 |
145 |
|
String fileName = item.getName(); |
165 |
146 |
|
// LOGGER.debug.log( "Upload file name before clean: ", fileName ); |
166 |
147 |
|
fileName = justFileName( fileName ); |
167 |
|
- |
if ( results != null ) |
168 |
|
- |
{ |
|
148 |
+ |
if ( results != null ) { |
169 |
149 |
|
throw new UnsupportedOperationException( "Expected One File, but found Two '" + results.getName() + "' AND '" + fileName + "'" ); |
170 |
150 |
|
} |
171 |
151 |
|
results = new FileNameDataPair( fileName, item.openStream() ); // closes InputStream |
172 |
152 |
|
} |
173 |
|
- |
if ( results == null ) |
174 |
|
- |
{ |
|
153 |
+ |
if ( results == null ) { |
175 |
154 |
|
throw new UnsupportedOperationException( "Expected One File, but None Found" ); |
176 |
155 |
|
} |
177 |
156 |
|
return validator.validate( results.getName(), results.getData() ); |
178 |
157 |
|
} |
179 |
158 |
|
|
180 |
|
- |
private String justFileName( String fileName ) |
181 |
|
- |
{ |
|
159 |
+ |
private String justFileName( String fileName ) { |
182 |
160 |
|
fileName = "/" + cleanFileName( fileName ); |
183 |
161 |
|
return fileName.substring( fileName.lastIndexOf( '/' ) + 1 ); |
184 |
162 |
|
} |
185 |
163 |
|
|
186 |
|
- |
private String cleanFileName( String fileName ) |
187 |
|
- |
{ |
|
164 |
+ |
private String cleanFileName( String fileName ) { |
188 |
165 |
|
fileName = deNull( fileName ).trim().replace( '\\', '/' ); |
189 |
|
- |
if ( (fileName.length() >= 2) && Character.isLetter( fileName.charAt( 0 ) ) && (':' == fileName.charAt( 1 )) ) |
190 |
|
- |
{ |
|
166 |
+ |
if ( (fileName.length() >= 2) && Character.isLetter( fileName.charAt( 0 ) ) && (':' == fileName.charAt( 1 )) ) { |
191 |
167 |
|
fileName = fileName.substring( 2 ).trim(); |
192 |
168 |
|
} |
193 |
|
- |
while ( fileName.startsWith( "/" ) ) |
194 |
|
- |
{ |
|
169 |
+ |
while ( fileName.startsWith( "/" ) ) { |
195 |
170 |
|
fileName = fileName.substring( 1 ).trim(); |
196 |
171 |
|
} |
197 |
172 |
|
return fileName; |
198 |
173 |
|
} |
199 |
174 |
|
|
200 |
|
- |
private String determineSeparator( char[] options, int lengthFactor, String data1, String data2, String data3 ) |
201 |
|
- |
{ |
202 |
|
- |
for ( int blockSize = lengthFactor; true; blockSize += lengthFactor ) |
203 |
|
- |
{ |
204 |
|
- |
for ( char option : options ) |
205 |
|
- |
{ |
|
175 |
+ |
private String determineSeparator( char[] options, int lengthFactor, String data1, String data2, String data3 ) { |
|
176 |
+ |
for ( int blockSize = lengthFactor; true; blockSize += lengthFactor ) { |
|
177 |
+ |
for ( char option : options ) { |
206 |
178 |
|
StringBuilder sb = new StringBuilder( blockSize ); |
207 |
|
- |
for ( int i = 0; i < blockSize; i++ ) |
208 |
|
- |
{ |
|
179 |
+ |
for ( int i = 0; i < blockSize; i++ ) { |
209 |
180 |
|
sb.append( option ); |
210 |
181 |
|
} |
211 |
|
- |
if ( !data1.contains( sb ) && !data2.contains( sb ) && !data3.contains( sb ) ) |
212 |
|
- |
{ |
|
182 |
+ |
if ( !data1.contains( sb ) && !data2.contains( sb ) && !data3.contains( sb ) ) { |
213 |
183 |
|
return sb.toString(); // The Separator we'll use |
214 |
184 |
|
} |
215 |
185 |
|
} |
216 |
186 |
|
} |
217 |
187 |
|
} |
218 |
188 |
|
|
219 |
|
- |
private String deNull( String string ) |
220 |
|
- |
{ |
|
189 |
+ |
private String deNull( String string ) { |
221 |
190 |
|
return (string != null) ? string : ""; |
222 |
191 |
|
} |
223 |
192 |
|
|
224 |
193 |
|
private void insureCharacterEncoding( HttpServletRequest request ) |
225 |
|
- |
throws UnsupportedEncodingException |
226 |
|
- |
{ |
|
194 |
+ |
throws UnsupportedEncodingException { |
227 |
195 |
|
String encoding = request.getCharacterEncoding(); |
228 |
|
- |
if ( encoding == null ) |
229 |
|
- |
{ |
|
196 |
+ |
if ( encoding == null ) { |
230 |
197 |
|
request.setCharacterEncoding( "UTF-8" ); |
231 |
|
- |
} |
232 |
|
- |
else if ( !"UTF-8".equalsIgnoreCase( encoding ) ) |
233 |
|
- |
{ |
|
198 |
+ |
} else if ( !"UTF-8".equalsIgnoreCase( encoding ) ) { |
234 |
199 |
|
System.out.println( "UploadSmallFileReflectorServlet.insureCharacterEncoding: " + encoding ); |
235 |
200 |
|
// LOGGER.debug.log( encoding, " = request.getCharacterEncoding();" ); |
236 |
201 |
|
} |
|
@@ -242,61 +207,48 @@ |
242 |
207 |
|
* @return String describing this servlet. |
243 |
208 |
|
*/ |
244 |
209 |
|
@Override |
245 |
|
- |
public String getServletInfo() |
246 |
|
- |
{ |
|
210 |
+ |
public String getServletInfo() { |
247 |
211 |
|
return "Upload Small File Reflector servlet -- used to reflect a small file back to the Browser"; |
248 |
212 |
|
} |
249 |
213 |
|
|
250 |
|
- |
private static class FileNameDataPair |
251 |
|
- |
{ |
|
214 |
+ |
private static class FileNameDataPair { |
252 |
215 |
|
private String name; |
253 |
216 |
|
private byte[] data; |
254 |
217 |
|
|
255 |
218 |
|
public FileNameDataPair( String name, InputStream is ) |
256 |
|
- |
throws IOException |
257 |
|
- |
{ |
|
219 |
+ |
throws IOException { |
258 |
220 |
|
this.name = name; |
259 |
221 |
|
data = capture( is ); |
260 |
222 |
|
} |
261 |
223 |
|
|
262 |
|
- |
public String getName() |
263 |
|
- |
{ |
|
224 |
+ |
public String getName() { |
264 |
225 |
|
return name; |
265 |
226 |
|
} |
266 |
227 |
|
|
267 |
|
- |
public byte[] getData() |
268 |
|
- |
{ |
|
228 |
+ |
public byte[] getData() { |
269 |
229 |
|
return data; |
270 |
230 |
|
} |
271 |
231 |
|
|
272 |
232 |
|
private byte[] capture( InputStream is ) |
273 |
|
- |
throws IOException |
274 |
|
- |
{ |
|
233 |
+ |
throws IOException { |
275 |
234 |
|
int maxRemaining = MAX_FILE_SIZE; |
276 |
235 |
|
ByteArrayOutputStream os = new ByteArrayOutputStream( maxRemaining ); |
277 |
|
- |
try |
278 |
|
- |
{ |
|
236 |
+ |
try { |
279 |
237 |
|
byte[] buffer = new byte[4096]; |
280 |
|
- |
for ( int bytesRead; -1 != (bytesRead = is.read( buffer )); ) |
281 |
|
- |
{ |
282 |
|
- |
if ( bytesRead > 0 ) |
283 |
|
- |
{ |
284 |
|
- |
if ( (maxRemaining -= bytesRead) < 0 ) |
285 |
|
- |
{ |
|
238 |
+ |
for ( int bytesRead; -1 != (bytesRead = is.read( buffer )); ) { |
|
239 |
+ |
if ( bytesRead > 0 ) { |
|
240 |
+ |
if ( (maxRemaining -= bytesRead) < 0 ) { |
286 |
241 |
|
throw new UnsupportedOperationException( "File Too Large - Byte Count Exceeded: " + MAX_FILE_SIZE ); |
287 |
242 |
|
} |
288 |
243 |
|
os.write( buffer, 0, bytesRead ); |
289 |
244 |
|
} |
290 |
245 |
|
} |
291 |
246 |
|
} |
292 |
|
- |
finally |
293 |
|
- |
{ |
294 |
|
- |
try |
295 |
|
- |
{ |
|
247 |
+ |
finally { |
|
248 |
+ |
try { |
296 |
249 |
|
is.close(); |
297 |
250 |
|
} |
298 |
|
- |
catch ( IOException e ) |
299 |
|
- |
{ |
|
251 |
+ |
catch ( IOException e ) { |
300 |
252 |
|
// Whatever |
301 |
253 |
|
} |
302 |
254 |
|
} |
|
@@ -306,17 +258,13 @@ |
306 |
258 |
|
} |
307 |
259 |
|
} |
308 |
260 |
|
|
309 |
|
- |
protected void validate( String pData ) |
310 |
|
- |
{ |
311 |
|
- |
for ( int i = 0; i < pData.length(); i++ ) |
312 |
|
- |
{ |
|
261 |
+ |
protected void validate( String pData ) { |
|
262 |
+ |
for ( int i = 0; i < pData.length(); i++ ) { |
313 |
263 |
|
char c = pData.charAt( i ); |
314 |
|
- |
if ( (' ' <= c) && (c <= 126) ) |
315 |
|
- |
{ |
|
264 |
+ |
if ( (' ' <= c) && (c <= 126) ) { |
316 |
265 |
|
continue; |
317 |
266 |
|
} |
318 |
|
- |
if ( c == '\r' || c == '\n' ) |
319 |
|
- |
{ |
|
267 |
+ |
if ( c == '\r' || c == '\n' ) { |
320 |
268 |
|
continue; |
321 |
269 |
|
} |
322 |
270 |
|
throw new UnsupportedOperationException( "Only Supporting a limited subset of 7-bit Ascii" ); |