|
@@ -9,14 +9,12 @@ import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
import java.nio.ByteBuffer;
|
|
|
+import java.util.Arrays;
|
|
|
|
|
|
public class SimpleHttpProtocol implements Protocol<ByteBuffer, HttpEntity> {
|
|
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(SimpleHttpProtocol.class);
|
|
|
|
|
|
- private static final String CONTENT_LENGTH = "CONTENT-LENGTH";
|
|
|
- private static final String TRANSFER_ENCODING = "TRANSFER-ENCODING";
|
|
|
- private static final String CHUNKED = "CHUNKED";
|
|
|
private static final byte CR13 = (byte) 13; // \CR \r
|
|
|
private static final byte LF10 = (byte) 10; // \LF \n
|
|
|
private static final byte SPACE0 = (byte) 32; // \SP
|
|
@@ -40,22 +38,22 @@ public class SimpleHttpProtocol implements Protocol<ByteBuffer, HttpEntity> {
|
|
|
}
|
|
|
|
|
|
if (!httpEntity.headerComplete() && byteBuffer.hasRemaining()) { //解析header
|
|
|
- readHeader(byteBuffer, session, httpEntity);
|
|
|
+ readHeader(byteBuffer, httpEntity);
|
|
|
}
|
|
|
|
|
|
- if (httpEntity.headerComplete() && httpEntity.bodyBuffer != null && byteBuffer.hasRemaining()) {// 解析body
|
|
|
- readBody(byteBuffer, session, httpEntity);
|
|
|
- }
|
|
|
-
|
|
|
- if (httpEntity.complete()) {
|
|
|
- session.setAttribute(httpEntityKey, null);
|
|
|
- return httpEntity;
|
|
|
+ if (httpEntity.headerComplete()) {
|
|
|
+ if (httpEntity.complete()) {
|
|
|
+ session.setAttribute(httpEntityKey, null);
|
|
|
+ return httpEntity;
|
|
|
+ }
|
|
|
+ if (httpEntity.bodyBuffer != null && byteBuffer.hasRemaining()) { // 解析request body
|
|
|
+ readBody(byteBuffer, httpEntity);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- private void readHeader(ByteBuffer byteBuffer, Session session, HttpRequestEntity httpEntity) {
|
|
|
+ private void readHeader(ByteBuffer byteBuffer, HttpRequestEntity httpEntity) {
|
|
|
try {
|
|
|
ByteBuffer buf = byteBuffer.duplicate();
|
|
|
int startPos = 0;
|
|
@@ -71,6 +69,11 @@ public class SimpleHttpProtocol implements Protocol<ByteBuffer, HttpEntity> {
|
|
|
httpEntity.crNum = 0;
|
|
|
httpEntity.lfNum = 0;
|
|
|
}
|
|
|
+
|
|
|
+ if (httpEntity.headerComplete()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
if (httpEntity.isReadHeadLine()) {
|
|
|
if (b == SPACE0) {
|
|
|
int len = endPos - startPos - 1;
|
|
@@ -80,21 +83,16 @@ public class SimpleHttpProtocol implements Protocol<ByteBuffer, HttpEntity> {
|
|
|
buf.position(startPos);
|
|
|
if (httpEntity.method == null) {
|
|
|
httpEntity.method = new String(bytes);
|
|
|
- continue;
|
|
|
- }
|
|
|
- if (httpEntity.url == null) {
|
|
|
+ } else if (httpEntity.url == null) {
|
|
|
httpEntity.url = new String(bytes);
|
|
|
- continue;
|
|
|
}
|
|
|
- }
|
|
|
- if (httpEntity.crNum == 1 && httpEntity.lfNum == 1) {
|
|
|
+ } else if (httpEntity.crNum == 1 && httpEntity.lfNum == 1) {
|
|
|
int len = endPos - startPos - 2;
|
|
|
byte[] bytes = new byte[len];
|
|
|
buf.get(bytes, 0, len);
|
|
|
startPos = endPos;
|
|
|
buf.position(startPos);
|
|
|
httpEntity.protocol = new String(bytes);
|
|
|
- continue;
|
|
|
}
|
|
|
} else {
|
|
|
if (b == COLON && httpEntity.tmp == null) {
|
|
@@ -103,26 +101,23 @@ public class SimpleHttpProtocol implements Protocol<ByteBuffer, HttpEntity> {
|
|
|
buf.get(bytes, 0, len);
|
|
|
startPos = endPos;
|
|
|
buf.position(startPos);
|
|
|
- httpEntity.tmp = new String(bytes);
|
|
|
- continue;
|
|
|
- }
|
|
|
- if (httpEntity.crNum == 1 && httpEntity.lfNum == 1) {
|
|
|
+ httpEntity.tmp = bytes;
|
|
|
+ } else if (httpEntity.crNum == 1 && httpEntity.lfNum == 1) {
|
|
|
int len = endPos - startPos - 2;
|
|
|
byte[] bytes = new byte[len];
|
|
|
buf.get(bytes, 0, len);
|
|
|
startPos = endPos;
|
|
|
buf.position(startPos);
|
|
|
- String value = new String(bytes);
|
|
|
- httpEntity.setHeader(httpEntity.tmp, value);
|
|
|
+ httpEntity.setHeader(httpEntity.tmp, bytes);
|
|
|
httpEntity.tmp = null;
|
|
|
- if (CONTENT_LENGTH.equals(httpEntity.tmp)) {
|
|
|
- httpEntity.contentLength = (value == null ? 0 : Integer.valueOf(value));
|
|
|
- httpEntity.bodyBuffer = ByteBuffer.allocate(httpEntity.contentLength);//TODO can pooling
|
|
|
- }
|
|
|
- if (CHUNKED.equals(httpEntity.tmp)) {
|
|
|
- httpEntity.chunked = true;
|
|
|
+// if (Arrays.equals(CONTENT_LENGTH, httpEntity.tmp)) {
|
|
|
+// httpEntity.contentLength = (value == null ? 0 : Integer.valueOf(value));
|
|
|
+// httpEntity.bodyBuffer = ByteBuffer.allocate(httpEntity.contentLength);//TODO can pooling
|
|
|
+// }
|
|
|
+// if (Arrays.equals(CHUNKED, httpEntity.tmp)) {
|
|
|
+// httpEntity.chunked = true;
|
|
|
// throw new RuntimeException("not support chunked");
|
|
|
- }
|
|
|
+// }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -131,7 +126,7 @@ public class SimpleHttpProtocol implements Protocol<ByteBuffer, HttpEntity> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void readBody(ByteBuffer byteBuffer, Session session, HttpRequestEntity httpEntity) {
|
|
|
+ private void readBody(ByteBuffer byteBuffer, HttpRequestEntity httpEntity) {
|
|
|
try {
|
|
|
if (httpEntity.bodyBuffer.hasRemaining()) {
|
|
|
if (byteBuffer.remaining() <= httpEntity.bodyBuffer.remaining()) {
|
|
@@ -152,8 +147,8 @@ public class SimpleHttpProtocol implements Protocol<ByteBuffer, HttpEntity> {
|
|
|
|
|
|
@Override
|
|
|
public ByteBuffer encode(HttpEntity httpEntity, Session session) {
|
|
|
+ ByteBuffer byteBuffer = session.getHandler().getPooledByteBuff().get();
|
|
|
HttpResponseEntity httpResponseEntity = (HttpResponseEntity) httpEntity;
|
|
|
-
|
|
|
- return httpResponseEntity.toBuffer();
|
|
|
+ return httpResponseEntity.toBuffer(byteBuffer);
|
|
|
}
|
|
|
}
|