diff options
11 files changed, 181 insertions, 78 deletions
diff --git a/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpClient.java b/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpClient.java index 0a36a72..8da007c 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpClient.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpClient.java @@ -11,6 +11,8 @@ import java.nio.ByteBuffer; import java.util.HashSet; import java.util.Hashtable; +import junit.framework.Assert; + import org.json.JSONException; import org.json.JSONObject; @@ -22,6 +24,8 @@ import com.koushikdutta.async.AsyncSocket; import com.koushikdutta.async.ByteBufferList; import com.koushikdutta.async.DataEmitter; import com.koushikdutta.async.DataExchange; +import com.koushikdutta.async.ExceptionCallback; +import com.koushikdutta.async.FilteredDataCallback; import com.koushikdutta.async.NullDataCallback; import com.koushikdutta.async.SSLDataExchange; import com.koushikdutta.async.callback.ClosedCallback; @@ -29,7 +33,11 @@ import com.koushikdutta.async.callback.CompletedCallback; import com.koushikdutta.async.callback.ConnectCallback; import com.koushikdutta.async.callback.DataCallback; import com.koushikdutta.async.callback.RequestCallback; +import com.koushikdutta.async.http.filter.ChunkedInputFilter; +import com.koushikdutta.async.http.filter.GZIPInputFilter; +import com.koushikdutta.async.http.filter.InflaterInputFilter; import com.koushikdutta.async.http.libcore.RawHeaders; +import com.koushikdutta.async.http.libcore.ResponseHeaders; import com.koushikdutta.async.stream.OutputStreamDataCallback; public class AsyncHttpClient { diff --git a/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpRequest.java b/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpRequest.java index ef9d410..65a8f90 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpRequest.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpRequest.java @@ -62,12 +62,12 @@ public class AsyncHttpRequest { mFollowRedirect = follow; } - private AsyncHttpRequestContentWriter mWriter; - public void setContentWriter(AsyncHttpRequestContentWriter writer) { - mWriter = writer; + private AsyncHttpRequestBody mBody; + public void setBody(AsyncHttpRequestBody body) { + mBody = body; } - public AsyncHttpRequestContentWriter getContentWriter() { - return mWriter; + public AsyncHttpRequestBody getBody() { + return mBody; } } diff --git a/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpRequestBody.java b/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpRequestBody.java new file mode 100644 index 0000000..007568b --- /dev/null +++ b/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpRequestBody.java @@ -0,0 +1,9 @@ +package com.koushikdutta.async.http; + +import com.koushikdutta.async.callback.CompletedCallback; +import com.koushikdutta.async.callback.DataCallback; + +public interface AsyncHttpRequestBody extends DataCallback, CompletedCallback { + public void write(AsyncHttpRequest request, AsyncHttpResponse sink); + public String getContentType(); +} diff --git a/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpRequestContentWriter.java b/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpRequestContentWriter.java deleted file mode 100644 index f015827..0000000 --- a/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpRequestContentWriter.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.koushikdutta.async.http; - - -public interface AsyncHttpRequestContentWriter { - public void write(AsyncHttpRequest request, AsyncHttpResponse sink); - public String getContentType(); -} diff --git a/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpResponseImpl.java b/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpResponseImpl.java index db6625f..11601ac 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpResponseImpl.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/AsyncHttpResponseImpl.java @@ -5,25 +5,19 @@ import java.nio.ByteBuffer; import junit.framework.Assert; import com.koushikdutta.async.AsyncSocket; -import com.koushikdutta.async.BufferedDataSink; import com.koushikdutta.async.ByteBufferList; import com.koushikdutta.async.DataEmitter; import com.koushikdutta.async.DataExchange; -import com.koushikdutta.async.FilteredDataCallback; import com.koushikdutta.async.ExceptionCallback; -import com.koushikdutta.async.FilteredDataSink; +import com.koushikdutta.async.FilteredDataCallback; import com.koushikdutta.async.LineEmitter; -import com.koushikdutta.async.NullDataCallback; -import com.koushikdutta.async.Util; import com.koushikdutta.async.LineEmitter.StringCallback; +import com.koushikdutta.async.NullDataCallback; import com.koushikdutta.async.callback.ClosedCallback; import com.koushikdutta.async.callback.CompletedCallback; import com.koushikdutta.async.callback.DataCallback; import com.koushikdutta.async.callback.WritableCallback; -import com.koushikdutta.async.http.filter.ChunkedInputFilter; import com.koushikdutta.async.http.filter.ChunkedOutputFilter; -import com.koushikdutta.async.http.filter.GZIPInputFilter; -import com.koushikdutta.async.http.filter.InflaterInputFilter; import com.koushikdutta.async.http.libcore.RawHeaders; import com.koushikdutta.async.http.libcore.ResponseHeaders; @@ -33,19 +27,19 @@ public class AsyncHttpResponseImpl extends FilteredDataCallback implements Async return mRawHeaders; } - private AsyncHttpRequestContentWriter mWriter; + private AsyncHttpRequestBody mWriter; void setSocket(AsyncSocket socket, DataExchange exchange) { mSocket = socket; mExchange = exchange; - mWriter = mRequest.getContentWriter(); + mWriter = mRequest.getBody(); if (mWriter != null) { mRequest.getHeaders().setContentType(mWriter.getContentType()); mRequest.getHeaders().getHeaders().set("Transfer-Encoding", "Chunked"); } String rs = mRequest.getRequestString(); - Util.writeAll(exchange, rs.getBytes(), new CompletedCallback() { + com.koushikdutta.async.Util.writeAll(exchange, rs.getBytes(), new CompletedCallback() { @Override public void onCompleted(Exception ex) { if (mWriter != null) @@ -87,52 +81,7 @@ public class AsyncHttpResponseImpl extends FilteredDataCallback implements Async return; } - DataCallback callback = this; - - if ("gzip".equals(mHeaders.getContentEncoding())) { - GZIPInputFilter gunzipper = new GZIPInputFilter(); - gunzipper.setDataCallback(callback); - gunzipper.setExceptionCallback(mReporter); - callback = gunzipper; - } - else if ("deflate".equals(mHeaders.getContentEncoding())) { - InflaterInputFilter inflater = new InflaterInputFilter(); - inflater.setExceptionCallback(mReporter); - inflater.setDataCallback(callback); - callback = inflater; - } - - if (!mHeaders.isChunked()) { - if (mHeaders.getContentLength() < 0) { - report(new Exception("not using chunked encoding, and no content-length found.")); - return; - } - FilteredDataCallback contentLengthWatcher = new FilteredDataCallback() { - int totalRead = 0; - @Override - public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) { - totalRead += bb.remaining(); - Assert.assertTrue(totalRead <= mHeaders.getContentLength()); - super.onDataAvailable(emitter, bb); - if (totalRead == mHeaders.getContentLength()) - AsyncHttpResponseImpl.this.report(null); - } - }; - contentLengthWatcher.setDataCallback(callback); - callback = contentLengthWatcher; - } - else { - ChunkedInputFilter chunker = new ChunkedInputFilter() { - @Override - public void onCompleted(Exception ex) { - AsyncHttpResponseImpl.this.report(ex); - } - }; - - chunker.setExceptionCallback(mReporter); - chunker.setDataCallback(callback); - callback = chunker; - } + DataCallback callback = Util.getBodyDecoder(this, mRawHeaders, mReporter); mExchange.setDataCallback(callback); } @@ -148,7 +97,6 @@ public class AsyncHttpResponseImpl extends FilteredDataCallback implements Async } else { onHeadersReceived(); -// System.out.println(mRawHeaders.toHeaderString()); } } catch (Exception ex) { diff --git a/AndroidAsync/src/com/koushikdutta/async/http/UrlEncodedFormWriter.java b/AndroidAsync/src/com/koushikdutta/async/http/UrlEncodedFormBody.java index 854dcfb..ccea283 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/UrlEncodedFormWriter.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/UrlEncodedFormBody.java @@ -5,12 +5,14 @@ import java.util.List; import org.apache.http.NameValuePair; +import com.koushikdutta.async.ByteBufferList; +import com.koushikdutta.async.DataEmitter; import com.koushikdutta.async.Util; import com.koushikdutta.async.callback.CompletedCallback; -public class UrlEncodedFormWriter implements AsyncHttpRequestContentWriter { +public class UrlEncodedFormBody implements AsyncHttpRequestBody { List<NameValuePair> mParameters; - public UrlEncodedFormWriter(List<NameValuePair> parameters) { + public UrlEncodedFormBody(List<NameValuePair> parameters) { mParameters = parameters; } @Override @@ -37,4 +39,14 @@ public class UrlEncodedFormWriter implements AsyncHttpRequestContentWriter { public String getContentType() { return "application/x-www-form-urlencoded"; } + @Override + public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) { + // TODO Auto-generated method stub + + } + @Override + public void onCompleted(Exception ex) { + // TODO Auto-generated method stub + + } } diff --git a/AndroidAsync/src/com/koushikdutta/async/http/Util.java b/AndroidAsync/src/com/koushikdutta/async/http/Util.java new file mode 100644 index 0000000..39a069c --- /dev/null +++ b/AndroidAsync/src/com/koushikdutta/async/http/Util.java @@ -0,0 +1,75 @@ +package com.koushikdutta.async.http; + +import junit.framework.Assert; + +import com.koushikdutta.async.ByteBufferList; +import com.koushikdutta.async.DataEmitter; +import com.koushikdutta.async.ExceptionCallback; +import com.koushikdutta.async.FilteredDataCallback; +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; +import com.koushikdutta.async.http.libcore.RawHeaders; +import com.koushikdutta.async.http.server.UnknownRequestBody; + +public class Util { + public static AsyncHttpRequestBody getBody(DataEmitter emitter, RawHeaders headers) { + return new UnknownRequestBody(emitter, headers.get("Content-Type")); + } + + public static DataCallback getBodyDecoder(DataCallback callback, RawHeaders headers, final ExceptionCallback reporter) { + if ("gzip".equals(headers.get("Content-Encoding"))) { + GZIPInputFilter gunzipper = new GZIPInputFilter(); + gunzipper.setDataCallback(callback); + gunzipper.setExceptionCallback(reporter); + callback = gunzipper; + } + else if ("deflate".equals(headers.get("Content-Encoding"))) { + InflaterInputFilter inflater = new InflaterInputFilter(); + inflater.setExceptionCallback(reporter); + inflater.setDataCallback(callback); + callback = inflater; + } + + int _contentLength; + try { + _contentLength = Integer.parseInt(headers.get("Content-Length")); + } + catch (Exception ex) { + _contentLength = -1; + } + final int contentLength = _contentLength; + if (!"chunked".equalsIgnoreCase(headers.get("Transfer-Encoding"))) { + if (contentLength < 0) { + reporter.onException(new Exception("not using chunked encoding, and no content-length found.")); + } + FilteredDataCallback contentLengthWatcher = new FilteredDataCallback() { + int totalRead = 0; + @Override + public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) { + totalRead += bb.remaining(); + Assert.assertTrue(totalRead <= contentLength); + super.onDataAvailable(emitter, bb); + if (totalRead == contentLength) + reporter.onException(null); + } + }; + contentLengthWatcher.setDataCallback(callback); + callback = contentLengthWatcher; + } + else { + ChunkedInputFilter chunker = new ChunkedInputFilter() { + @Override + public void onCompleted(Exception ex) { + reporter.onException(ex); + } + }; + + chunker.setExceptionCallback(reporter); + chunker.setDataCallback(callback); + callback = chunker; + } + return callback; + } +} diff --git a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServer.java b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServer.java index b930a55..5298e9d 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServer.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServer.java @@ -21,9 +21,13 @@ import com.koushikdutta.async.AsyncServerSocket; import com.koushikdutta.async.AsyncSocket; import com.koushikdutta.async.ExceptionCallback; import com.koushikdutta.async.ExceptionEmitter; +import com.koushikdutta.async.NullDataCallback; import com.koushikdutta.async.Util; import com.koushikdutta.async.callback.CompletedCallback; import com.koushikdutta.async.callback.ListenCallback; +import com.koushikdutta.async.http.AsyncHttpClient; +import com.koushikdutta.async.http.AsyncHttpGet; +import com.koushikdutta.async.http.AsyncHttpPost; import com.koushikdutta.async.http.libcore.RawHeaders; public class AsyncHttpServer implements ExceptionEmitter { @@ -40,6 +44,8 @@ public class AsyncHttpServer implements ExceptionEmitter { @Override protected void onHeadersReceived() { super.onHeadersReceived(); + + socket.setDataCallback(new NullDataCallback()); RawHeaders headers = getRawHeaders(); String statusLine = headers.getStatusLine(); @@ -167,7 +173,11 @@ public class AsyncHttpServer implements ExceptionEmitter { } public void get(String regex, HttpServerRequestCallback callback) { - addAction("GET", regex, callback); + addAction(AsyncHttpGet.METHOD, regex, callback); + } + + public void post(String regex, HttpServerRequestCallback callback) { + addAction(AsyncHttpPost.METHOD, regex, callback); } public static InputStream getAssetStream(final Context context, String asset) { diff --git a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerRequest.java b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerRequest.java index 51e7d38..17ade33 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerRequest.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerRequest.java @@ -3,9 +3,11 @@ package com.koushikdutta.async.http.server; import java.util.regex.Matcher; import com.koushikdutta.async.DataEmitter; +import com.koushikdutta.async.http.AsyncHttpRequestBody; import com.koushikdutta.async.http.libcore.RequestHeaders; public interface AsyncHttpServerRequest extends DataEmitter { public RequestHeaders getHeaders(); public Matcher getMatcher(); + public AsyncHttpRequestBody getBody(); } diff --git a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerRequestImpl.java b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerRequestImpl.java index 3034874..49b7c58 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerRequestImpl.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerRequestImpl.java @@ -3,9 +3,12 @@ package com.koushikdutta.async.http.server; import java.util.regex.Matcher; import com.koushikdutta.async.AsyncSocket; +import com.koushikdutta.async.ExceptionCallback; import com.koushikdutta.async.LineEmitter; import com.koushikdutta.async.LineEmitter.StringCallback; import com.koushikdutta.async.callback.DataCallback; +import com.koushikdutta.async.http.AsyncHttpRequestBody; +import com.koushikdutta.async.http.Util; import com.koushikdutta.async.http.libcore.RawHeaders; import com.koushikdutta.async.http.libcore.RequestHeaders; @@ -14,14 +17,22 @@ public class AsyncHttpServerRequestImpl implements AsyncHttpServerRequest { AsyncSocket mSocket; Matcher mMatcher; + private ExceptionCallback mReporter = new ExceptionCallback() { + @Override + public void onException(Exception error) { + report(error); + } + }; + protected void report(Exception e) { + if (mBody != null) + mBody.onCompleted(e); } protected void onHeadersReceived() { } protected void onNotHttp() { - } StringCallback mHeaderCallback = new StringCallback() { @@ -40,7 +51,8 @@ public class AsyncHttpServerRequestImpl implements AsyncHttpServerRequest { } else { onHeadersReceived(); -// System.out.println(mRawHeaders.toHeaderString()); + DataCallback callback = Util.getBodyDecoder(mBody = Util.getBody(mSocket, mRawHeaders), mRawHeaders, mReporter); + mSocket.setDataCallback(callback); } } catch (Exception ex) { @@ -55,11 +67,9 @@ public class AsyncHttpServerRequestImpl implements AsyncHttpServerRequest { void setSocket(AsyncSocket socket) { mSocket = socket; - - + LineEmitter liner = new LineEmitter(mSocket); liner.setLineCallback(mHeaderCallback); - } private RequestHeaders mHeaders = new RequestHeaders(null, mRawHeaders); @@ -88,4 +98,9 @@ public class AsyncHttpServerRequestImpl implements AsyncHttpServerRequest { return mMatcher; } + AsyncHttpRequestBody mBody; + @Override + public AsyncHttpRequestBody getBody() { + return mBody; + } } diff --git a/AndroidAsync/src/com/koushikdutta/async/http/server/UnknownRequestBody.java b/AndroidAsync/src/com/koushikdutta/async/http/server/UnknownRequestBody.java new file mode 100644 index 0000000..d1002c5 --- /dev/null +++ b/AndroidAsync/src/com/koushikdutta/async/http/server/UnknownRequestBody.java @@ -0,0 +1,31 @@ +package com.koushikdutta.async.http.server; + +import junit.framework.Assert; + +import com.koushikdutta.async.DataEmitter; +import com.koushikdutta.async.FilteredDataCallback; +import com.koushikdutta.async.http.AsyncHttpRequest; +import com.koushikdutta.async.http.AsyncHttpRequestBody; +import com.koushikdutta.async.http.AsyncHttpResponse; + +public class UnknownRequestBody extends FilteredDataCallback implements AsyncHttpRequestBody { + public UnknownRequestBody(DataEmitter emitter, String contentType) { + mContentType = contentType; + emitter.setDataCallback(this); + } + + @Override + public void write(AsyncHttpRequest request, AsyncHttpResponse sink) { + Assert.fail(); + } + + private String mContentType; + @Override + public String getContentType() { + return mContentType; + } + + @Override + public void onCompleted(Exception ex) { + } +} |