Permalink
Browse files

Merge pull request #6 from rickerbh/feature/refactor-completion-handler

Feature/refactor completion handler
  • Loading branch information...
rickerbh committed Aug 25, 2016
2 parents 180f80b + 165f9f9 commit d524a31562969bb39351f7cbd0567b9db503d815
@@ -0,0 +1,37 @@
package com.hamishrickerby.http_server;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.concurrent.TimeUnit;
/**
* Created by rickerbh on 25/08/2016.
*/
public class AsynchronousSocketChannelReader implements ByteReader {
AsynchronousSocketChannel channel;
public AsynchronousSocketChannelReader(AsynchronousSocketChannel channel) {
this.channel = channel;
}
@Override
public byte[] read() {
ByteBuffer buffer = ByteBuffer.allocate(8192);
byte[] requestBytes = null;
try {
int bytesRead = channel.read(buffer).get(20, TimeUnit.SECONDS);
requestBytes = new byte[bytesRead];
if (bytesRead > 0 && buffer.position() > 2) {
buffer.flip();
buffer.get(requestBytes, 0, bytesRead);
buffer.clear();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
return requestBytes;
}
}
}
@@ -0,0 +1,20 @@
package com.hamishrickerby.http_server;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
/**
* Created by rickerbh on 25/08/2016.
*/
public class AsynchronousSocketChannelWriter implements ByteWriter {
private AsynchronousSocketChannel channel;
public AsynchronousSocketChannelWriter(AsynchronousSocketChannel channel) {
this.channel = channel;
}
@Override
public void write(byte[] bytes) {
channel.write(ByteBuffer.wrap(bytes));
}
}
@@ -0,0 +1,8 @@
package com.hamishrickerby.http_server;
/**
* Created by rickerbh on 25/08/2016.
*/
public interface ByteReader {
byte[] read();
}
@@ -0,0 +1,8 @@
package com.hamishrickerby.http_server;
/**
* Created by rickerbh on 25/08/2016.
*/
public interface ByteWriter {
void write(byte[] bytes);
}
@@ -1,62 +1,39 @@
package com.hamishrickerby.http_server;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.TimeUnit;
/**
* Created by rickerbh on 15/08/2016.
*/
public class HTTPCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, Void> {
ResponseFactory responseFactory;
AsynchronousServerSocketChannel listeningChannel;
HTTPHandler handler;
public HTTPCompletionHandler(String rootDirectory, AsynchronousServerSocketChannel listeningChannel) {
responseFactory = new ResponseFactory(rootDirectory);
handler = new HTTPHandler(rootDirectory);
this.listeningChannel = listeningChannel;
}
@Override
public void completed(AsynchronousSocketChannel ch, Void attachment) {
listeningChannel.accept(null, this);
String requestText = extractRequestText(ch);
Request request = new Request(requestText);
Response response = responseFactory.makeResponse(request);
setupHandlerForNextConnection();
sendResponse(ch, response);
ByteReader reader = new AsynchronousSocketChannelReader(ch);
ByteWriter writer = new AsynchronousSocketChannelWriter(ch);
handler.run(reader, writer);
closeChannel(ch);
}
@Override
public void failed(Throwable exc, Void attachment) {
private void setupHandlerForNextConnection() {
listeningChannel.accept(null, this);
}
private String extractRequestText(AsynchronousSocketChannel ch) {
ByteBuffer buffer = ByteBuffer.allocate(8192);
byte[] requestBytes = null;
try {
int bytesRead = ch.read(buffer).get(20, TimeUnit.SECONDS);
requestBytes = new byte[bytesRead];
if (bytesRead > 0 && buffer.position() > 2) {
buffer.flip();
buffer.get(requestBytes, 0, bytesRead);
buffer.clear();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
return new String(requestBytes);
}
}
@Override
public void failed(Throwable exc, Void attachment) {
private void sendResponse(AsynchronousSocketChannel ch, Response response) {
ch.write(ByteBuffer.wrap(response.getBytes()));
}
private void closeChannel(AsynchronousSocketChannel ch) {
@@ -0,0 +1,29 @@
package com.hamishrickerby.http_server;
/**
* Created by rickerbh on 25/08/2016.
*/
public class HTTPHandler {
ResponseFactory responseFactory;
public HTTPHandler(String rootDirectory) {
responseFactory = new ResponseFactory(rootDirectory);
}
public void run(ByteReader reader, ByteWriter writer) {
String requestText = extractRequestText(reader);
Request request = new Request(requestText);
Response response = responseFactory.makeResponse(request);
sendResponse(writer, response);
}
private String extractRequestText(ByteReader reader) {
return new String(reader.read());
}
private void sendResponse(ByteWriter writer, Response response) {
writer.write(response.getBytes());
}
}
@@ -0,0 +1,19 @@
package com.hamishrickerby.http_server;
import com.hamishrickerby.http_server.mocks.MockAsynchronousSocketChannel;
import junit.framework.TestCase;
/**
* Created by rickerbh on 25/08/2016.
*/
public class AsynchronousSocketChannelReaderTest extends TestCase {
public void testReaderReturnsData() {
MockAsynchronousSocketChannel channel = new MockAsynchronousSocketChannel(null);
String expected = "Hello";
channel.setReadData(expected);
ByteReader reader = new AsynchronousSocketChannelReader(channel);
assertEquals(expected, new String(reader.read()));
}
}
@@ -0,0 +1,17 @@
package com.hamishrickerby.http_server;
import com.hamishrickerby.http_server.mocks.MockAsynchronousSocketChannel;
import junit.framework.TestCase;
/**
* Created by rickerbh on 25/08/2016.
*/
public class AsynchronousSocketChannelWriterTest extends TestCase {
public void testWriterReturnsData() {
MockAsynchronousSocketChannel channel = new MockAsynchronousSocketChannel(null);
String expected = "Hello";
ByteWriter writer = new AsynchronousSocketChannelWriter(channel);
writer.write(expected.getBytes());
assertEquals(expected, new String(channel.getWrittenData().array()));
}
}
@@ -0,0 +1,17 @@
package com.hamishrickerby.http_server;
import com.hamishrickerby.http_server.mocks.FakeReader;
import junit.framework.TestCase;
/**
* Created by rickerbh on 25/08/2016.
*/
public class ByteReaderTest extends TestCase {
public void testReaderReturnsData() {
String expected = "Hello";
ByteReader reader = new FakeReader("Hello");
assertEquals(expected, new String(reader.read()));
}
}
@@ -0,0 +1,16 @@
package com.hamishrickerby.http_server;
import com.hamishrickerby.http_server.mocks.FakeWriter;
import junit.framework.TestCase;
/**
* Created by rickerbh on 25/08/2016.
*/
public class ByteWriterTest extends TestCase {
public void testWrittenBytesCanBeRead() {
String expected = "Hello";
FakeWriter writer = new FakeWriter();
writer.write(expected.getBytes());
assertEquals(expected, new String(writer.readWrittenBytes()));
}
}
@@ -20,7 +20,7 @@ public void testGetRespondsWith200() {
private String runRequestAndGetResponse(String request) {
HTTPCompletionHandler handler = new HTTPCompletionHandler("./src/test/resources", new MockAsynchronousServerSocketChannel(null));
MockAsynchronousSocketChannel channel = new MockAsynchronousSocketChannel(null);
channel.setReadData(ByteBuffer.wrap(request.getBytes()));
channel.setReadData(request);
handler.completed(channel, null);
@@ -0,0 +1,18 @@
package com.hamishrickerby.http_server;
import com.hamishrickerby.http_server.mocks.FakeReader;
import com.hamishrickerby.http_server.mocks.FakeWriter;
import junit.framework.TestCase;
/**
* Created by rickerbh on 25/08/2016.
*/
public class HTTPHandlerTest extends TestCase {
public void testRequestGivesAResponse() {
ByteReader reader = new FakeReader("GET / HTTP/1.1");
FakeWriter writer = new FakeWriter();
HTTPHandler handler = new HTTPHandler("./src/test/resources");
handler.run(reader, writer);
assertNotSame(new byte[0], writer.readWrittenBytes());
}
}
@@ -0,0 +1,20 @@
package com.hamishrickerby.http_server.mocks;
import com.hamishrickerby.http_server.ByteReader;
/**
* Created by rickerbh on 25/08/2016.
*/
public class FakeReader implements ByteReader {
private byte[] byteData;
public FakeReader(String data) {
byteData = data.getBytes();
}
@Override
public byte[] read() {
return byteData;
}
}
@@ -0,0 +1,20 @@
package com.hamishrickerby.http_server.mocks;
import com.hamishrickerby.http_server.ByteWriter;
/**
* Created by rickerbh on 25/08/2016.
*/
public class FakeWriter implements ByteWriter {
private byte[] byteData;
@Override
public void write(byte[] bytes) {
byteData = bytes;
}
public byte[] readWrittenBytes() {
return byteData;
}
}
@@ -16,8 +16,8 @@
* Created by rickerbh on 15/08/2016.
*/
public class MockAsynchronousSocketChannel extends AsynchronousSocketChannel {
public void setReadData(ByteBuffer readData) {
this.readData = readData;
public void setReadData(String text) {
this.readData = ByteBuffer.wrap(text.getBytes());
}
private ByteBuffer readData;

0 comments on commit d524a31

Please sign in to comment.