1 package fi.iki.elonen; 2 3 /* 4 * #%L 5 * NanoHttpd-Core 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 static junit.framework.Assert.assertEquals; 37 38 import java.io.BufferedReader; 39 import java.io.FileReader; 40 import java.util.ArrayList; 41 import java.util.List; 42 import java.util.UUID; 43 44 import org.junit.Test; 45 46 public class HttpPostRequestTest extends HttpServerTest { 47 48 public static final String CONTENT_LENGTH = "Content-Length: "; 49 50 public static final String FIELD = "caption"; 51 52 public static final String VALUE = "Summer vacation"; 53 54 public static final String FIELD2 = "location"; 55 56 public static final String VALUE2 = "Grand Canyon"; 57 58 public static final String POST_RAW_CONTENT_FILE_ENTRY = "postData"; 59 60 public static final String VALUE_TEST_SIMPLE_RAW_DATA_WITH_AMPHASIS = "Test raw data & Result value"; 61 62 /** 63 * contains common preparation steps for testing POST with Multipart Form 64 * 65 * @param fileName 66 * Name of file to be uploaded 67 * @param fileContent 68 * Content of file to be uploaded 69 * @return input String with POST request complete information including 70 * header, length and content 71 */ 72 private String preparePostWithMultipartForm(String fileName, String fileContent) { 73 String divider = UUID.randomUUID().toString(); 74 String header = "POST " + HttpServerTest.URI + " HTTP/1.1\nContent-Type: " + "multipart/form-data, boundary=" + divider + "\r\n"; 75 String content = 76 "--" + divider + "\r\n" + "Content-Disposition: form-data; name=\"" + HttpPostRequestTest.FIELD + "\"; filename=\"" + fileName + "\"\r\n" 77 + "Content-Type: image/jpeg\r\n" + "\r\n" + fileContent + "\r\n" + "--" + divider + "--\r\n"; 78 int size = content.length() + header.length(); 79 int contentLengthHeaderValueSize = String.valueOf(size).length(); 80 int contentLength = size + contentLengthHeaderValueSize + HttpPostRequestTest.CONTENT_LENGTH.length(); 81 String input = header + HttpPostRequestTest.CONTENT_LENGTH + (contentLength + 5) + "\r\n\r\n" + content; 82 83 return input; 84 } 85 86 @Test 87 public void testPostWithMultipartFormUpload() throws Exception { 88 String filename = "GrandCanyon.txt"; 89 String fileContent = HttpPostRequestTest.VALUE; 90 String input = preparePostWithMultipartForm(filename, fileContent); 91 92 invokeServer(input); 93 94 assertEquals(1, this.testServer.parms.size()); 95 BufferedReader reader = new BufferedReader(new FileReader(this.testServer.files.get(HttpPostRequestTest.FIELD))); 96 List<String> lines = readLinesFromFile(reader); 97 assertLinesOfText(new String[]{ 98 fileContent 99 }, lines); 100 } 101 102 @Test 103 public void testPostWithMultipartFormUploadFilenameHasSpaces() throws Exception { 104 String fileNameWithSpace = "Grand Canyon.txt"; 105 String fileContent = HttpPostRequestTest.VALUE; 106 String input = preparePostWithMultipartForm(fileNameWithSpace, fileContent); 107 108 invokeServer(input); 109 110 String fileNameAfter = new ArrayList<String>(this.testServer.parms.values()).get(0); 111 112 assertEquals(fileNameWithSpace, fileNameAfter); 113 } 114 115 @Test 116 public void testPostWithMultipleMultipartFormFields() throws Exception { 117 String divider = UUID.randomUUID().toString(); 118 String header = "POST " + HttpServerTest.URI + " HTTP/1.1\nContent-Type: " + "multipart/form-data; boundary=" + divider + "\n"; 119 String content = 120 "--" + divider + "\r\n" + "Content-Disposition: form-data; name=\"" + HttpPostRequestTest.FIELD + "\"\r\n" + "\r\n" + HttpPostRequestTest.VALUE + "\r\n" 121 + "--" + divider + "\r\n" + "Content-Disposition: form-data; name=\"" + HttpPostRequestTest.FIELD2 + "\"\r\n" + "\r\n" + HttpPostRequestTest.VALUE2 122 + "\r\n" + "--" + divider + "--\r\n"; 123 int size = content.length() + header.length(); 124 int contentLengthHeaderValueSize = String.valueOf(size).length(); 125 int contentLength = size + contentLengthHeaderValueSize + HttpPostRequestTest.CONTENT_LENGTH.length(); 126 String input = header + HttpPostRequestTest.CONTENT_LENGTH + (contentLength + 4) + "\r\n\r\n" + content; 127 invokeServer(input); 128 129 assertEquals(2, this.testServer.parms.size()); 130 assertEquals(HttpPostRequestTest.VALUE, this.testServer.parms.get(HttpPostRequestTest.FIELD)); 131 assertEquals(HttpPostRequestTest.VALUE2, this.testServer.parms.get(HttpPostRequestTest.FIELD2)); 132 } 133 134 @Test 135 public void testPostWithMultipleMultipartFormFieldsWhereContentTypeWasSeparatedByComma() throws Exception { 136 String divider = UUID.randomUUID().toString(); 137 String header = "POST " + HttpServerTest.URI + " HTTP/1.1\nContent-Type: " + "multipart/form-data, boundary=" + divider + "\r\n"; 138 String content = 139 "--" + divider + "\r\n" + "Content-Disposition: form-data; name=\"" + HttpPostRequestTest.FIELD + "\"\r\n" + "\r\n" + HttpPostRequestTest.VALUE + "\r\n" 140 + "--" + divider + "\r\n" + "Content-Disposition: form-data; name=\"" + HttpPostRequestTest.FIELD2 + "\"\r\n" + "\r\n" + HttpPostRequestTest.VALUE2 141 + "\r\n" + "--" + divider + "--\r\n"; 142 int size = content.length() + header.length(); 143 int contentLengthHeaderValueSize = String.valueOf(size).length(); 144 int contentLength = size + contentLengthHeaderValueSize + HttpPostRequestTest.CONTENT_LENGTH.length(); 145 String input = header + HttpPostRequestTest.CONTENT_LENGTH + (contentLength + 4) + "\r\n\r\n" + content; 146 invokeServer(input); 147 148 assertEquals(2, this.testServer.parms.size()); 149 assertEquals(HttpPostRequestTest.VALUE, this.testServer.parms.get(HttpPostRequestTest.FIELD)); 150 assertEquals(HttpPostRequestTest.VALUE2, this.testServer.parms.get(HttpPostRequestTest.FIELD2)); 151 } 152 153 @Test 154 public void testSimplePostWithSingleMultipartFormField() throws Exception { 155 String divider = UUID.randomUUID().toString(); 156 String header = "POST " + HttpServerTest.URI + " HTTP/1.1\nContent-Type: " + "multipart/form-data; boundary=" + divider + "\r\n"; 157 String content = 158 "--" + divider + "\r\n" + "Content-Disposition: form-data; name=\"" + HttpPostRequestTest.FIELD + "\"\r\n" + "\r\n" + HttpPostRequestTest.VALUE + "\r\n" 159 + "--" + divider + "--\r\n"; 160 int size = content.length() + header.length(); 161 int contentLengthHeaderValueSize = String.valueOf(size).length(); 162 int contentLength = size + contentLengthHeaderValueSize + HttpPostRequestTest.CONTENT_LENGTH.length(); 163 String input = header + HttpPostRequestTest.CONTENT_LENGTH + (contentLength + 4) + "\r\n\r\n" + content; 164 invokeServer(input); 165 166 assertEquals(1, this.testServer.parms.size()); 167 assertEquals(HttpPostRequestTest.VALUE, this.testServer.parms.get(HttpPostRequestTest.FIELD)); 168 } 169 170 @Test 171 public void testSimpleRawPostData() throws Exception { 172 String header = "POST " + HttpServerTest.URI + " HTTP/1.1\n"; 173 String content = HttpPostRequestTest.VALUE_TEST_SIMPLE_RAW_DATA_WITH_AMPHASIS + "\r\n"; 174 int size = content.length() + header.length(); 175 int contentLengthHeaderValueSize = String.valueOf(size).length(); 176 int contentLength = size + contentLengthHeaderValueSize + HttpPostRequestTest.CONTENT_LENGTH.length(); 177 String input = header + HttpPostRequestTest.CONTENT_LENGTH + (contentLength + 4) + "\r\n\r\n" + content; 178 invokeServer(input); 179 assertEquals(0, this.testServer.parms.size()); 180 assertEquals(1, this.testServer.files.size()); 181 assertEquals(HttpPostRequestTest.VALUE_TEST_SIMPLE_RAW_DATA_WITH_AMPHASIS, this.testServer.files.get(HttpPostRequestTest.POST_RAW_CONTENT_FILE_ENTRY)); 182 } 183 184 } 185