Skip to content

Commit

Permalink
Fixed bug in HTTP form upload handling for small files, and in counti…
Browse files Browse the repository at this point in the history
…ng size, also added more tests
  • Loading branch information
purplefox committed Feb 23, 2015
1 parent 32b1485 commit 7c88740
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 30 deletions.
36 changes: 21 additions & 15 deletions src/main/java/io/vertx/core/http/impl/HttpServerFileUploadImpl.java
Expand Up @@ -120,11 +120,11 @@ public synchronized HttpServerFileUpload resume() {
req.resume();
paused = false;
if (pauseBuff != null) {
receiveData(pauseBuff);
doReceiveData(pauseBuff);
pauseBuff = null;
}
if (complete && endHandler != null) {
endHandler.handle(null);
if (complete) {
handleComplete();
}
}
return this;
Expand All @@ -148,10 +148,8 @@ public HttpServerFileUpload streamToFileSystem(String filename) {
vertx.fileSystem().open(filename, new OpenOptions(), ar -> {
if (ar.succeeded()) {
file = ar.result();

Pump p = Pump.pump(HttpServerFileUploadImpl.this, ar.result());
p.start();

resume();
} else {
notifyExceptionHandler(ar.cause());
Expand All @@ -169,6 +167,10 @@ synchronized void receiveData(Buffer data) {
if (lazyCalculateSize) {
size += data.length();
}
doReceiveData(data);
}

synchronized void doReceiveData(Buffer data) {
if (!paused) {
if (dataHandler != null) {
dataHandler.handle(data);
Expand All @@ -183,20 +185,24 @@ synchronized void receiveData(Buffer data) {

synchronized void complete() {
req.uploadComplete(this);
lazyCalculateSize = false;
if (paused) {
complete = true;
} else {
if (file == null) {
handleComplete();
}
}

private void handleComplete() {
lazyCalculateSize = false;
if (file == null) {
notifyEndHandler();
} else {
file.close(ar -> {
if (ar.failed()) {
notifyExceptionHandler(ar.cause());
}
notifyEndHandler();
} else {
file.close(ar -> {
if (ar.failed()) {
notifyExceptionHandler(ar.cause());
}
notifyEndHandler();
});
}
});
}
}

Expand Down
Expand Up @@ -19,15 +19,7 @@
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.handler.codec.http.DefaultHttpContent;
import io.netty.handler.codec.http.DefaultHttpResponse;
import io.netty.handler.codec.http.DefaultLastHttpContent;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.handler.codec.http.*;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
Expand Down
45 changes: 39 additions & 6 deletions src/test/java/io/vertx/test/core/HttpTest.java
Expand Up @@ -3233,9 +3233,30 @@ public void testHttpVersion() {
}

@Test
public void testFormUploadFile() throws Exception {
public void testFormUploadSmallFile() throws Exception {
testFormUploadFile(TestUtils.randomAlphaString(100), false);
}

@Test
public void testFormUploadLargerFile() throws Exception {
testFormUploadFile(TestUtils.randomAlphaString(20000), false);
}

@Test
public void testFormUploadSmallFileStreamToDisk() throws Exception {
testFormUploadFile(TestUtils.randomAlphaString(100), true);
}

@Test
public void testFormUploadLargerFileStreamToDisk() throws Exception {
testFormUploadFile(TestUtils.randomAlphaString(20000), true);
}

private void testFormUploadFile(String contentStr, boolean streamToDisk) throws Exception {

Buffer content = Buffer.buffer(contentStr);

AtomicInteger attributeCount = new AtomicInteger();
String content = "Vert.x rocks!";

server.requestHandler(req -> {
if (req.method() == HttpMethod.POST) {
Expand All @@ -3244,13 +3265,25 @@ public void testFormUploadFile() throws Exception {
req.setExpectMultipart(true);
assertTrue(req.isExpectMultipart());
req.uploadHandler(upload -> {
upload.handler(buffer -> {
assertEquals(content, buffer.toString("UTF-8"));
});
Buffer tot = Buffer.buffer();
assertEquals("file", upload.name());
assertEquals("tmp-0.txt", upload.filename());
assertEquals("image/gif", upload.contentType());
String uploadedFileName;
if (!streamToDisk) {
upload.handler(buffer -> tot.appendBuffer(buffer));
uploadedFileName = null;
} else {
uploadedFileName = new File(testDir, UUID.randomUUID().toString()).getPath();
upload.streamToFileSystem(uploadedFileName);
}
upload.endHandler(v -> {
if (streamToDisk) {
Buffer uploaded = vertx.fileSystem().readFileBlocking(uploadedFileName);
assertEquals(content, uploaded);
} else {
assertEquals(content, tot);
}
assertTrue(upload.isSizeAvailable());
assertEquals(content.length(), upload.size());
});
Expand Down Expand Up @@ -3281,7 +3314,7 @@ public void testFormUploadFile() throws Exception {
"Content-Disposition: form-data; name=\"file\"; filename=\"tmp-0.txt\"\r\n" +
"Content-Type: image/gif\r\n" +
"\r\n" +
content + "\r\n" +
contentStr + "\r\n" +
"--" + boundary + "--\r\n";

buffer.appendString(body);
Expand Down
16 changes: 16 additions & 0 deletions src/test/java/io/vertx/test/core/StarterTest.java
Expand Up @@ -274,6 +274,22 @@ public void testConfigureFromSystemPropertiesInvalidPropertyType() throws Except
assertEquals(new VertxOptions(), opts);
}

@Test
public void testRunWithCommandLine() throws Exception {
Starter starter = new Starter();
int instances = 10;
String cl = "run java:" + TestVerticle.class.getCanonicalName() + " -instances " + instances;
Thread t = new Thread(() -> {
starter.run(cl);
});
t.start();
waitUntil(() -> TestVerticle.instanceCount.get() == instances);
assertTrue(t.isAlive()); // It's blocked
// Now unblock it
starter.unblock();
waitUntil(() -> !t.isAlive());
}

class MyStarter extends Starter {
public Vertx getVert() {
return vertx;
Expand Down

0 comments on commit 7c88740

Please sign in to comment.