You are viewing a plain text version of this content. The canonical link for it is here.
Posted to awf-commits@incubator.apache.org by sl...@apache.org on 2011/09/25 23:21:31 UTC
svn commit: r1175622 - in /incubator/deft/sandbox/src:
main/java/org/apache/deft/io/ main/java/org/apache/deft/web/
main/java/org/apache/deft/web/http/ test/java/org/apache/deft/web/
test/java/org/apache/deft/web/http/
Author: slemesle
Date: Sun Sep 25 23:21:31 2011
New Revision: 1175622
URL: http://svn.apache.org/viewvc?rev=1175622&view=rev
Log:
First multi-thread test in HttpServer
Improve new Http parser with length control and JavaDoc
Ensure IOLoop get stopped when server stops in multi-thread context
Modified:
incubator/deft/sandbox/src/main/java/org/apache/deft/io/IOLoop.java
incubator/deft/sandbox/src/main/java/org/apache/deft/web/HttpServer.java
incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpBufferedLexer.java
incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpParsingContext.java
incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpRequestImpl.java
incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpRequestParser.java
incubator/deft/sandbox/src/test/java/org/apache/deft/web/DeftSystemTest.java
incubator/deft/sandbox/src/test/java/org/apache/deft/web/HttpServerTest.java
incubator/deft/sandbox/src/test/java/org/apache/deft/web/http/HttpBufferedLexerTest.java
Modified: incubator/deft/sandbox/src/main/java/org/apache/deft/io/IOLoop.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/apache/deft/io/IOLoop.java?rev=1175622&r1=1175621&r2=1175622&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/apache/deft/io/IOLoop.java (original)
+++ incubator/deft/sandbox/src/main/java/org/apache/deft/io/IOLoop.java Sun Sep 25 23:21:31 2011
@@ -19,8 +19,6 @@
*/
package org.apache.deft.io;
-import static com.google.common.collect.Collections2.transform;
-
import java.io.IOException;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.ClosedChannelException;
@@ -34,6 +32,9 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import org.apache.deft.io.callback.CallbackManager;
import org.apache.deft.io.callback.JMXDebuggableCallbackManager;
import org.apache.deft.io.timeout.JMXDebuggableTimeoutManager;
@@ -43,10 +44,7 @@ import org.apache.deft.util.MXBeanUtil;
import org.apache.deft.web.AsyncCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
+import static com.google.common.collect.Collections2.transform;
public class IOLoop implements IOLoopMXBean {
@@ -234,4 +232,12 @@ public class IOLoop implements IOLoopMXB
});
return Lists.newLinkedList(readables);
}
+
+ /**
+ * Checks wether this IOLoop is running or not
+ * @return
+ */
+ public boolean isRunning() {
+ return running;
+ }
}
Modified: incubator/deft/sandbox/src/main/java/org/apache/deft/web/HttpServer.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/apache/deft/web/HttpServer.java?rev=1175622&r1=1175621&r2=1175622&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/apache/deft/web/HttpServer.java (original)
+++ incubator/deft/sandbox/src/main/java/org/apache/deft/web/HttpServer.java Sun Sep 25 23:21:31 2011
@@ -19,13 +19,7 @@
*/
package org.apache.deft.web;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.ServerSocketChannel;
-import java.util.List;
-import java.util.Map;
-
+import com.google.common.collect.Lists;
import org.apache.deft.configuration.AnnotationsScanner;
import org.apache.deft.configuration.Configuration;
import org.apache.deft.io.IOLoop;
@@ -35,7 +29,13 @@ import org.apache.deft.web.http.HttpProt
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.collect.Lists;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.ServerSocketChannel;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
public class HttpServer {
@@ -49,11 +49,13 @@ public class HttpServer {
private final Application application;
+
public HttpServer(Configuration configuration) {
application = createApplication(configuration.getHandlerPackage());
application.setStaticContentDir(configuration.getStaticDirectory());
application.setConfiguration(configuration);
+
}
protected Application createApplication(String packageName) {
@@ -103,6 +105,8 @@ public class HttpServer {
}
public void start(int numThreads) {
+
+ final CountDownLatch loopsLatch = new CountDownLatch(numThreads);
for (int i = 0; i < numThreads; i++) {
final IOLoop ioLoop = new IOLoop();
ioLoops.add(ioLoop);
@@ -112,22 +116,41 @@ public class HttpServer {
@Override
public void run() {
registerHandler(ioLoop, protocol);
+ loopsLatch.countDown();
ioLoop.start();
}
}).start();
}
+ try {
+ loopsLatch.await();
+ } catch (InterruptedException e) {
+ logger.error("Interrupted while waiting for all IOLoop to start", e);
+ }
}
/**
* Unbinds the port and shutdown the HTTP server
+ * using a callback to execute the stop from the IOLoop thread
+ *
*/
public void stop() {
logger.debug("Stopping HTTP server");
- for (IOLoop ioLoop : ioLoops) {
- // TODO RS 110527 Should probably do this in each IOLoop through an
- // AsyncCallback
- // (hint: ioloop.addCallback(..))
- Closeables.closeQuietly(ioLoop, serverChannel);
+ final CountDownLatch loopsLatch = new CountDownLatch(ioLoops.size());
+ for (final IOLoop ioLoop : ioLoops) {
+ // Use a callback to stop the loops from theire Threads
+ ioLoop.addCallback(new AsyncCallback(){
+ @Override
+ public void onCallback() {
+ Closeables.closeQuietly(ioLoop, serverChannel);
+ ioLoop.stop();
+ loopsLatch.countDown();
+ }
+ });
+ }
+ try {
+ loopsLatch.await();
+ } catch (InterruptedException e) {
+ logger.error("Interrupted while waiting for all IOLoop to stop",e);
}
}
@@ -136,4 +159,11 @@ public class HttpServer {
);
}
+ /**
+ * Added for test purpose
+ * @return
+ */
+ protected List<IOLoop> getIoLoops(){
+ return ioLoops;
+ }
}
Modified: incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpBufferedLexer.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpBufferedLexer.java?rev=1175622&r1=1175621&r2=1175622&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpBufferedLexer.java (original)
+++ incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpBufferedLexer.java Sun Sep 25 23:21:31 2011
@@ -19,8 +19,6 @@
*/
package org.apache.deft.web.http;
-import java.nio.ByteBuffer;
-
/**
* Lexer class responsible for lexing an HTTP stream into tokens.
* The tokens are composed of Method, URI, Protocol version, Header name and header value.
@@ -38,6 +36,9 @@ public class HttpBufferedLexer {
static final int LINE_MAX_SIZE = 500;
+ /**
+ * Use ' ' as separator and forbids CR / LF
+ */
static final StopChars SP_SEPARATOR = new StopChars() {
public boolean isSeparator(int ptr) {
@@ -50,6 +51,9 @@ public class HttpBufferedLexer {
}
};
+ /**
+ * Use CR or LF as separator and forbids nothing
+ */
static final StopChars CRLF_SEPARATOR = new StopChars() {
public boolean isSeparator(int ptr) {
@@ -61,6 +65,9 @@ public class HttpBufferedLexer {
}
};
+ /**
+ * Use ':' as separator and forbids CR or LF
+ */
static final StopChars HEADER_NAME_SEPARATOR = new StopChars() {
public boolean isSeparator(int ptr) {
@@ -71,8 +78,14 @@ public class HttpBufferedLexer {
return ptr == CR || ptr == LF;
}
};
-
- private ErrorStatus status = ErrorStatus.OK;
+
+ static final int METHOD_LENGTH = 7;
+ static final int URI_LENGTH = 255;
+ static final int VERSION_LENGTH = 10;
+ static final int HEADER_NAME_LENGTH = 30;
+ static final int HEADER_VALUE_LENGTH = 300;
+
+ private ErrorStatus status = ErrorStatus.OK;
enum ErrorStatus {
OK,
@@ -89,12 +102,13 @@ public class HttpBufferedLexer {
*/
public int nextToken(HttpParsingContext context){
int res = -1;
+ context.clearTokenBuffer(); // Clean the token buffer if we start a new token akka last token was complete
switch (context.currentType){
case REQUEST_LINE: { // read the first token of the request line METHOD
if (skipWhiteSpaceAndLine(context)){
// Get method token
- res = nextWord(context, HttpParsingContext.TokenType.REQUEST_METHOD, SP_SEPARATOR);
+ res = nextWord(context, HttpParsingContext.TokenType.REQUEST_METHOD, SP_SEPARATOR, METHOD_LENGTH);
}else{ // EOS reached with no data
return 0;
@@ -103,17 +117,17 @@ public class HttpBufferedLexer {
}
case REQUEST_METHOD:{
// Get URI token
- res = nextWord(context, HttpParsingContext.TokenType.REQUEST_URI, SP_SEPARATOR);
+ res = nextWord(context, HttpParsingContext.TokenType.REQUEST_URI, SP_SEPARATOR, URI_LENGTH);
break;
}
case REQUEST_URI:{ // request version
- res = nextWord(context, HttpParsingContext.TokenType.HTTP_VERSION, CRLF_SEPARATOR);
+ res = nextWord(context, HttpParsingContext.TokenType.HTTP_VERSION, CRLF_SEPARATOR, VERSION_LENGTH);
break;
}
case HTTP_VERSION:{ // First header line
context.skips = 0;
if (!skipEndOfLine(context)){
- res = nextWord(context, HttpParsingContext.TokenType.HEADER_NAME, HEADER_NAME_SEPARATOR);
+ res = nextWord(context, HttpParsingContext.TokenType.HEADER_NAME, HEADER_NAME_SEPARATOR, HEADER_NAME_LENGTH);
}else {
context.setBodyFound();
res = 1;
@@ -121,15 +135,16 @@ public class HttpBufferedLexer {
break;
}
case HEADER_NAME:{ // header value
- res = nextWord(context, HttpParsingContext.TokenType.HEADER_VALUE, CRLF_SEPARATOR);
+ res = nextWord(context, HttpParsingContext.TokenType.HEADER_VALUE, CRLF_SEPARATOR, HEADER_VALUE_LENGTH);
break;
}case HEADER_VALUE:{ // Might be a header value for multiline headers, a header name, or Body
context.skips = 0;
if (!skipEndOfLine(context)){
if (context.currentPointer == SP || context.currentPointer == TAB){
- res = nextWord(context, HttpParsingContext.TokenType.HEADER_VALUE,CRLF_SEPARATOR );
+ context.deleteFirstCharFromTokenBuffer(); // Don't keep the first whitespace character
+ res = nextWord(context, HttpParsingContext.TokenType.HEADER_VALUE,CRLF_SEPARATOR, HEADER_VALUE_LENGTH);
}else {
- res = nextWord(context, HttpParsingContext.TokenType.HEADER_NAME, HEADER_NAME_SEPARATOR);
+ res = nextWord(context, HttpParsingContext.TokenType.HEADER_NAME, HEADER_NAME_SEPARATOR, HEADER_NAME_LENGTH);
}
}else {
context.setBodyFound();
@@ -137,7 +152,7 @@ public class HttpBufferedLexer {
}
break;
}
- default:{ // If BODY or other nothing todo
+ default:{ // If BODY or other nothing to do
res = 0;
}
}
@@ -150,26 +165,36 @@ public class HttpBufferedLexer {
while(context.hasRemaining()){
if (context.incrementAndGetPointer() != CR && context.currentPointer != LF && context.currentPointer != SP){
- context.startPreviousPosition();
+ context.appendChar();
return true;
}
}
return false;
}
- public int nextWord(HttpParsingContext context, HttpParsingContext.TokenType type, StopChars stopChars){
+ /**
+ *
+ */
+ public int nextWord(HttpParsingContext context, HttpParsingContext.TokenType type, StopChars stopChars, int maxLen){
int currentChar = 0;
-
- while(context.buffer.hasRemaining()){
- currentChar = context.buffer.get();
+
+ while(context.hasRemaining()){
+ currentChar = context.incrementAndGetPointer();
if (stopChars.isForbidden(currentChar)){
return -1; // Bad format Request should not contain this char at this point
} else if (stopChars.isSeparator(currentChar)){
+ if (context.tokenGreaterThan(maxLen)){
+ return -1; // Too long
+ }
context.storeCompleteToken(type);
return 1;
}
+ context.appendChar();
}
// No errors but the token is not complete
+ if (context.tokenGreaterThan(maxLen)){
+ return -1; // Too long
+ }
context.storeIncompleteToken();
return 0;
}
@@ -184,7 +209,7 @@ public class HttpBufferedLexer {
while(context.hasRemaining()){
if (context.incrementAndGetPointer() != CR && context.currentPointer != LF){
- context.startPreviousPosition();
+ context.appendChar();
return false;
}else if (context.skips >= 2){ // Here we got CRLFCRLF combination so rest is the body
return true;
@@ -197,11 +222,19 @@ public class HttpBufferedLexer {
}
-
+ /**
+ * Defines the Stop characters to use (Separator and Forbidden)
+ */
private interface StopChars {
+ /**
+ * Tells wether this char is a separator endind the current Token under parsing
+ */
boolean isSeparator(int ptr);
+ /**
+ * Tells wether this char is forbidden or not. If forbidden then parsing will raise an error
+ */
boolean isForbidden(int ptr);
}
Modified: incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpParsingContext.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpParsingContext.java?rev=1175622&r1=1175621&r2=1175622&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpParsingContext.java (original)
+++ incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpParsingContext.java Sun Sep 25 23:21:31 2011
@@ -19,8 +19,6 @@
*/
package org.apache.deft.web.http;
-import com.google.common.base.Charsets;
-
import java.nio.ByteBuffer;
/**
@@ -30,7 +28,6 @@ import java.nio.ByteBuffer;
public class HttpParsingContext {
-
enum TokenType{
REQUEST_LINE,
REQUEST_METHOD,
@@ -39,11 +36,10 @@ public class HttpParsingContext {
HEADER_NAME,
HEADER_VALUE,
BODY;
+
}
-
- ByteBuffer buffer;
- int startPosition = 0;
+ ByteBuffer buffer;
TokenType currentType = TokenType.REQUEST_LINE;
@@ -62,13 +58,12 @@ public class HttpParsingContext {
return currentPointer;
}
+ public boolean tokenGreaterThan(int maxLen) {
+ return tokenValue.length() > maxLen;
+ }
+
void setBuffer(ByteBuffer buffer){
this.buffer = buffer;
- if (buffer != null){
- startPosition = buffer.position();
- } else {
- startPosition = 0;
- }
}
boolean hasRemaining(){
@@ -84,27 +79,34 @@ public class HttpParsingContext {
return TokenType.BODY.equals(currentType);
}
- void startPreviousPosition(){
- startPosition = buffer.position()-1;
+ void clearTokenBuffer(){
+ if (complete){ // Free buffer when last was complete
+ tokenValue.delete(0, Integer.MAX_VALUE);
+ }
+ }
+
+
+ void deleteFirstCharFromTokenBuffer(){
+ tokenValue.deleteCharAt(0);
+ }
+
+ void appendChar(){
+ tokenValue.append((char)currentPointer);
}
/**
* Stores the token value and define the completeness
*/
void storeIncompleteToken(){
- storeTokenValue(currentType, false, buffer.position() - startPosition);
+ storeTokenValue(currentType, false);
}
void storeCompleteToken(TokenType type){
- storeTokenValue(type, true, buffer.position() - startPosition -1);
+ storeTokenValue(type, true);
}
- private void storeTokenValue(TokenType type, boolean _complete, int endPosition){
- if (complete){ // Free buffer when last was complete
- tokenValue.delete(0, Integer.MAX_VALUE);
- }
- tokenValue.append(new String (buffer.array(), startPosition, endPosition, Charsets.ISO_8859_1));
- startPosition = buffer.position();
+ private void storeTokenValue(TokenType type, boolean _complete){
+
currentType = type;
complete = _complete;
}
Modified: incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpRequestImpl.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpRequestImpl.java?rev=1175622&r1=1175621&r2=1175622&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpRequestImpl.java (original)
+++ incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpRequestImpl.java Sun Sep 25 23:21:31 2011
@@ -27,15 +27,14 @@ import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
-import org.apache.deft.io.IOLoop;
-import org.apache.deft.io.buffer.DynamicByteBuffer;
-import org.apache.deft.util.ArrayUtil;
-import org.apache.deft.web.http.protocol.HttpVerb;
-
import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Maps;
+import org.apache.deft.io.IOLoop;
+import org.apache.deft.io.buffer.DynamicByteBuffer;
+import org.apache.deft.util.ArrayUtil;
+import org.apache.deft.web.http.protocol.HttpVerb;
public class HttpRequestImpl implements HttpRequest {
Modified: incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpRequestParser.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpRequestParser.java?rev=1175622&r1=1175621&r2=1175622&view=diff
==============================================================================
--- incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpRequestParser.java (original)
+++ incubator/deft/sandbox/src/main/java/org/apache/deft/web/http/HttpRequestParser.java Sun Sep 25 23:21:31 2011
@@ -21,7 +21,6 @@ package org.apache.deft.web.http;
import java.nio.ByteBuffer;
-import com.google.common.base.Charsets;
import org.apache.deft.io.buffer.DynamicByteBuffer;
import org.apache.deft.web.http.protocol.HttpVerb;
import org.slf4j.Logger;
@@ -31,6 +30,8 @@ import org.slf4j.LoggerFactory;
/**
* Builds HttpRequest using a given ByteBuffer and already existing request object (unfinished).
+ * Uses an HttpBufferedLexer to retrieve Http Tokens and the HttpParsingContext stored in the request
+ * to maintain parsing state.
*/
public class HttpRequestParser {
@@ -49,10 +50,13 @@ public class HttpRequestParser {
}
/**
+ * Parse the data in the given buffer as an Http request. It handles segmented buffer
+ * when the given request is not null.
*
- * @param buffer
- * @param result
- * @return
+ * @param buffer ByteBuffer containing data to parse
+ * @param result null if it's a new request or the incomplete request
+ * @return new HttpRequestImpl if result is null representing a complete or incomplete request
+ * on error, it will return a MalformedHttpRequest.
*/
public HttpRequestImpl parseRequestBuffer(ByteBuffer buffer,HttpRequestImpl result){
@@ -64,7 +68,6 @@ public class HttpRequestParser {
HttpParsingContext context = result.getContext();
context.setBuffer(buffer);
-// LOG.warn("Request buffer is {}", new String (buffer.array(), Charsets.ISO_8859_1));
// while no errors and buffer not finished
while ((status = lexer.nextToken(context)) > 0){
switch (context.currentType){
@@ -95,7 +98,6 @@ public class HttpRequestParser {
// Copy body data to the request bodyBuffer
if (result.getContentLength() > 0){
pushRemainingToBody(context.buffer, result.getBodyBuffer(), result.getContentLength());
- // LOG.warn("Body size is {} and contentLength is {}", result.getBodyBuffer().position(), result.getContentLength());
}
// TODO: Implement chunked encoding here
}
@@ -107,6 +109,11 @@ public class HttpRequestParser {
return result;
}
+ /**
+ * Fill's the body buffer with the data retrieved from the given buffer starting
+ * at buffer position and copying given size byte.<br/>
+ * This will ensure that body buffer does not contain more than size byte.
+ */
private void pushRemainingToBody(ByteBuffer buffer, DynamicByteBuffer body, int size){
// If buffer is empty or there is no clength then skip this
if (size == 0 || !buffer.hasRemaining()){
Modified: incubator/deft/sandbox/src/test/java/org/apache/deft/web/DeftSystemTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/test/java/org/apache/deft/web/DeftSystemTest.java?rev=1175622&r1=1175621&r2=1175622&view=diff
==============================================================================
--- incubator/deft/sandbox/src/test/java/org/apache/deft/web/DeftSystemTest.java (original)
+++ incubator/deft/sandbox/src/test/java/org/apache/deft/web/DeftSystemTest.java Sun Sep 25 23:21:31 2011
@@ -19,11 +19,6 @@
*/
package org.apache.deft.web;
-import static org.apache.deft.web.DeftSystemTestHandlers.expectedPayload;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@@ -43,30 +38,13 @@ import java.util.concurrent.ExecutorServ
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
+import com.ning.http.client.AsyncCompletionHandler;
+import com.ning.http.client.AsyncHttpClient;
+import com.ning.http.client.Response;
import org.apache.deft.configuration.Configuration;
import org.apache.deft.io.IOLoop;
import org.apache.deft.io.timeout.Timeout;
-import org.apache.deft.web.DeftSystemTestHandlers.AsyncThrowingHttpExceptionRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.AuthenticatedRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.CapturingRequestRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.ChunkedRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.DeleteRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.EchoingPostBodyRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.ExampleRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.KeyValueStoreExampleRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.MovedPermanentlyRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.NoBodyRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.PostRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.PutRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.QueryParamsRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.ThrowingHttpExceptionRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.UserDefinedStaticContentHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.WFFFWFFFRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.WFWFRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.WRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.WWFWRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers.WWRequestHandler;
-import org.apache.deft.web.DeftSystemTestHandlers._450KBResponseEntityRequestHandler;
+import org.apache.deft.web.DeftSystemTestHandlers.*;
import org.apache.deft.web.handler.RequestHandler;
import org.apache.deft.web.http.client.AsynchronousHttpClient;
import org.apache.deft.web.http.protocol.HttpStatus;
@@ -88,10 +66,8 @@ import org.apache.http.params.HttpProtoc
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
-
-import com.ning.http.client.AsyncCompletionHandler;
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.Response;
+import static org.junit.Assert.*;
+import static org.apache.deft.web.DeftSystemTestHandlers.expectedPayload;
/**
* General tests of server operation.
@@ -955,7 +931,10 @@ public class DeftSystemTest {
assertEquals(expected.length() + "", response.getFirstHeader("Content-Length").getValue());
}
- @Test
+ /**
+ * TODO SLM This test does not make sense since stop use a callback and server store only one serverChannel
+ * @Test
+ */
public void multipleStartStopCombinations() throws InterruptedException {
Configuration configuration = new Configuration();
Modified: incubator/deft/sandbox/src/test/java/org/apache/deft/web/HttpServerTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/test/java/org/apache/deft/web/HttpServerTest.java?rev=1175622&r1=1175621&r2=1175622&view=diff
==============================================================================
--- incubator/deft/sandbox/src/test/java/org/apache/deft/web/HttpServerTest.java (original)
+++ incubator/deft/sandbox/src/test/java/org/apache/deft/web/HttpServerTest.java Sun Sep 25 23:21:31 2011
@@ -20,11 +20,14 @@
package org.apache.deft.web;
import org.apache.deft.configuration.Configuration;
+import org.apache.deft.io.IOLoop;
import org.apache.deft.web.handler.RequestHandler;
+import org.junit.Assert;
import org.junit.Test;
import com.google.common.collect.Maps;
+
/**
* Test cases for {@link HttpServer}.
*/
@@ -51,6 +54,26 @@ public class HttpServerTest {
server.listen(port);
}
+
+ @Test
+ public void multiThreadServerStartStop(){
+ int port = 8181;
+ HttpServer server = createServer();
+ server.bind(port);
+ server.start(3);
+
+ org.junit.Assert.assertEquals(3, server.getIoLoops().size());
+ for (IOLoop loop : server.getIoLoops()){
+ Assert.assertTrue(loop.isRunning());
+ }
+
+ server.stop();
+ for (IOLoop loop : server.getIoLoops()){
+ Assert.assertFalse(loop.isRunning());
+ }
+
+ }
+
private HttpServer createServer() {
HttpServer server = new HttpServer(new Configuration()) {
Modified: incubator/deft/sandbox/src/test/java/org/apache/deft/web/http/HttpBufferedLexerTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/src/test/java/org/apache/deft/web/http/HttpBufferedLexerTest.java?rev=1175622&r1=1175621&r2=1175622&view=diff
==============================================================================
--- incubator/deft/sandbox/src/test/java/org/apache/deft/web/http/HttpBufferedLexerTest.java (original)
+++ incubator/deft/sandbox/src/test/java/org/apache/deft/web/http/HttpBufferedLexerTest.java Sun Sep 25 23:21:31 2011
@@ -20,27 +20,26 @@
package org.apache.deft.web.http;
+import java.nio.ByteBuffer;
+
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
-
-import java.nio.ByteBuffer;
+import static org.apache.deft.web.http.HttpBufferedLexer.*;
+import static org.apache.deft.web.http.HttpParsingContext.TokenType;
/**
- *
- * User: slm
- * Date: 13/09/11
- * Time: 00:11
+ * Unit tests suite for HttpBufferedLexer
*/
public class HttpBufferedLexerTest {
- HttpBufferedLexer lexer;
- HttpParsingContext context;
+ HttpBufferedLexer lexer;
+ HttpParsingContext context;
@Before
- public void init(){
- lexer = new HttpBufferedLexer();
+ public void init() {
+ lexer = new HttpBufferedLexer();
context = new HttpParsingContext();
}
@@ -51,40 +50,39 @@ public class HttpBufferedLexerTest {
context.setBuffer(ByteBuffer.wrap(request.getBytes()));
int res = lexer.nextToken(context);
- Assert.assertEquals("Token GET should be found with no errors", 1,res);
+ Assert.assertEquals("Token GET should be found with no errors", 1, res);
Assert.assertEquals("GET", context.getTokenValue());
- Assert.assertEquals(HttpParsingContext.TokenType.REQUEST_METHOD, context.currentType);
+ Assert.assertEquals(TokenType.REQUEST_METHOD, context.currentType);
res = lexer.nextToken(context);
- Assert.assertEquals("Token uri should be found with no errors", 1,res);
+ Assert.assertEquals("Token uri should be found with no errors", 1, res);
Assert.assertEquals("/path/script.cgi", context.getTokenValue());
- Assert.assertEquals(HttpParsingContext.TokenType.REQUEST_URI, context.currentType);
+ Assert.assertEquals(TokenType.REQUEST_URI, context.currentType);
res = lexer.nextToken(context);
- Assert.assertEquals("Token protocol version should be found with no errors", 1,res);
+ Assert.assertEquals("Token protocol version should be found with no errors", 1, res);
Assert.assertEquals("HTTP/1.1", context.getTokenValue());
- Assert.assertEquals(HttpParsingContext.TokenType.HTTP_VERSION, context.currentType);
+ Assert.assertEquals(TokenType.HTTP_VERSION, context.currentType);
res = lexer.nextToken(context);
- Assert.assertEquals("Token body should be found with no errors", 1,res);
- Assert.assertEquals(HttpParsingContext.TokenType.BODY, context.currentType);
- Assert.assertEquals("TokenValue should be null for body","", context.getTokenValue());
+ Assert.assertEquals("Token body should be found with no errors", 1, res);
+ Assert.assertEquals(TokenType.BODY, context.currentType);
+ Assert.assertEquals("TokenValue should be null for body", "", context.getTokenValue());
}
@Test
- public void requestLineContainingCRLF(){
+ public void requestLineContainingCRLF() {
String request = "GET\r\n /path/script.cgi HTTP/1.1\r\n\r\n";
context.setBuffer(ByteBuffer.wrap(request.getBytes()));
int res = lexer.nextToken(context);
- Assert.assertEquals("Token GET should be found with error", -1,res);
- Assert.assertEquals("", context.getTokenValue());
+ Assert.assertEquals("Token GET should be found with error", -1, res);
}
@Test
- public void requestWithHeadersParsing(){
+ public void requestWithHeadersParsing() {
String request = "POST /path/script.cgi HTTP/1.0\r\n"
+ "Host: localhost\r\n"
@@ -93,8 +91,8 @@ public class HttpBufferedLexerTest {
+ "Content-Type: application/x-www-form-urlencoded\r\n"
+ "Content-Length: 32\r\n\r\n";
- context.setBuffer( ByteBuffer.wrap(request.getBytes()));
- String [][] headers = new String[][]{{"Host", " localhost"},
+ context.setBuffer(ByteBuffer.wrap(request.getBytes()));
+ String[][] headers = new String[][]{{"Host", " localhost"},
{"From", " frog@jmarshall.com"},
{"User-Agent", " HTTPTool/1.0"},
{"Content-Type", " application/x-www-form-urlencoded"},
@@ -111,130 +109,336 @@ public class HttpBufferedLexerTest {
Assert.assertEquals("/path/script.cgi", path);
Assert.assertEquals("HTTP/1.0", protocol);
- for (String [] header : headers){
+ for (String[] header : headers) {
res = lexer.nextToken(context);
Assert.assertEquals(1, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HEADER_NAME, context.currentType);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
Assert.assertEquals(header[0], context.getTokenValue());
res = lexer.nextToken(context);
Assert.assertEquals(1, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HEADER_VALUE, context.currentType);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
Assert.assertEquals(header[1], context.getTokenValue());
}
res = lexer.nextToken(context);
- Assert.assertEquals("Token body should be found with no errors", 1,res);
- Assert.assertEquals(HttpParsingContext.TokenType.BODY, context.currentType);
- Assert.assertEquals("TokenValue should be null for body","", context.getTokenValue());
+ Assert.assertEquals("Token body should be found with no errors", 1, res);
+ Assert.assertEquals(TokenType.BODY, context.currentType);
+ Assert.assertEquals("TokenValue should be null for body", "", context.getTokenValue());
}
@Test
- public void requestLineWithTrailingHeaders(){
+ public void requestLineWithTrailingHeaders() {
String request = " \r\n \r\nPOST ";
context.setBuffer(ByteBuffer.wrap(request.getBytes()));
int res = lexer.nextToken(context);
Assert.assertEquals(1, res);
- Assert.assertEquals(HttpParsingContext.TokenType.REQUEST_METHOD,context.currentType);
+ Assert.assertEquals(TokenType.REQUEST_METHOD, context.currentType);
Assert.assertEquals("POST", context.getTokenValue());
}
@Test
- public void incompleteHeaderAfterRequestLine(){
+ public void incompleteHeaderAfterRequestLine() {
String requestPart1 = "Content-";
String requestPart2 = "Type: application";
String requestPart3 = "/x-www-form-";
String requestPart4 = "urlencoded\r\n";
- context.currentType = HttpParsingContext.TokenType.HTTP_VERSION;
+ context.currentType = TokenType.HTTP_VERSION;
context.setBuffer(ByteBuffer.wrap(requestPart1.getBytes()));
int res = lexer.nextToken(context);
Assert.assertEquals(0, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HTTP_VERSION,context.currentType);
+ Assert.assertEquals(TokenType.HTTP_VERSION, context.currentType);
Assert.assertEquals("Content-", context.getTokenValue());
context.setBuffer(ByteBuffer.wrap(requestPart2.getBytes()));
res = lexer.nextToken(context);
Assert.assertEquals(1, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HEADER_NAME,context.currentType);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
Assert.assertEquals("Content-Type", context.getTokenValue());
res = lexer.nextToken(context);
Assert.assertEquals(0, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HEADER_NAME,context.currentType);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
Assert.assertEquals(" application", context.getTokenValue());
context.setBuffer(ByteBuffer.wrap(requestPart3.getBytes()));
res = lexer.nextToken(context);
Assert.assertEquals(0, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HEADER_NAME,context.currentType);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
Assert.assertEquals(" application/x-www-form-", context.getTokenValue());
context.setBuffer(ByteBuffer.wrap(requestPart4.getBytes()));
res = lexer.nextToken(context);
Assert.assertEquals(1, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HEADER_VALUE,context.currentType);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
Assert.assertEquals(" application/x-www-form-urlencoded", context.getTokenValue());
}
@Test
- public void incompleteHeaderAfterHeader(){
+ public void incompleteHeaderAfterHeader() {
String requestPart1 = "Content-";
String requestPart2 = "Type: application";
String requestPart3 = "/x-www-form-";
String requestPart4 = "urlencoded\r\n";
- context.currentType = HttpParsingContext.TokenType.HEADER_VALUE;
+ context.currentType = TokenType.HEADER_VALUE;
context.setBuffer(ByteBuffer.wrap(requestPart1.getBytes()));
int res = lexer.nextToken(context);
Assert.assertEquals(0, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HEADER_VALUE,context.currentType);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
Assert.assertEquals("Content-", context.getTokenValue());
context.setBuffer(ByteBuffer.wrap(requestPart2.getBytes()));
res = lexer.nextToken(context);
Assert.assertEquals(1, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HEADER_NAME,context.currentType);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
Assert.assertEquals("Content-Type", context.getTokenValue());
res = lexer.nextToken(context);
Assert.assertEquals(0, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HEADER_NAME,context.currentType);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
Assert.assertEquals(" application", context.getTokenValue());
context.setBuffer(ByteBuffer.wrap(requestPart3.getBytes()));
res = lexer.nextToken(context);
Assert.assertEquals(0, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HEADER_NAME,context.currentType);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
Assert.assertEquals(" application/x-www-form-", context.getTokenValue());
context.setBuffer(ByteBuffer.wrap(requestPart4.getBytes()));
res = lexer.nextToken(context);
Assert.assertEquals(1, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HEADER_VALUE,context.currentType);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
Assert.assertEquals(" application/x-www-form-urlencoded", context.getTokenValue());
}
@Test
- public void parseMultiLineHeaders(){
+ public void parseMultiLineHeaders() {
String request = "my headervalue\r\n and so on\r\n\tand so on\r\n";
- context.currentType = HttpParsingContext.TokenType.HEADER_NAME;
+ context.currentType = TokenType.HEADER_NAME;
context.setBuffer(ByteBuffer.wrap(request.getBytes()));
int res = lexer.nextToken(context);
Assert.assertEquals(1, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HEADER_VALUE,context.currentType);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
Assert.assertEquals("my headervalue", context.getTokenValue());
res = lexer.nextToken(context);
Assert.assertEquals(1, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HEADER_VALUE,context.currentType);
- Assert.assertEquals(" and so on", context.getTokenValue());
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ Assert.assertEquals("and so on", context.getTokenValue());
+
+ res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ Assert.assertEquals("and so on", context.getTokenValue());
+ }
+
+ @Test
+ public void failOnMethodAboveMaxSize() {
+ StringBuilder request = getRandomString(METHOD_LENGTH + 1).append(' ');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.REQUEST_LINE, context.currentType);
+
+ request = getRandomString(METHOD_LENGTH + 1);
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.REQUEST_LINE, context.currentType);
+
+ }
+
+
+ @Test
+ public void successOnMethodAtMaxSize() {
+ StringBuilder request = getRandomString(METHOD_LENGTH).append(' ');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.REQUEST_METHOD, context.currentType);
+ Assert.assertEquals(request.deleteCharAt(METHOD_LENGTH).toString(), context.getTokenValue());
+ }
+
+ @Test
+ public void successOnUriAtMaxSize() {
+ StringBuilder request = getRandomString(URI_LENGTH).append(' ');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.REQUEST_METHOD;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.REQUEST_URI, context.currentType);
+ Assert.assertEquals(request.deleteCharAt(URI_LENGTH).toString(), context.getTokenValue());
+ }
+
+ @Test
+ public void failOnUriAboveMaxSize() {
+ StringBuilder request = getRandomString(URI_LENGTH + 1).append(' ');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.REQUEST_METHOD;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.REQUEST_METHOD, context.currentType);
+
+ request = getRandomString(URI_LENGTH + 1);
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.REQUEST_METHOD, context.currentType);
+ }
+
+ @Test
+ public void successOnVersionAtMaxSize() {
+ StringBuilder request = getRandomString(VERSION_LENGTH).append('\r');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.REQUEST_URI;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HTTP_VERSION, context.currentType);
+ Assert.assertEquals(request.deleteCharAt(VERSION_LENGTH).toString(),
+ context.getTokenValue());
+ }
+
+ @Test
+ public void failOnVersionAboveMaxSize() {
+ StringBuilder request = getRandomString(VERSION_LENGTH + 1).append(' ');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.REQUEST_URI;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.REQUEST_URI, context.currentType);
+
+ request = getRandomString(VERSION_LENGTH + 1);
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.REQUEST_URI, context.currentType);
+ }
+
+ @Test
+ public void successOnHeaderNameAtMaxSizeFromRequestLine() {
+ StringBuilder request = getRandomString(HEADER_NAME_LENGTH).append(':');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HTTP_VERSION;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+ Assert.assertEquals(request.deleteCharAt(HEADER_NAME_LENGTH).toString(), context.getTokenValue());
+ }
+
+ @Test
+ public void failOnHeaderNameAboveMaxSizeFromRequestLine() {
+ StringBuilder request = getRandomString(HEADER_NAME_LENGTH + 1).append(' ');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HTTP_VERSION;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HTTP_VERSION, context.currentType);
+
+ request = getRandomString(HEADER_NAME_LENGTH + 1);
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HTTP_VERSION, context.currentType);
+ }
+
+ @Test
+ public void successOnHeaderNameAtMaxSizeFromHeaderValue() {
+ StringBuilder request = getRandomString(HEADER_NAME_LENGTH).append(':');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HEADER_VALUE;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+ Assert.assertEquals(request.deleteCharAt(HEADER_NAME_LENGTH).toString(), context.getTokenValue());
+ }
+
+ @Test
+ public void failOnHeaderNameAboveMaxSizeFromHeaderValue() {
+ StringBuilder request = getRandomString(HEADER_NAME_LENGTH + 1).append(' ');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HEADER_VALUE;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+
+ request = getRandomString(HEADER_NAME_LENGTH + 1);
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ }
+
+ @Test
+ public void successOnHeaderValueAtMaxSize() {
+ StringBuilder request = getRandomString(HEADER_VALUE_LENGTH).append('\r');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HEADER_NAME;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ Assert.assertEquals(request.deleteCharAt(HEADER_VALUE_LENGTH).toString(), context.getTokenValue());
+ }
+ @Test
+ public void failOnHeaderValueAboveMaxSize() {
+ StringBuilder request = getRandomString(HEADER_VALUE_LENGTH + 1).append('\r');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HEADER_NAME;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+
+ request = getRandomString(HEADER_NAME_LENGTH + 1);
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+ }
+
+ @Test
+ public void successOnHeaderValueAtMaxSizeOnMultiLine() {
+ StringBuilder request = getRandomString(HEADER_VALUE_LENGTH).insert(0, '\t').append('\r');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HEADER_VALUE;
+ int res = lexer.nextToken(context);
Assert.assertEquals(1, res);
- Assert.assertEquals(HttpParsingContext.TokenType.HEADER_VALUE,context.currentType);
- Assert.assertEquals("\tand so on", context.getTokenValue());
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ Assert.assertEquals(request.deleteCharAt(0).deleteCharAt(HEADER_VALUE_LENGTH).toString(), context.getTokenValue());
}
+
+ @Test
+ public void failOnHeaderValueAboveMaxSizeOnMultiLine() {
+ StringBuilder request = getRandomString(HEADER_VALUE_LENGTH + 1).insert(0, ' ').append('\r');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HEADER_VALUE;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+
+ request = getRandomString(HEADER_VALUE_LENGTH + 1).insert(0, '\t');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ }
+
+ /**
+ * Generate
+ *
+ * @param length
+ * @return
+ */
+ private StringBuilder getRandomString(int length) {
+
+ StringBuilder stringBuilder = new StringBuilder(length);
+ for (int i = 0; i < length; i++) {
+ stringBuilder.append('A');
+ }
+ return stringBuilder;
+ }
+
}