Skip to content

Commit cf1970c

Browse files
fredericBregiertrustin
authored andcommitted
Split HttpPostRequestDecoder into HttpPostStandardRequestDecoder and HttpPostMultipartRequestDecoder / Add HttpData.maxSize
- Related issues: netty#1937 netty#1938 and netty#1946 - Add InterfaceHttpPostRequestDecoder and Make HttpPostRequestDecoder implement it - HttpPostRequestDecoder actually delegates itself to HttpPostStandardRequestDecoder or HttpPostMultipartRequestDecoder - Remove IncompatibleDataDecoderException because it's not thrown anywhere now
1 parent 2eb5d4f commit cf1970c

16 files changed

Lines changed: 2805 additions & 1959 deletions

codec-http/src/main/java/io/netty/handler/codec/http/multipart/AbstractDiskHttpData.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ public void setContent(ByteBuf buffer) throws IOException {
101101
}
102102
try {
103103
size = buffer.readableBytes();
104+
checkSize(size);
104105
if (definedSize > 0 && definedSize < size) {
105106
throw new IOException("Out of size: " + size + " > " + definedSize);
106107
}
@@ -137,6 +138,7 @@ public void addContent(ByteBuf buffer, boolean last)
137138
if (buffer != null) {
138139
try {
139140
int localsize = buffer.readableBytes();
141+
checkSize(size + localsize);
140142
if (definedSize > 0 && definedSize < size + localsize) {
141143
throw new IOException("Out of size: " + (size + localsize) +
142144
" > " + definedSize);
@@ -187,6 +189,7 @@ public void setContent(File file) throws IOException {
187189
}
188190
this.file = file;
189191
size = file.length();
192+
checkSize(size);
190193
isRenamed = true;
191194
completed = true;
192195
}
@@ -209,6 +212,7 @@ public void setContent(InputStream inputStream) throws IOException {
209212
while (read > 0) {
210213
byteBuffer.position(read).flip();
211214
written += localfileChannel.write(byteBuffer);
215+
checkSize(written);
212216
read = inputStream.read(bytes);
213217
}
214218
localfileChannel.force(false);

codec-http/src/main/java/io/netty/handler/codec/http/multipart/AbstractHttpData.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public abstract class AbstractHttpData extends AbstractReferenceCounted implemen
3737
protected long size;
3838
protected Charset charset = HttpConstants.DEFAULT_CHARSET;
3939
protected boolean completed;
40+
protected long maxSize = DefaultHttpDataFactory.MAXSIZE;
4041

4142
protected AbstractHttpData(String name, Charset charset, long size) {
4243
if (name == null) {
@@ -57,6 +58,16 @@ protected AbstractHttpData(String name, Charset charset, long size) {
5758
definedSize = size;
5859
}
5960

61+
public void setMaxSize(long maxSize) {
62+
this.maxSize = maxSize;
63+
}
64+
65+
public void checkSize(long newSize) throws IOException {
66+
if (maxSize >= 0 && newSize > maxSize) {
67+
throw new IOException("Size exceed allowed maximum capacity");
68+
}
69+
}
70+
6071
@Override
6172
public String getName() {
6273
return name;

codec-http/src/main/java/io/netty/handler/codec/http/multipart/AbstractMemoryHttpData.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public void setContent(ByteBuf buffer) throws IOException {
4949
throw new NullPointerException("buffer");
5050
}
5151
long localsize = buffer.readableBytes();
52+
checkSize(localsize);
5253
if (definedSize > 0 && definedSize < localsize) {
5354
throw new IOException("Out of size: " + localsize + " > " +
5455
definedSize);
@@ -73,6 +74,7 @@ public void setContent(InputStream inputStream) throws IOException {
7374
while (read > 0) {
7475
buffer.writeBytes(bytes, 0, read);
7576
written += read;
77+
checkSize(written);
7678
read = inputStream.read(bytes);
7779
}
7880
size = written;
@@ -91,6 +93,7 @@ public void addContent(ByteBuf buffer, boolean last)
9193
throws IOException {
9294
if (buffer != null) {
9395
long localsize = buffer.readableBytes();
96+
checkSize(size + localsize);
9497
if (definedSize > 0 && definedSize < size + localsize) {
9598
throw new IOException("Out of size: " + (size + localsize) +
9699
" > " + definedSize);
@@ -128,6 +131,7 @@ public void setContent(File file) throws IOException {
128131
throw new IllegalArgumentException(
129132
"File too big to be loaded in memory");
130133
}
134+
checkSize(newsize);
131135
FileInputStream inputStream = new FileInputStream(file);
132136
FileChannel fileChannel = inputStream.getChannel();
133137
byte[] array = new byte[(int) newsize];

codec-http/src/main/java/io/netty/handler/codec/http/multipart/DefaultHttpDataFactory.java

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,19 @@ public class DefaultHttpDataFactory implements HttpDataFactory {
3737
* Proposed default MINSIZE as 16 KB.
3838
*/
3939
public static final long MINSIZE = 0x4000;
40+
/**
41+
* Proposed default MAXSIZE = -1 as UNLIMITED
42+
*/
43+
public static final long MAXSIZE = -1;
4044

4145
private final boolean useDisk;
4246

4347
private final boolean checkSize;
4448

4549
private long minSize;
4650

51+
private long maxSize = MAXSIZE;
52+
4753
/**
4854
* Keep all HttpDatas until cleanAllHttpDatas() is called.
4955
*/
@@ -78,6 +84,10 @@ public DefaultHttpDataFactory(long minSize) {
7884
this.minSize = minSize;
7985
}
8086

87+
public void setMaxLimit(long max) {
88+
this.maxSize = max;
89+
}
90+
8191
/**
8292
* @return the associated list of Files for the request
8393
*/
@@ -94,17 +104,33 @@ private List<HttpData> getList(HttpRequest request) {
94104
public Attribute createAttribute(HttpRequest request, String name) {
95105
if (useDisk) {
96106
Attribute attribute = new DiskAttribute(name);
107+
attribute.setMaxSize(maxSize);
97108
List<HttpData> fileToDelete = getList(request);
98109
fileToDelete.add(attribute);
99110
return attribute;
100111
}
101112
if (checkSize) {
102113
Attribute attribute = new MixedAttribute(name, minSize);
114+
attribute.setMaxSize(maxSize);
103115
List<HttpData> fileToDelete = getList(request);
104116
fileToDelete.add(attribute);
105117
return attribute;
106118
}
107-
return new MemoryAttribute(name);
119+
MemoryAttribute attribute = new MemoryAttribute(name);
120+
attribute.setMaxSize(maxSize);
121+
return attribute;
122+
}
123+
124+
/**
125+
* Utility method
126+
* @param data
127+
*/
128+
private void checkHttpDataSize(HttpData data) {
129+
try {
130+
data.checkSize(data.length());
131+
} catch (IOException e) {
132+
throw new IllegalArgumentException("Attribute bigger than maxSize allowed");
133+
}
108134
}
109135

110136
@Override
@@ -113,22 +139,30 @@ public Attribute createAttribute(HttpRequest request, String name, String value)
113139
Attribute attribute;
114140
try {
115141
attribute = new DiskAttribute(name, value);
142+
attribute.setMaxSize(maxSize);
116143
} catch (IOException e) {
117144
// revert to Mixed mode
118145
attribute = new MixedAttribute(name, value, minSize);
146+
attribute.setMaxSize(maxSize);
119147
}
148+
checkHttpDataSize(attribute);
120149
List<HttpData> fileToDelete = getList(request);
121150
fileToDelete.add(attribute);
122151
return attribute;
123152
}
124153
if (checkSize) {
125154
Attribute attribute = new MixedAttribute(name, value, minSize);
155+
attribute.setMaxSize(maxSize);
156+
checkHttpDataSize(attribute);
126157
List<HttpData> fileToDelete = getList(request);
127158
fileToDelete.add(attribute);
128159
return attribute;
129160
}
130161
try {
131-
return new MemoryAttribute(name, value);
162+
MemoryAttribute attribute = new MemoryAttribute(name, value);
163+
attribute.setMaxSize(maxSize);
164+
checkHttpDataSize(attribute);
165+
return attribute;
132166
} catch (IOException e) {
133167
throw new IllegalArgumentException(e);
134168
}
@@ -141,19 +175,26 @@ public FileUpload createFileUpload(HttpRequest request, String name, String file
141175
if (useDisk) {
142176
FileUpload fileUpload = new DiskFileUpload(name, filename, contentType,
143177
contentTransferEncoding, charset, size);
178+
fileUpload.setMaxSize(maxSize);
179+
checkHttpDataSize(fileUpload);
144180
List<HttpData> fileToDelete = getList(request);
145181
fileToDelete.add(fileUpload);
146182
return fileUpload;
147183
}
148184
if (checkSize) {
149185
FileUpload fileUpload = new MixedFileUpload(name, filename, contentType,
150186
contentTransferEncoding, charset, size, minSize);
187+
fileUpload.setMaxSize(maxSize);
188+
checkHttpDataSize(fileUpload);
151189
List<HttpData> fileToDelete = getList(request);
152190
fileToDelete.add(fileUpload);
153191
return fileUpload;
154192
}
155-
return new MemoryFileUpload(name, filename, contentType,
193+
MemoryFileUpload fileUpload = new MemoryFileUpload(name, filename, contentType,
156194
contentTransferEncoding, charset, size);
195+
fileUpload.setMaxSize(maxSize);
196+
checkHttpDataSize(fileUpload);
197+
return fileUpload;
157198
}
158199

159200
@Override

codec-http/src/main/java/io/netty/handler/codec/http/multipart/DiskAttribute.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public void setValue(String value) throws IOException {
6464
throw new NullPointerException("value");
6565
}
6666
byte [] bytes = value.getBytes(charset.name());
67+
checkSize(bytes.length);
6768
ByteBuf buffer = wrappedBuffer(bytes);
6869
if (definedSize > 0) {
6970
definedSize = buffer.readableBytes();
@@ -74,6 +75,7 @@ public void setValue(String value) throws IOException {
7475
@Override
7576
public void addContent(ByteBuf buffer, boolean last) throws IOException {
7677
int localsize = buffer.readableBytes();
78+
checkSize(size + localsize);
7779
if (definedSize > 0 && definedSize < size + localsize) {
7880
definedSize = size + localsize;
7981
}

codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpData.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@
2727
* Extended interface for InterfaceHttpData
2828
*/
2929
public interface HttpData extends InterfaceHttpData, ByteBufHolder {
30+
/**
31+
* Set the maxSize for this HttpData. When limit will be reached, an exception will be raised.
32+
* Setting it to (-1) means no limitation.
33+
*
34+
* By default, to be set from the HttpDataFactory.
35+
* @param maxSize
36+
*/
37+
void setMaxSize(long maxSize);
38+
39+
/**
40+
* Check if the new size is not reaching the max limit allowed.
41+
* The limit is always computed in term of bytes.
42+
* @param newSize
43+
* @throws IOException
44+
*/
45+
void checkSize(long newSize) throws IOException;
46+
3047
/**
3148
* Set the content from the ChannelBuffer (erase any previous data)
3249
*

codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpDataFactory.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@
2323
* Interface to enable creation of InterfaceHttpData objects
2424
*/
2525
public interface HttpDataFactory {
26+
/**
27+
* To set a max size limitation on fields. Exceeding it will generate an ErrorDataDecoderException.
28+
* A value of -1 means no limitation (default).
29+
* @param max
30+
*/
31+
void setMaxLimit(long max);
32+
2633
/**
2734
*
2835
* @param request associated request

0 commit comments

Comments
 (0)