/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package simpleserver; import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.FileChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.nio.charset.CharacterCodingException; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * * @author Michael */ public class Request { private static Pattern pattern = Pattern.compile("GET /.*\r?\n"); private RequestListener context; private SocketChannel socket; private SelectionKey key; private ByteBuffer request; private FileChannel file = null; private ByteBuffer response = null; private ByteBuffer contents = null; public Request(RequestListener context, Selector selector, SocketChannel sc) throws IOException { this.context = context; sc.configureBlocking(false); socket = sc; key = sc.register(selector, SelectionKey.OP_READ, this); request = ByteBuffer.allocate(4096); } public void process() { try { if (file == null) { /* Reading request. Change selection to OP_WRITE when done. */ if (socket.read(request) < 0) { close(); } else if (isComplete(request)) { key.interestOps(SelectionKey.OP_WRITE); request.flip(); decodeRequest(context.decoder.decode(request).toString()); } } else { /* Delivering file. Cancel this key when done. */ if (response != null) { socket.write(response); if (!response.hasRemaining()) response = null; } else { socket.write(contents); if (!contents.hasRemaining()) close(); } } } catch (IOException ioe) { ioe.printStackTrace(); close(); } } private boolean isComplete(ByteBuffer r) { int index = r.position(); return index >= 4 && r.get(index-4)=='\r' && r.get(index-3)=='\n' && r.get(index-2)=='\r' && r.get(index-1)=='\n'; } public void close() { key.cancel(); try {socket.close();}catch(IOException e){} if (file != null) try{file.close();}catch(IOException e){} response = null; contents = null; } private void decodeRequest(String request) throws IOException { if (!request.startsWith("GET ")) { respond(405, "Invalid method"); } else { int sp = request.indexOf(' ', 4); if (sp < 0) sp = request.indexOf('\r'); else if (sp < 0) sp = request.indexOf('\n'); else if (sp < 0) sp = request.length(); String path = request.substring(4, sp); System.err.println("PATH = " + path); file = new FileInputStream(Main.BASE_PATH + path).getChannel(); respond(200, "OK"); contents = file.map(FileChannel.MapMode.READ_ONLY, 0, file.size()); } } private void respond(int code, String message) { try { response = context.encoder.encode(CharBuffer.wrap("1.1 " + code + " " + message + "\r\n\r\n")); } catch (CharacterCodingException e) { throw new RuntimeException(e); } } }