diff options
18 files changed, 147 insertions, 242 deletions
diff --git a/AndroidAsync/src/com/koushikdutta/async/AsyncServer.java b/AndroidAsync/src/com/koushikdutta/async/AsyncServer.java index b198a88..63a3fb6 100644 --- a/AndroidAsync/src/com/koushikdutta/async/AsyncServer.java +++ b/AndroidAsync/src/com/koushikdutta/async/AsyncServer.java @@ -122,28 +122,6 @@ public class AsyncServer { e.printStackTrace(); } } - - private static final long DEFAULT_WAIT = 100; - private static long runQueue(LinkedList<Scheduled> queue) { - long wait = DEFAULT_WAIT; - long now = System.currentTimeMillis(); - LinkedList<Scheduled> later = null; - while (queue.size() > 0) { - Scheduled s = queue.remove(); - if (s.time < now) - s.runnable.run(); - else { - wait = Math.min(wait, s.time - now); - if (later == null) - later = new LinkedList<AsyncServer.Scheduled>(); - later.add(s); - } - } - if (later != null) - queue.addAll(later); - - return wait; - } private static class Scheduled { public Scheduled(Runnable runnable, long time) { @@ -417,13 +395,39 @@ public class AsyncServer { } } + private static final long DEFAULT_WAIT = 100; private static long lockAndRunQueue(AsyncServer server, LinkedList<Scheduled> queue) { - LinkedList<Scheduled> copy; + long wait = DEFAULT_WAIT; + LinkedList<Scheduled> copy = null; + // first filter out the queue items we can actually run synchronized (server) { - copy = new LinkedList<Scheduled>(queue); - queue.clear(); + long now = System.currentTimeMillis(); + LinkedList<Scheduled> later = null; + while (queue.size() > 0) { + Scheduled s = queue.remove(); + if (s.time <= now) { + if (copy == null) + copy = new LinkedList<AsyncServer.Scheduled>(); + copy.add(s); + } + else { + wait = Math.min(wait, s.time - now); + if (later == null) + later = new LinkedList<AsyncServer.Scheduled>(); + later.add(s); + } + } + if (later != null) + queue.addAll(later); } - return runQueue(copy); + + // now run + if (copy != null) { + while (copy.size() > 0) { + copy.remove().runnable.run(); + } + } + return wait; } private static void runLoop(AsyncServer server, Selector selector, LinkedList<Scheduled> queue, boolean keepRunning) throws IOException { diff --git a/AndroidAsync/src/com/koushikdutta/async/BufferedDataEmitter.java b/AndroidAsync/src/com/koushikdutta/async/BufferedDataEmitter.java index 4c7f8e0..045e206 100644 --- a/AndroidAsync/src/com/koushikdutta/async/BufferedDataEmitter.java +++ b/AndroidAsync/src/com/koushikdutta/async/BufferedDataEmitter.java @@ -87,4 +87,9 @@ public class BufferedDataEmitter implements DataEmitter, DataCallback { public CompletedCallback getEndCallback() { return mEndCallback; } + + @Override + public AsyncServer getServer() { + return mEmitter.getServer(); + } } diff --git a/AndroidAsync/src/com/koushikdutta/async/DataEmitter.java b/AndroidAsync/src/com/koushikdutta/async/DataEmitter.java index f9a9ee3..79eb3fb 100644 --- a/AndroidAsync/src/com/koushikdutta/async/DataEmitter.java +++ b/AndroidAsync/src/com/koushikdutta/async/DataEmitter.java @@ -12,4 +12,5 @@ public interface DataEmitter { public boolean isPaused(); public void setEndCallback(CompletedCallback callback); public CompletedCallback getEndCallback(); + public AsyncServer getServer(); } diff --git a/AndroidAsync/src/com/koushikdutta/async/FilteredDataCallback.java b/AndroidAsync/src/com/koushikdutta/async/FilteredDataCallback.java deleted file mode 100644 index 034ffaf..0000000 --- a/AndroidAsync/src/com/koushikdutta/async/FilteredDataCallback.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.koushikdutta.async; - -import junit.framework.Assert; - -import com.koushikdutta.async.callback.CompletedCallback; -import com.koushikdutta.async.callback.DataCallback; - -public class FilteredDataCallback implements DataEmitter, DataCallback { - public FilteredDataCallback() { - } - - private DataCallback mDataCallback; - @Override - public void setDataCallback(DataCallback callback) { - mDataCallback = callback; - } - - @Override - public DataCallback getDataCallback() { - return mDataCallback; - } - - @Override - public boolean isChunked() { - return false; - } - - protected void report(Exception e) { - if (mCompletedCallback != null) - mCompletedCallback.onCompleted(e); - } - - @Override - public CompletedCallback getEndCallback() { - return mCompletedCallback; - } - - @Override - public void setEndCallback(CompletedCallback callback) { - mCompletedCallback = callback; - } - CompletedCallback mCompletedCallback; - - @Override - public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) { - Assert.assertNull(pending); - Assert.assertNotNull(mDataCallback); - Util.emitAllData(this, bb); - if (bb.remaining() > 0) - pending = bb; - } - - private ByteBufferList pending; - private boolean mPaused; - @Override - public void pause() { - mPaused = true; - } - - @Override - public void resume() { - if (!mPaused) - return; - mPaused = false; - if (pending != null) { - Assert.assertNotNull(mDataCallback); - Util.emitAllData(this, pending); - if (pending.remaining() == 0) - pending = null; - } - } - - @Override - public boolean isPaused() { - return mPaused; - } - - public int remaining() { - if (pending == null) - return 0; - return pending.remaining(); - } -} diff --git a/AndroidAsync/src/com/koushikdutta/async/FilteredDataEmitter.java b/AndroidAsync/src/com/koushikdutta/async/FilteredDataEmitter.java index c4409c6..ee7c2bd 100644 --- a/AndroidAsync/src/com/koushikdutta/async/FilteredDataEmitter.java +++ b/AndroidAsync/src/com/koushikdutta/async/FilteredDataEmitter.java @@ -3,26 +3,33 @@ package com.koushikdutta.async; import com.koushikdutta.async.callback.CompletedCallback; import com.koushikdutta.async.callback.DataCallback; -public class FilteredDataEmitter implements DataEmitter { +public class FilteredDataEmitter implements DataEmitter, DataCallback { DataEmitter mEmitter; public DataEmitter getDataEmitter() { return mEmitter; } + protected void report(Exception e) { + if (mEndCallback != null) + mEndCallback.onCompleted(e); + } + public void setDataEmitter(DataEmitter emitter) { if (mEmitter != null) { mEmitter.setDataCallback(null); } mEmitter = emitter; - mEmitter.setDataCallback(new DataCallback() { + mEmitter.setDataCallback(this); + mEmitter.setEndCallback(new CompletedCallback() { @Override - public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) { - FilteredDataEmitter.this.onDataAvailable(emitter, bb); + public void onCompleted(Exception ex) { + report(ex); } }); } - protected void onDataAvailable(DataEmitter emitter, ByteBufferList bb) { + @Override + public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) { Util.emitAllData(this, bb); // if there's data after the emitting, and it is paused... the underlying implementation // is obligated to cache the byte buffer list. @@ -59,13 +66,19 @@ public class FilteredDataEmitter implements DataEmitter { return mEmitter.isPaused(); } + CompletedCallback mEndCallback; @Override public void setEndCallback(CompletedCallback callback) { - mEmitter.setEndCallback(callback); + mEndCallback = callback; } @Override public CompletedCallback getEndCallback() { - return mEmitter.getEndCallback(); + return mEndCallback; + } + + @Override + public AsyncServer getServer() { + return mEmitter.getServer(); } } diff --git a/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpResponseImpl.java b/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpResponseImpl.java index 1719f42..a4a00e5 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpResponseImpl.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpResponseImpl.java @@ -9,18 +9,17 @@ import com.koushikdutta.async.AsyncSocket; import com.koushikdutta.async.ByteBufferList; import com.koushikdutta.async.DataEmitter; import com.koushikdutta.async.DataSink; -import com.koushikdutta.async.FilteredDataCallback; +import com.koushikdutta.async.FilteredDataEmitter; import com.koushikdutta.async.LineEmitter; import com.koushikdutta.async.LineEmitter.StringCallback; import com.koushikdutta.async.NullDataCallback; import com.koushikdutta.async.callback.CompletedCallback; -import com.koushikdutta.async.callback.DataCallback; import com.koushikdutta.async.callback.WritableCallback; import com.koushikdutta.async.http.filter.ChunkedOutputFilter; import com.koushikdutta.async.http.libcore.RawHeaders; import com.koushikdutta.async.http.libcore.ResponseHeaders; -abstract class AsyncHttpResponseImpl extends FilteredDataCallback implements AsyncHttpResponse { +abstract class AsyncHttpResponseImpl extends FilteredDataEmitter implements AsyncHttpResponse { private RawHeaders mRawHeaders = new RawHeaders(); public RawHeaders getRawHeaders() { return mRawHeaders; @@ -70,9 +69,7 @@ abstract class AsyncHttpResponseImpl extends FilteredDataCallback implements Asy mSocket.setClosedCallback(new CompletedCallback() { @Override public void onCompleted(Exception ex) { - if (!mCompleted) { - report(new Exception("connection closed before response completed.")); - } + // TODO: do we care? throw if socket is still writing or something? } }); } @@ -80,7 +77,12 @@ abstract class AsyncHttpResponseImpl extends FilteredDataCallback implements Asy private CompletedCallback mReporter = new CompletedCallback() { @Override public void onCompleted(Exception error) { - report(error); + if (error != null && !mCompleted) { + report(new Exception("connection closed before response completed.")); + } + else { + report(error); + } } }; @@ -102,8 +104,8 @@ abstract class AsyncHttpResponseImpl extends FilteredDataCallback implements Asy // socket may get detached after headers (websocket) if (mSocket == null) return; - DataCallback callback = Util.getBodyDecoder(AsyncHttpResponseImpl.this, mRawHeaders, false, mReporter); - mSocket.setDataCallback(callback); + DataEmitter emitter = Util.getBodyDecoder(mSocket, mRawHeaders, false, mReporter); + setDataEmitter(emitter); } } catch (Exception ex) { diff --git a/AndroidAsync/src/com/koushikdutta/async/http/MultipartCallback.java b/AndroidAsync/src/com/koushikdutta/async/http/MultipartCallback.java index f3f3026..e3eb950 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/MultipartCallback.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/MultipartCallback.java @@ -2,6 +2,7 @@ package com.koushikdutta.async.http; import com.koushikdutta.async.callback.DataCallback; + public interface MultipartCallback { public DataCallback onPart(Part part); } diff --git a/AndroidAsync/src/com/koushikdutta/async/http/MultipartFormDataBody.java b/AndroidAsync/src/com/koushikdutta/async/http/MultipartFormDataBody.java index 53035f6..5016447 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/MultipartFormDataBody.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/MultipartFormDataBody.java @@ -1,9 +1,8 @@ package com.koushikdutta.async.http; -import com.koushikdutta.async.ByteBufferList; -import com.koushikdutta.async.DataEmitter; import com.koushikdutta.async.LineEmitter; import com.koushikdutta.async.LineEmitter.StringCallback; +import com.koushikdutta.async.NullDataCallback; import com.koushikdutta.async.callback.DataCallback; import com.koushikdutta.async.http.libcore.RawHeaders; import com.koushikdutta.async.http.server.AsyncHttpRequestBodyBase; @@ -33,20 +32,7 @@ public class MultipartFormDataBody extends AsyncHttpRequestBodyBase { headers.addLine(s); } else { - Part part = new Part(headers); - DataCallback callback = onPart(part); - if (callback == null) - callback = new DataCallback() { - int total; - @Override - public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) { - total += bb.remaining(); -// System.out.println(total); -// System.out.println(bb.peekString()); - bb.clear(); - } - }; - boundaryEmitter.setDataCallback(callback); + boundaryEmitter.setDataCallback(onPart(new Part(headers))); } } }); @@ -56,16 +42,12 @@ public class MultipartFormDataBody extends AsyncHttpRequestBodyBase { // System.out.println("boundary end"); } }; + boundaryEmitter.setDataEmitter(this); return; } report(new Exception ("No boundary found for multipart/form-data")); } - - @Override - public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) { - boundaryEmitter.onDataAvailable(emitter, bb); - } - + MultipartCallback mCallback; public void setMultipartCallback(MultipartCallback callback) { mCallback = callback; @@ -74,12 +56,12 @@ public class MultipartFormDataBody extends AsyncHttpRequestBodyBase { public MultipartCallback getMultipartCallback() { return mCallback; } - + private DataCallback onPart(Part part) { // System.out.println("here"); // System.out.println(headers.toHeaderString()); if (mCallback == null) - return null; + return new NullDataCallback(); return mCallback.onPart(part); } } diff --git a/AndroidAsync/src/com/koushikdutta/async/http/Util.java b/AndroidAsync/src/com/koushikdutta/async/http/Util.java index a971a27..189dd23 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/Util.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/Util.java @@ -1,12 +1,12 @@ package com.koushikdutta.async.http; import junit.framework.Assert; +import android.util.Log; import com.koushikdutta.async.ByteBufferList; import com.koushikdutta.async.DataEmitter; -import com.koushikdutta.async.FilteredDataCallback; +import com.koushikdutta.async.FilteredDataEmitter; import com.koushikdutta.async.callback.CompletedCallback; -import com.koushikdutta.async.callback.DataCallback; import com.koushikdutta.async.http.filter.ChunkedInputFilter; import com.koushikdutta.async.http.filter.GZIPInputFilter; import com.koushikdutta.async.http.filter.InflaterInputFilter; @@ -14,7 +14,7 @@ import com.koushikdutta.async.http.libcore.RawHeaders; import com.koushikdutta.async.http.server.UnknownRequestBody; public class Util { - public static AsyncHttpRequestBody getBody(RawHeaders headers) { + public static AsyncHttpRequestBody getBody(DataEmitter emitter, final CompletedCallback reporter, RawHeaders headers) { String contentType = headers.get("Content-Type"); if (contentType != null) { String[] values = contentType.split(";"); @@ -24,27 +24,19 @@ public class Util { for (String ct: values) { if (UrlEncodedFormBody.CONTENT_TYPE.equals(ct)) return new UrlEncodedFormBody(); - if (MultipartFormDataBody.CONTENT_TYPE.equals(ct)) - return new MultipartFormDataBody(contentType, values); + if (MultipartFormDataBody.CONTENT_TYPE.equals(ct)) { + MultipartFormDataBody ret = new MultipartFormDataBody(contentType, values); + ret.setDataEmitter(emitter); + ret.setEndCallback(null); + emitter.setEndCallback(reporter); + return ret; + } } } return new UnknownRequestBody(contentType); } - public static DataCallback getBodyDecoder(DataCallback callback, RawHeaders headers, boolean server, final CompletedCallback reporter) { - if ("gzip".equals(headers.get("Content-Encoding"))) { - GZIPInputFilter gunzipper = new GZIPInputFilter(); - gunzipper.setDataCallback(callback); - gunzipper.setEndCallback(reporter); - callback = gunzipper; - } - else if ("deflate".equals(headers.get("Content-Encoding"))) { - InflaterInputFilter inflater = new InflaterInputFilter(); - inflater.setEndCallback(reporter); - inflater.setDataCallback(callback); - callback = inflater; - } - + public static DataEmitter getBodyDecoder(DataEmitter emitter, RawHeaders headers, boolean server, final CompletedCallback reporter) { int _contentLength; try { _contentLength = Integer.parseInt(headers.get("Content-Length")); @@ -55,15 +47,24 @@ public class Util { final int contentLength = _contentLength; if (-1 != contentLength) { if (contentLength < 0) { - reporter.onCompleted(new Exception("not using chunked encoding, and no content-length found.")); - return callback; + emitter.getServer().post(new Runnable() { + @Override + public void run() { + reporter.onCompleted(new Exception("not using chunked encoding, and no content-length found.")); + } + }); + return emitter; } if (contentLength == 0) { - reporter.onCompleted(null); - return callback; + emitter.getServer().post(new Runnable() { + @Override + public void run() { + reporter.onCompleted(null); + } + }); + return emitter; } -// System.out.println("Content len: " + contentLength); - FilteredDataCallback contentLengthWatcher = new FilteredDataCallback() { + FilteredDataEmitter contentLengthWatcher = new FilteredDataEmitter() { int totalRead = 0; @Override public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) { @@ -75,23 +76,39 @@ public class Util { report(null); } }; - contentLengthWatcher.setDataCallback(callback); + contentLengthWatcher.setDataEmitter(emitter); contentLengthWatcher.setEndCallback(reporter); - callback = contentLengthWatcher; + emitter = contentLengthWatcher; } else if ("chunked".equalsIgnoreCase(headers.get("Transfer-Encoding"))) { ChunkedInputFilter chunker = new ChunkedInputFilter(); - + chunker.setDataEmitter(emitter); chunker.setEndCallback(reporter); - chunker.setDataCallback(callback); - callback = chunker; + emitter = chunker; } else if (server) { // if this is the server, and the client has not indicated a request body, the client is done - reporter.onCompleted(null); + emitter.getServer().post(new Runnable() { + @Override + public void run() { + reporter.onCompleted(null); + } + }); } + + if ("gzip".equals(headers.get("Content-Encoding"))) { + GZIPInputFilter gunzipper = new GZIPInputFilter(); + gunzipper.setDataEmitter(emitter); + emitter = gunzipper; + } + else if ("deflate".equals(headers.get("Content-Encoding"))) { + InflaterInputFilter inflater = new InflaterInputFilter(); + inflater.setDataEmitter(emitter); + emitter = inflater; + } + // conversely, if this is the client, and the server has not indicated a request body, we do not report // the close/end event until the server actually closes the connection. - return callback; + return emitter; } } diff --git a/AndroidAsync/src/com/koushikdutta/async/http/filter/ChunkedInputFilter.java b/AndroidAsync/src/com/koushikdutta/async/http/filter/ChunkedInputFilter.java index 447327b..36d9227 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/filter/ChunkedInputFilter.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/filter/ChunkedInputFilter.java @@ -4,11 +4,10 @@ import junit.framework.Assert; import com.koushikdutta.async.ByteBufferList; import com.koushikdutta.async.DataEmitter; -import com.koushikdutta.async.FilteredDataCallback; +import com.koushikdutta.async.FilteredDataEmitter; import com.koushikdutta.async.Util; -import com.koushikdutta.async.callback.CompletedCallback; -public class ChunkedInputFilter extends FilteredDataCallback { +public class ChunkedInputFilter extends FilteredDataEmitter { private int mChunkLength = 0; private int mChunkLengthRemaining = 0; private State mState = State.CHUNK_LEN; diff --git a/AndroidAsync/src/com/koushikdutta/async/http/filter/GZIPInputFilter.java b/AndroidAsync/src/com/koushikdutta/async/http/filter/GZIPInputFilter.java index 6a72be7..ad01595 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/filter/GZIPInputFilter.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/filter/GZIPInputFilter.java @@ -120,7 +120,8 @@ public class GZIPInputFilter extends InflaterInputFilter { crc.reset(); } mNeedsHeader = false; - emitter.setDataCallback(GZIPInputFilter.this); + setDataEmitter(emitter); +// emitter.setDataCallback(GZIPInputFilter.this); } }); } diff --git a/AndroidAsync/src/com/koushikdutta/async/http/filter/InflaterInputFilter.java b/AndroidAsync/src/com/koushikdutta/async/http/filter/InflaterInputFilter.java index 7bca451..9b8797f 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/filter/InflaterInputFilter.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/filter/InflaterInputFilter.java @@ -7,10 +7,10 @@ import junit.framework.Assert; import com.koushikdutta.async.ByteBufferList; import com.koushikdutta.async.DataEmitter; -import com.koushikdutta.async.FilteredDataCallback; +import com.koushikdutta.async.FilteredDataEmitter; import com.koushikdutta.async.Util; -public class InflaterInputFilter extends FilteredDataCallback { +public class InflaterInputFilter extends FilteredDataEmitter { private Inflater mInflater; @Override diff --git a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpRequestBodyBase.java b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpRequestBodyBase.java index 3db423a..eaa21e4 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpRequestBodyBase.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpRequestBodyBase.java @@ -2,13 +2,12 @@ package com.koushikdutta.async.http.server; import junit.framework.Assert; -import com.koushikdutta.async.FilteredDataCallback; -import com.koushikdutta.async.callback.CompletedCallback; +import com.koushikdutta.async.FilteredDataEmitter; import com.koushikdutta.async.http.AsyncHttpRequest; import com.koushikdutta.async.http.AsyncHttpRequestBody; import com.koushikdutta.async.http.AsyncHttpResponse; -public class AsyncHttpRequestBodyBase extends FilteredDataCallback implements AsyncHttpRequestBody { +public class AsyncHttpRequestBodyBase extends FilteredDataEmitter implements AsyncHttpRequestBody { public AsyncHttpRequestBodyBase(String contentType) { mContentType = contentType; } @@ -26,9 +25,7 @@ public class AsyncHttpRequestBodyBase extends FilteredDataCallback implements As @Override public void onCompleted(Exception ex) { - CompletedCallback callback = getEndCallback(); - if (callback != null) - callback.onCompleted(ex); + report(ex); } @Override diff --git a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServer.java b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServer.java index 4ea8ec5..3b6eb2e 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServer.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServer.java @@ -101,6 +101,7 @@ public class AsyncHttpServer { res = new AsyncHttpServerResponseImpl(socket, this) { @Override protected void onEnd() { + mSocket.setEndCallback(null); responseComplete = true; // reuse the socket for a subsequent request. handleOnCompleted(); diff --git a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerRequestImpl.java b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerRequestImpl.java index 49db709..307519b 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerRequestImpl.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerRequestImpl.java @@ -3,6 +3,8 @@ package com.koushikdutta.async.http.server; import java.util.regex.Matcher; import com.koushikdutta.async.AsyncSocket; +import com.koushikdutta.async.DataEmitter; +import com.koushikdutta.async.FilteredDataEmitter; import com.koushikdutta.async.LineEmitter; import com.koushikdutta.async.LineEmitter.StringCallback; import com.koushikdutta.async.callback.CompletedCallback; @@ -12,26 +14,14 @@ import com.koushikdutta.async.http.Util; import com.koushikdutta.async.http.libcore.RawHeaders; import com.koushikdutta.async.http.libcore.RequestHeaders; -public abstract class AsyncHttpServerRequestImpl implements AsyncHttpServerRequest, CompletedCallback { +public abstract class AsyncHttpServerRequestImpl extends FilteredDataEmitter implements AsyncHttpServerRequest, CompletedCallback { private RawHeaders mRawHeaders = new RawHeaders(); AsyncSocket mSocket; Matcher mMatcher; - private CompletedCallback mCompleted; - @Override - public void setEndCallback(CompletedCallback callback) { - mCompleted = callback; - } - - @Override - public CompletedCallback getEndCallback() { - return mCompleted; - } - private CompletedCallback mReporter = new CompletedCallback() { @Override public void onCompleted(Exception error) { -// System.out.println("completion of request"); AsyncHttpServerRequestImpl.this.onCompleted(error); } }; @@ -40,8 +30,7 @@ public abstract class AsyncHttpServerRequestImpl implements AsyncHttpServerReque public void onCompleted(Exception e) { if (mBody != null) mBody.onCompleted(e); - if (mCompleted != null) - mCompleted.onCompleted(e); + report(e); } abstract protected void onHeadersReceived(); @@ -66,9 +55,9 @@ public abstract class AsyncHttpServerRequestImpl implements AsyncHttpServerReque mRawHeaders.addLine(s); } else { - mBody = Util.getBody(mRawHeaders); - DataCallback callback = Util.getBodyDecoder(mBody, mRawHeaders, true, mReporter); - mSocket.setDataCallback(callback); + DataEmitter emitter = Util.getBodyDecoder(mSocket, mRawHeaders, true, mReporter); + mBody = Util.getBody(emitter, mReporter, mRawHeaders); + emitter.setDataCallback(mBody); onHeadersReceived(); } } diff --git a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerResponseImpl.java b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerResponseImpl.java index d822292..e69590f 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerResponseImpl.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerResponseImpl.java @@ -14,7 +14,6 @@ import com.koushikdutta.async.AsyncServer; import com.koushikdutta.async.AsyncSocket; import com.koushikdutta.async.BufferedDataSink; import com.koushikdutta.async.ByteBufferList; -import com.koushikdutta.async.FilteredDataSink; import com.koushikdutta.async.Util; import com.koushikdutta.async.callback.CompletedCallback; import com.koushikdutta.async.callback.WritableCallback; diff --git a/AndroidAsync/src/com/koushikdutta/async/http/server/BoundaryEmitter.java b/AndroidAsync/src/com/koushikdutta/async/http/server/BoundaryEmitter.java index e9607dd..f893164 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/server/BoundaryEmitter.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/server/BoundaryEmitter.java @@ -6,9 +6,9 @@ import junit.framework.Assert; import com.koushikdutta.async.ByteBufferList; import com.koushikdutta.async.DataEmitter; -import com.koushikdutta.async.FilteredDataCallback; +import com.koushikdutta.async.FilteredDataEmitter; -public class BoundaryEmitter extends FilteredDataCallback { +public class BoundaryEmitter extends FilteredDataEmitter { private byte[] boundary; public BoundaryEmitter(String boundary) { this.boundary = ("--" + boundary).getBytes(); @@ -20,24 +20,6 @@ public class BoundaryEmitter extends FilteredDataCallback { protected void onBoundaryEnd() { } - private static int matches(byte[] a1, int o1, byte[] a2, int o2, int count) { - Assert.assertTrue(count <= a1.length - o1); - Assert.assertTrue(count <= a2.length - o2); - for (int i = 0; i < count; i++, o1++, o2++) { - if (a1[o1] != a2[o2]) { -// System.out.println("match fail at " + i); - return i; - } - } - return count; - } - - @Override - protected void report(Exception e) { - e.printStackTrace(); - super.report(e); - } - // >= 0 matching // -1 matching - (start of boundary end) or \r (boundary start) // -2 matching - (end of boundary end) @@ -85,7 +67,7 @@ public class BoundaryEmitter extends FilteredDataCallback { ByteBuffer b = ByteBuffer.wrap(buf, last, len); ByteBufferList list = new ByteBufferList(); list.add(b); - super.onDataAvailable(emitter, list); + super.onDataAvailable(this, list); } else { // len can be -1 on the first boundary @@ -117,7 +99,7 @@ public class BoundaryEmitter extends FilteredDataCallback { ByteBuffer b = ByteBuffer.wrap(buf, last, i - last - boundary.length - 4); ByteBufferList list = new ByteBufferList(); list.add(b); - super.onDataAvailable(emitter, list); + super.onDataAvailable(this, list); // System.out.println("bend"); onBoundaryEnd(); } @@ -158,7 +140,7 @@ public class BoundaryEmitter extends FilteredDataCallback { ByteBuffer b = ByteBuffer.wrap(buf, last, buf.length - last - keep); ByteBufferList list = new ByteBufferList(); list.add(b); - super.onDataAvailable(emitter, list); + super.onDataAvailable(this, list); } } } diff --git a/AndroidAsyncSample/src/com/koushikdutta/async/sample/MainActivity.java b/AndroidAsyncSample/src/com/koushikdutta/async/sample/MainActivity.java index a15ce92..9af863c 100644 --- a/AndroidAsyncSample/src/com/koushikdutta/async/sample/MainActivity.java +++ b/AndroidAsyncSample/src/com/koushikdutta/async/sample/MainActivity.java @@ -11,6 +11,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; +import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; @@ -52,16 +53,10 @@ public class MainActivity extends Activity { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } - + private void getFile(final ImageView iv, String url, final String filename) { AsyncHttpClient.getDefaultInstance().get(url, filename, new AsyncHttpClient.FileCallback() { @Override - public void onProgress(AsyncHttpResponse response, int downloaded, int total) { - response.pause(); - super.onProgress(response, downloaded, total); - } - - @Override public void onCompleted(Exception e, AsyncHttpResponse response, File result) { if (e != null) { e.printStackTrace(); |