|
23 | 23 | import io.netty.handler.codec.http.HttpHeaderValues; |
24 | 24 | import io.netty.handler.codec.http.HttpMethod; |
25 | 25 | import io.netty.handler.codec.http.HttpVersion; |
| 26 | +import io.netty.handler.codec.http.multipart.Attribute; |
26 | 27 | import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory; |
| 28 | +import io.netty.handler.codec.http.multipart.FileUpload; |
27 | 29 | import io.netty.handler.codec.http.multipart.HttpDataFactory; |
| 30 | +import io.netty.handler.codec.http.multipart.InterfaceHttpData; |
28 | 31 | import org.junit.jupiter.api.AfterEach; |
29 | 32 | import org.junit.jupiter.api.BeforeEach; |
30 | 33 | import org.junit.jupiter.api.Test; |
31 | 34 | import org.junit.jupiter.params.ParameterizedClass; |
32 | 35 | import org.junit.jupiter.params.provider.ValueSource; |
33 | 36 |
|
| 37 | +import java.io.IOException; |
34 | 38 | import java.nio.charset.StandardCharsets; |
35 | 39 |
|
36 | 40 | import static org.junit.jupiter.api.Assertions.assertEquals; |
| 41 | +import static org.junit.jupiter.api.Assertions.assertInstanceOf; |
37 | 42 |
|
38 | 43 | @ParameterizedClass |
39 | 44 | @ValueSource(booleans = {false, true}) |
@@ -78,4 +83,88 @@ void useFieldCharsetForDelimiterSearch() { |
78 | 83 | decoder.destroy(); |
79 | 84 | } |
80 | 85 | } |
| 86 | + |
| 87 | + private HttpPostRequestDecoder legacyHeaderSplittingDecoder(String body) { |
| 88 | + HttpPostRequestDecoder.Builder builder = HttpPostRequestDecoder.builder().dataFactory(dataFactory); |
| 89 | + if (quirk) { |
| 90 | + builder.enableQuirks(DecoderQuirk.LEGACY_HEADER_SPLITTING); |
| 91 | + } |
| 92 | + return builder.build(fullRequest("a", body)); |
| 93 | + } |
| 94 | + |
| 95 | + @Test |
| 96 | + void contentTypeNameParameterDoesNotOverrideFieldName() { |
| 97 | + HttpPostRequestDecoder decoder = legacyHeaderSplittingDecoder("--a\r\n" + |
| 98 | + "Content-Disposition: form-data; name=\"file\"; filename=\"real.pdf\"\r\n" + |
| 99 | + "Content-Type: application/pdf; name=\"x.pdf\"\r\n" + |
| 100 | + "\r\n" + |
| 101 | + "v\r\n" + |
| 102 | + "--a--\r\n"); |
| 103 | + try { |
| 104 | + FileUpload upload = assertInstanceOf(FileUpload.class, decoder.getBodyHttpDatas().get(0)); |
| 105 | + assertEquals(quirk ? "x.pdf" : "file", upload.getName()); |
| 106 | + assertEquals("real.pdf", upload.getFilename()); |
| 107 | + assertEquals("application/pdf", upload.getContentType()); |
| 108 | + } finally { |
| 109 | + decoder.destroy(); |
| 110 | + } |
| 111 | + } |
| 112 | + |
| 113 | + @Test |
| 114 | + void contentTypeFilenameParameterDoesNotOverrideFilename() { |
| 115 | + HttpPostRequestDecoder decoder = legacyHeaderSplittingDecoder("--a\r\n" + |
| 116 | + "Content-Disposition: form-data; name=\"file\"; filename=\"real.pdf\"\r\n" + |
| 117 | + "Content-Type: application/pdf; filename=\"x.pdf\"\r\n" + |
| 118 | + "\r\n" + |
| 119 | + "v\r\n" + |
| 120 | + "--a--\r\n"); |
| 121 | + try { |
| 122 | + FileUpload upload = assertInstanceOf(FileUpload.class, decoder.getBodyHttpDatas().get(0)); |
| 123 | + assertEquals("file", upload.getName()); |
| 124 | + assertEquals(quirk ? "x.pdf" : "real.pdf", upload.getFilename()); |
| 125 | + } finally { |
| 126 | + decoder.destroy(); |
| 127 | + } |
| 128 | + } |
| 129 | + |
| 130 | + @Test |
| 131 | + void contentTypeFilenameParameterDoesNotTurnFieldIntoFileUpload() throws IOException { |
| 132 | + HttpPostRequestDecoder decoder = legacyHeaderSplittingDecoder("--a\r\n" + |
| 133 | + "Content-Disposition: form-data; name=\"field\"\r\n" + |
| 134 | + "Content-Type: text/plain; filename=\"x.pdf\"; charset=UTF-8\r\n" + |
| 135 | + "\r\n" + |
| 136 | + "v\r\n" + |
| 137 | + "--a--\r\n"); |
| 138 | + try { |
| 139 | + InterfaceHttpData data = decoder.getBodyHttpDatas().get(0); |
| 140 | + assertEquals("field", data.getName()); |
| 141 | + if (quirk) { |
| 142 | + assertEquals("x.pdf", assertInstanceOf(FileUpload.class, data).getFilename()); |
| 143 | + } else { |
| 144 | + Attribute attribute = assertInstanceOf(Attribute.class, data); |
| 145 | + assertEquals("v", attribute.getValue()); |
| 146 | + assertEquals(StandardCharsets.UTF_8, attribute.getCharset()); |
| 147 | + } |
| 148 | + } finally { |
| 149 | + decoder.destroy(); |
| 150 | + } |
| 151 | + } |
| 152 | + |
| 153 | + @Test |
| 154 | + void contentTypeContentLengthParameterDoesNotOverrideLength() throws IOException { |
| 155 | + HttpPostRequestDecoder decoder = legacyHeaderSplittingDecoder("--a\r\n" + |
| 156 | + "Content-Disposition: form-data; name=\"field\"\r\n" + |
| 157 | + "Content-Type: text/plain; content-length=100\r\n" + |
| 158 | + "\r\n" + |
| 159 | + "value\r\n" + |
| 160 | + "--a--\r\n"); |
| 161 | + try { |
| 162 | + Attribute attribute = assertInstanceOf(Attribute.class, decoder.getBodyHttpDatas().get(0)); |
| 163 | + assertEquals("field", attribute.getName()); |
| 164 | + assertEquals("value", attribute.getValue()); |
| 165 | + assertEquals(quirk ? 100 : 0, attribute.definedLength()); |
| 166 | + } finally { |
| 167 | + decoder.destroy(); |
| 168 | + } |
| 169 | + } |
81 | 170 | } |
0 commit comments