package org.hwo.net.http; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.Arrays; import java.util.Enumeration; import java.util.Properties; public class HttpServerRequest { public static class Factory implements HttpServerRequestFactory { @Override public HttpServerRequest createRequest(HttpServerConnection connection) throws IOException { return new HttpServerRequest(connection); } } HttpServerConnection connection; String requestLine; String requestMethod; String requestProtocol; HttpRequestURI requestURI; Properties header; Integer resultCode; Properties responseHeader; byte[] responseBody; ByteArrayOutputStream responseOutputStream; BufferedWriter responseBufferedWriter; boolean responseSent; public HttpServerRequest(HttpServerConnection httpServerConnection) throws IOException { this.connection = httpServerConnection; this.header = new Properties(); readRequest(); readHeader(); requestURI.decode(); resultCode = 400; responseHeader = new Properties(); responseOutputStream = new ByteArrayOutputStream(); responseBufferedWriter = new BufferedWriter(new OutputStreamWriter(responseOutputStream)); } public boolean isResponseSent() { return responseSent; } private void readRequest() throws IOException { this.requestLine = connection.getBufferedReader().readLine(); String[] tokens = this.requestLine.split(" ",3); requestMethod = tokens[0]; if (tokens.length > 1) requestURI = new HttpRequestURI(this,tokens[1]); if (tokens.length > 2) requestProtocol = tokens[2]; } private void readHeader() throws IOException { String line; String headerName = null; StringBuilder headerValue = new StringBuilder(); while (true) { line = connection.getBufferedReader().readLine(); if ((line.length() == 0) || (line.charAt(0) > 32)) { if (headerName != null) { header.setProperty(headerName, headerValue.toString()); } if (line.length() > 0) { headerName = line.substring(0,line.indexOf(':')); headerValue = new StringBuilder(); headerValue.append(line.substring(line.indexOf(':')+1).trim()); } else return; } else { if (headerName != null) headerValue.append(line.trim()); } } } public HttpRequestURI getRequestURI() { return requestURI; } public String getRequestHeader(String headerName) { return header.getProperty(headerName); } public OutputStream getResponseOutputStream() { return responseOutputStream; } public BufferedWriter getResponseWriter() { return responseBufferedWriter; } public void setResponseHeader(String headerName,String headerValue) { responseHeader.setProperty(headerName, headerValue); } public void sendResponse(int code,byte[] responseBody) throws IOException { this.responseBody = responseBody; this.resultCode = code; sendResponse(); } public void sendResponse(int code) throws IOException { this.resultCode = code; sendResponse(); } public void sendResponse() throws IOException { if (responseSent) throw new IOException("The Response has already been sent."); responseSent = true; if (responseBody == null) { responseBufferedWriter.flush(); if (responseOutputStream.size() > 0) { responseBody = responseOutputStream.toByteArray(); } else responseBody = new byte[0]; } responseHeader.setProperty("Content-Length", String.format("%d", responseBody.length)); String protocol = "HTTP/1.0"; if (requestProtocol != null) protocol = requestProtocol; connection.getBufferedWriter().write(String.format("%s %d\r\n", protocol, resultCode)); Enumeration headerEnum = responseHeader.keys(); while (headerEnum.hasMoreElements()) { String headerName = (String)headerEnum.nextElement(); connection.getBufferedWriter().write(String.format("%s: %s\r\n", headerName, responseHeader.getProperty(headerName))); } connection.getBufferedWriter().write("\r\n"); connection.getBufferedWriter().flush(); connection.getClientSocket().getOutputStream().write(responseBody); } }