diff --git a/src/main/java/com/ning/http/multipart/FilePart.java b/src/main/java/com/ning/http/multipart/FilePart.java index 1f25bb9ce0..5548085f08 100644 --- a/src/main/java/com/ning/http/multipart/FilePart.java +++ b/src/main/java/com/ning/http/multipart/FilePart.java @@ -202,6 +202,14 @@ protected void sendData(OutputStream out) throws IOException { } } + public void setStalledTime(long ms) { + _stalledTime = ms; + } + + public long getStalledTime() { + return _stalledTime; + } + /** * Returns the source of the file part. * @@ -221,4 +229,6 @@ protected long lengthOfData() throws IOException { return source.getLength(); } + private long _stalledTime = -1; + } diff --git a/src/main/java/com/ning/http/multipart/FilePartStallHandler.java b/src/main/java/com/ning/http/multipart/FilePartStallHandler.java new file mode 100644 index 0000000000..2e02ef262e --- /dev/null +++ b/src/main/java/com/ning/http/multipart/FilePartStallHandler.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + */ +package com.ning.http.multipart; + +import java.util.Timer; +import java.util.TimerTask; + +/** + * @author Gail Hernandez + */ +public class FilePartStallHandler extends TimerTask { + public FilePartStallHandler(long waitTime, FilePart filePart) { + _waitTime = waitTime; + _failed = false; + _written = false; + } + + public void completed() { + if(_waitTime > 0) { + _timer.cancel(); + } + } + + public boolean isFailed() { + return _failed; + } + + public void run() { + if(!_written) { + _failed = true; + _timer.cancel(); + } + _written = false; + } + + public void start() { + if(_waitTime > 0) { + _timer = new Timer(); + _timer.scheduleAtFixedRate(this, _waitTime, _waitTime); + } + } + + public void writeHappened() { + _written = true; + } + + private long _waitTime; + private Timer _timer; + private boolean _failed; + private boolean _written; +} diff --git a/src/main/java/com/ning/http/multipart/FileUploadStalledException.java b/src/main/java/com/ning/http/multipart/FileUploadStalledException.java new file mode 100644 index 0000000000..11a7748a2d --- /dev/null +++ b/src/main/java/com/ning/http/multipart/FileUploadStalledException.java @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + */ +package com.ning.http.multipart; + +import java.io.IOException; + +/** + * @author Gail Hernandez + */ +public class FileUploadStalledException extends IOException { + +} diff --git a/src/main/java/com/ning/http/multipart/MultipartBody.java b/src/main/java/com/ning/http/multipart/MultipartBody.java index 40ac12f743..73a836452e 100644 --- a/src/main/java/com/ning/http/multipart/MultipartBody.java +++ b/src/main/java/com/ning/http/multipart/MultipartBody.java @@ -13,6 +13,7 @@ package com.ning.http.multipart; import com.ning.http.client.RandomAccessBody; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -434,7 +435,11 @@ private ByteArrayOutputStream generateFileStart(FilePart filePart) } private long handleFilePart(WritableByteChannel target, FilePart filePart) throws IOException { - + FilePartStallHandler handler = new FilePartStallHandler( + filePart.getStalledTime(), filePart); + + handler.start(); + if (FilePartSource.class.isAssignableFrom(filePart.getSource().getClass())) { int length = 0; @@ -453,8 +458,13 @@ private long handleFilePart(WritableByteChannel target, FilePart filePart) throw long nWrite = 0; synchronized (fc) { while (fileLength != l) { + if(handler.isFailed()) { + logger.debug("Stalled error"); + throw new FileUploadStalledException(); + } try { nWrite = fc.transferTo(fileLength, l, target); + if (nWrite == 0) { logger.info("Waiting for writing..."); try { @@ -463,6 +473,9 @@ private long handleFilePart(WritableByteChannel target, FilePart filePart) throw logger.trace(e.getMessage(), e); } } + else { + handler.writeHappened(); + } } catch (IOException ex) { String message = ex.getMessage(); @@ -482,6 +495,8 @@ private long handleFilePart(WritableByteChannel target, FilePart filePart) throw fileLength += nWrite; } } + handler.completed(); + fc.close(); length += handleFileEnd(target, filePart); @@ -541,7 +556,7 @@ private long handleMultiPart(WritableByteChannel target, Part currentPart) throw return handleStringPart(target, (StringPart) currentPart); } else if (currentPart.getClass().equals(FilePart.class)) { FilePart filePart = (FilePart) currentPart; - + return handleFilePart(target, filePart); } return 0;