use of com.koushikdutta.async.LineEmitter in project AndroidAsync by koush.
the class MultipartFormDataBody method onBoundaryStart.
@Override
protected void onBoundaryStart() {
final Headers headers = new Headers();
liner = new LineEmitter();
liner.setLineCallback(new StringCallback() {
@Override
public void onStringAvailable(String s) {
if (!"\r".equals(s)) {
headers.addLine(s);
} else {
handleLast();
liner = null;
setDataCallback(null);
Part part = new Part(headers);
if (mCallback != null)
mCallback.onPart(part);
if (getDataCallback() == null) {
if (part.isFile()) {
setDataCallback(new NullDataCallback());
return;
}
lastName = part.getName();
last = new ByteBufferList();
setDataCallback(new DataCallback() {
@Override
public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) {
bb.get(last);
}
});
}
}
}
});
setDataCallback(liner);
}
use of com.koushikdutta.async.LineEmitter in project AndroidAsync by koush.
the class AsyncHttpServerRequestImpl method setSocket.
void setSocket(AsyncSocket socket) {
mSocket = socket;
LineEmitter liner = new LineEmitter();
mSocket.setDataCallback(liner);
liner.setLineCallback(mHeaderCallback);
mSocket.setEndCallback(new NullCompletedCallback());
}
use of com.koushikdutta.async.LineEmitter in project AndroidAsync by koush.
the class AsyncSSLSocketMiddleware method wrapCallback.
@Override
protected ConnectCallback wrapCallback(final GetSocketData data, final Uri uri, final int port, final boolean proxied, final ConnectCallback callback) {
return new ConnectCallback() {
@Override
public void onConnectCompleted(Exception ex, final AsyncSocket socket) {
if (ex != null) {
callback.onConnectCompleted(ex, socket);
return;
}
if (!proxied) {
tryHandshake(socket, data, uri, port, callback);
return;
}
// this SSL connection is proxied, must issue a CONNECT request to the proxy server
// http://stackoverflow.com/a/6594880/704837
// some proxies also require 'Host' header, it should be safe to provide it every time
String connect = String.format(Locale.ENGLISH, "CONNECT %s:%s HTTP/1.1\r\nHost: %s\r\n\r\n", uri.getHost(), port, uri.getHost());
data.request.logv("Proxying: " + connect);
Util.writeAll(socket, connect.getBytes(), new CompletedCallback() {
@Override
public void onCompleted(Exception ex) {
if (ex != null) {
callback.onConnectCompleted(ex, socket);
return;
}
LineEmitter liner = new LineEmitter();
liner.setLineCallback(new LineEmitter.StringCallback() {
String statusLine;
@Override
public void onStringAvailable(String s) {
data.request.logv(s);
if (statusLine == null) {
statusLine = s.trim();
if (!statusLine.matches("HTTP/1.\\d 2\\d\\d .*")) {
// connect response is allowed to have any 2xx status code
socket.setDataCallback(null);
socket.setEndCallback(null);
callback.onConnectCompleted(new IOException("non 2xx status line: " + statusLine), socket);
}
} else if (TextUtils.isEmpty(s.trim())) {
// skip all headers, complete handshake once empty line is received
socket.setDataCallback(null);
socket.setEndCallback(null);
tryHandshake(socket, data, uri, port, callback);
}
}
});
socket.setDataCallback(liner);
socket.setEndCallback(new CompletedCallback() {
@Override
public void onCompleted(Exception ex) {
if (!socket.isOpen() && ex == null)
ex = new IOException("socket closed before proxy connect response");
callback.onConnectCompleted(ex, socket);
}
});
}
});
}
};
}
use of com.koushikdutta.async.LineEmitter in project AndroidAsync by koush.
the class LineEmitterTests method testFunnyCharacter.
public void testFunnyCharacter() {
final String stuff = "é\n";
LineEmitter emitter = new LineEmitter(Charsets.UTF_8);
emitter.setLineCallback(new LineEmitter.StringCallback() {
@Override
public void onStringAvailable(String s) {
assertEquals(s + '\n', stuff);
}
});
assertEquals(stuff.charAt(0), 233);
ByteBufferList bb = new ByteBufferList(ByteBuffer.wrap(stuff.getBytes(Charsets.UTF_8)));
emitter.onDataAvailable(null, bb);
}
use of com.koushikdutta.async.LineEmitter in project AndroidAsync by koush.
the class HttpTransportMiddleware method exchangeHeaders.
@Override
public boolean exchangeHeaders(final OnExchangeHeaderData data) {
Protocol p = Protocol.get(data.protocol);
if (p != null && p != Protocol.HTTP_1_0 && p != Protocol.HTTP_1_1)
return super.exchangeHeaders(data);
AsyncHttpRequest request = data.request;
AsyncHttpRequestBody requestBody = data.request.getBody();
if (requestBody != null) {
if (requestBody.length() >= 0) {
request.getHeaders().set("Content-Length", String.valueOf(requestBody.length()));
data.response.sink(data.socket);
} else if ("close".equals(request.getHeaders().get("Connection"))) {
data.response.sink(data.socket);
} else {
request.getHeaders().set("Transfer-Encoding", "Chunked");
data.response.sink(new ChunkedOutputFilter(data.socket));
}
}
String rl = request.getRequestLine().toString();
String rs = request.getHeaders().toPrefixString(rl);
byte[] rsBytes = rs.getBytes();
// try to get the request body in the same packet as the request headers... if it will fit
// in the max MTU (1540 or whatever).
final boolean waitForBody = requestBody != null && requestBody.length() >= 0 && requestBody.length() + rsBytes.length < 1024;
final BufferedDataSink bsink;
final DataSink headerSink;
if (waitForBody) {
// force buffering of headers
bsink = new BufferedDataSink(data.response.sink());
bsink.forceBuffering(true);
data.response.sink(bsink);
headerSink = bsink;
} else {
bsink = null;
headerSink = data.socket;
}
request.logv("\n" + rs);
final CompletedCallback sentCallback = data.sendHeadersCallback;
Util.writeAll(headerSink, rsBytes, new CompletedCallback() {
@Override
public void onCompleted(Exception ex) {
Util.end(sentCallback, ex);
// flush headers and any request body that was written by the callback
if (bsink != null) {
bsink.forceBuffering(false);
bsink.setMaxBuffer(0);
}
}
});
LineEmitter.StringCallback headerCallback = new LineEmitter.StringCallback() {
Headers mRawHeaders = new Headers();
String statusLine;
@Override
public void onStringAvailable(String s) {
try {
s = s.trim();
if (statusLine == null) {
statusLine = s;
} else if (!TextUtils.isEmpty(s)) {
mRawHeaders.addLine(s);
} else {
String[] parts = statusLine.split(" ", 3);
if (parts.length < 2)
throw new Exception(new IOException("Not HTTP"));
data.response.headers(mRawHeaders);
String protocol = parts[0];
data.response.protocol(protocol);
data.response.code(Integer.parseInt(parts[1]));
data.response.message(parts.length == 3 ? parts[2] : "");
data.receiveHeadersCallback.onCompleted(null);
// socket may get detached after headers (websocket)
AsyncSocket socket = data.response.socket();
if (socket == null)
return;
DataEmitter emitter;
// return content length, etc, which will confuse the body decoder
if (AsyncHttpHead.METHOD.equalsIgnoreCase(data.request.getMethod())) {
emitter = HttpUtil.EndEmitter.create(socket.getServer(), null);
} else {
emitter = HttpUtil.getBodyDecoder(socket, Protocol.get(protocol), mRawHeaders, false);
}
data.response.emitter(emitter);
}
} catch (Exception ex) {
data.receiveHeadersCallback.onCompleted(ex);
}
}
};
LineEmitter liner = new LineEmitter();
data.socket.setDataCallback(liner);
liner.setLineCallback(headerCallback);
return true;
}
Aggregations