• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package fi.iki.elonen;
2 
3 /*
4  * #%L
5  * NanoHttpd-apache file upload integration
6  * %%
7  * Copyright (C) 2012 - 2015 nanohttpd
8  * %%
9  * Redistribution and use in source and binary forms, with or without modification,
10  * are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice, this
13  *    list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  *    this list of conditions and the following disclaimer in the documentation
17  *    and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the nanohttpd nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software without
21  *    specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
32  * OF THE POSSIBILITY OF SUCH DAMAGE.
33  * #L%
34  */
35 
36 import java.io.File;
37 import java.io.IOException;
38 import java.io.InputStream;
39 import java.io.OutputStream;
40 import java.net.InetAddress;
41 import java.util.Arrays;
42 import java.util.HashMap;
43 import java.util.List;
44 import java.util.Map;
45 
46 import org.apache.commons.fileupload.FileItem;
47 import org.apache.commons.fileupload.FileItemIterator;
48 import org.apache.commons.fileupload.FileItemStream;
49 import org.apache.commons.fileupload.FileUploadException;
50 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
51 import org.apache.commons.fileupload.util.Streams;
52 import org.apache.http.HttpEntity;
53 import org.apache.http.HttpResponse;
54 import org.apache.http.client.ClientProtocolException;
55 import org.apache.http.client.methods.CloseableHttpResponse;
56 import org.apache.http.client.methods.HttpPost;
57 import org.apache.http.client.methods.HttpTrace;
58 import org.apache.http.entity.ContentType;
59 import org.apache.http.entity.mime.HttpMultipartMode;
60 import org.apache.http.entity.mime.MultipartEntityBuilder;
61 import org.apache.http.entity.mime.content.FileBody;
62 import org.apache.http.entity.mime.content.StringBody;
63 import org.apache.http.impl.client.CloseableHttpClient;
64 import org.apache.http.impl.client.HttpClients;
65 import org.junit.After;
66 import org.junit.Assert;
67 import org.junit.Before;
68 import org.junit.FixMethodOrder;
69 import org.junit.Test;
70 import org.junit.internal.runners.statements.Fail;
71 
72 import fi.iki.elonen.NanoHTTPD.Response.Status;
73 
74 /**
75  * very strange but if the file upload is the first request the test fails.
76  *
77  * @author ritchieGitHub
78  */
79 @FixMethodOrder
80 public class TestNanoFileUpLoad {
81 
82     protected TestServer testServer;
83 
84     public static class TestServer extends NanoHTTPD {
85 
86         public Response response = newFixedLengthResponse("");
87 
88         public String uri;
89 
90         public Method method;
91 
92         public Map<String, String> header;
93 
94         public Map<String, String> parms;
95 
96         public Map<String, List<FileItem>> files;
97 
98         public Map<String, List<String>> decodedParamters;
99 
100         public Map<String, List<String>> decodedParamtersFromParameter;
101 
102         public String queryParameterString;
103 
TestServer()104         public TestServer() {
105             super(8192);
106             uploader = new NanoFileUpload(new DiskFileItemFactory());
107         }
108 
createSession(TempFileManager tempFileManager, InputStream inputStream, OutputStream outputStream)109         public HTTPSession createSession(TempFileManager tempFileManager, InputStream inputStream, OutputStream outputStream) {
110             return new HTTPSession(tempFileManager, inputStream, outputStream);
111         }
112 
createSession(TempFileManager tempFileManager, InputStream inputStream, OutputStream outputStream, InetAddress inetAddress)113         public HTTPSession createSession(TempFileManager tempFileManager, InputStream inputStream, OutputStream outputStream, InetAddress inetAddress) {
114             return new HTTPSession(tempFileManager, inputStream, outputStream, inetAddress);
115         }
116 
117         NanoFileUpload uploader;
118 
119         @Override
serve(IHTTPSession session)120         public Response serve(IHTTPSession session) {
121 
122             this.uri = session.getUri();
123             this.method = session.getMethod();
124             this.header = session.getHeaders();
125             this.parms = session.getParms();
126             if (NanoFileUpload.isMultipartContent(session)) {
127                 try {
128                     if ("/uploadFile1".equals(this.uri)) {
129                         session.getHeaders().put("content-length", "AA");
130                         files = uploader.parseParameterMap(session);
131                     }
132                     if ("/uploadFile2".equals(this.uri)) {
133                         files = new HashMap<String, List<FileItem>>();
134                         List<FileItem> parseRequest = uploader.parseRequest(session);
135                         files.put(parseRequest.get(0).getFieldName(), parseRequest);
136                     }
137                     if ("/uploadFile3".equals(this.uri)) {
138                         files = new HashMap<String, List<FileItem>>();
139                         FileItemIterator iter = uploader.getItemIterator(session);
140                         while (iter.hasNext()) {
141                             FileItemStream item = iter.next();
142                             final String fileName = item.getName();
143                             FileItem fileItem = uploader.getFileItemFactory().createItem(item.getFieldName(), item.getContentType(), item.isFormField(), fileName);
144                             files.put(fileItem.getFieldName(), Arrays.asList(new FileItem[]{
145                                 fileItem
146                             }));
147                             try {
148                                 Streams.copy(item.openStream(), fileItem.getOutputStream(), true);
149                             } catch (Exception e) {
150                             }
151                             fileItem.setHeaders(item.getHeaders());
152                         }
153                     }
154                 } catch (Exception e) {
155                     this.response.setStatus(Status.INTERNAL_ERROR);
156                     e.printStackTrace();
157                 }
158             }
159             this.queryParameterString = session.getQueryParameterString();
160             this.decodedParamtersFromParameter = decodeParameters(this.queryParameterString);
161             this.decodedParamters = decodeParameters(session.getQueryParameterString());
162             return this.response;
163         }
164 
165     }
166 
167     @Test
testNormalRequest()168     public void testNormalRequest() throws Exception {
169         CloseableHttpClient httpclient = HttpClients.createDefault();
170         HttpTrace httphead = new HttpTrace("http://localhost:8192/index.html");
171         CloseableHttpResponse response = httpclient.execute(httphead);
172         Assert.assertEquals(200, response.getStatusLine().getStatusCode());
173         response.close();
174     }
175 
176     @Test
testPostWithMultipartFormUpload1()177     public void testPostWithMultipartFormUpload1() throws Exception {
178         CloseableHttpClient httpclient = HttpClients.createDefault();
179         String textFileName = "src/test/java/fi/iki/elonen/TestNanoFileUpLoad.java";
180         HttpPost post = new HttpPost("http://localhost:8192/uploadFile1");
181 
182         executeUpload(httpclient, textFileName, post);
183         FileItem file = this.testServer.files.get("upfile").get(0);
184         Assert.assertEquals(file.getSize(), new File(textFileName).length());
185     }
186 
187     @Test
testPostWithMultipartFormUpload2()188     public void testPostWithMultipartFormUpload2() throws Exception {
189         CloseableHttpClient httpclient = HttpClients.createDefault();
190         String textFileName = "src/test/java/fi/iki/elonen/TestNanoFileUpLoad.java";
191         HttpPost post = new HttpPost("http://localhost:8192/uploadFile2");
192 
193         executeUpload(httpclient, textFileName, post);
194         FileItem file = this.testServer.files.get("upfile").get(0);
195         Assert.assertEquals(file.getSize(), new File(textFileName).length());
196     }
197 
198     @Test
testPostWithMultipartFormUpload3()199     public void testPostWithMultipartFormUpload3() throws Exception {
200         CloseableHttpClient httpclient = HttpClients.createDefault();
201         String textFileName = "src/test/java/fi/iki/elonen/TestNanoFileUpLoad.java";
202         HttpPost post = new HttpPost("http://localhost:8192/uploadFile3");
203 
204         executeUpload(httpclient, textFileName, post);
205         FileItem file = this.testServer.files.get("upfile").get(0);
206         Assert.assertEquals(file.getSize(), new File(textFileName).length());
207     }
208 
executeUpload(CloseableHttpClient httpclient, String textFileName, HttpPost post)209     private void executeUpload(CloseableHttpClient httpclient, String textFileName, HttpPost post) throws IOException, ClientProtocolException {
210         FileBody fileBody = new FileBody(new File(textFileName), ContentType.DEFAULT_BINARY);
211         StringBody stringBody1 = new StringBody("Message 1", ContentType.MULTIPART_FORM_DATA);
212 
213         MultipartEntityBuilder builder = MultipartEntityBuilder.create();
214         builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
215         builder.addPart("upfile", fileBody);
216         builder.addPart("text1", stringBody1);
217         HttpEntity entity = builder.build();
218         //
219         post.setEntity(entity);
220         HttpResponse response = httpclient.execute(post);
221         Assert.assertEquals(200, response.getStatusLine().getStatusCode());
222     }
223 
224     @Before
setUp()225     public void setUp() throws IOException {
226         this.testServer = new TestServer();
227         this.testServer.start();
228         try {
229             long start = System.currentTimeMillis();
230             Thread.sleep(100L);
231             while (!this.testServer.wasStarted()) {
232                 Thread.sleep(100L);
233                 if (System.currentTimeMillis() - start > 2000) {
234                     Assert.fail("could not start server");
235                 }
236             }
237         } catch (InterruptedException e) {
238         }
239     }
240 
241     @After
tearDown()242     public void tearDown() {
243         this.testServer.stop();
244     }
245 
246 }
247