java-org.hwo/src/org/hwo/net/http/HttpServerRequest.java

308 lines
6.9 KiB
Java

package org.hwo.net.http;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.hwo.sessions.Session;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
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;
MessageHeaders
requestHeaders;
Hashtable<String,HttpCookie>
requestCookies;
byte[] requestContent;
Document
xmlRequest;
private Integer resultCode;
MessageHeaders
responseHeaders;
byte[] responseBody;
ByteArrayOutputStream
responseOutputStream;
BufferedWriter
responseBufferedWriter;
boolean responseSent;
Session session;
List<HttpCookie> responseCookies;
public HttpServerRequest(HttpServerConnection httpServerConnection) throws IOException
{
this.connection = httpServerConnection;
this.requestHeaders = new MessageHeaders();
this.requestCookies = new Hashtable<String, HttpCookie>();
this.responseCookies = new ArrayList<HttpCookie>();
readRequest();
readHeader();
requestURI.decode();
resultCode = 400;
responseHeaders = new MessageHeaders();
responseOutputStream = new ByteArrayOutputStream();
responseBufferedWriter = new BufferedWriter(new OutputStreamWriter(responseOutputStream));
readCookies();
attachSession();
readContent();
if ((getRequestHeader("Content-Type") != null) && getRequestHeader("Content-Type").equals("text/xml"))
readXML();
}
private void readCookies()
{
HttpCookie[] cookies = HttpCookie.readCookies(this);
for (HttpCookie c:cookies)
requestCookies.put(c.getName(), c);
}
private void attachSession()
{
SessionTracker tracker = connection.getHttpServer().getSessionTracker();
if (tracker != null)
{
String sid = tracker.retrieveSessionID(this);
if (sid != null)
session = connection.getHttpServer().getSessionManager().getSession(sid);
if (session == null)
{
session = connection.getHttpServer().getSessionManager().createSession();
connection.getHttpServer().getSessionTracker().implantSession(this,session);
}
}
}
private void readContent() throws IOException
{
String cl = getRequestHeader("Content-Length");
if (cl != null)
{
int len = Integer.decode(cl);
requestContent = new byte[ len ];
connection.getStreamReader().read(requestContent, 0, len);
}
}
private void readXML()
{
DocumentBuilder builder;
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
builder = dbf.newDocumentBuilder();
this.xmlRequest = builder.parse(new ByteArrayInputStream(requestContent));
this.xmlRequest.normalize();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException ex)
{
ex.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Session getSession()
{
return session;
}
public boolean isResponseSent()
{
return responseSent;
}
private void readRequest() throws IOException
{
do
{
this.requestLine = connection.getStreamReader().readLine();
if (this.requestLine == null)
throw new IOException("0byte read()");
} while (this.requestLine.length() == 0);
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
{
requestHeaders.read(connection.getStreamReader());
}
public HttpRequestURI getRequestURI()
{
return requestURI;
}
public String getRequestHeader(String headerName)
{
return requestHeaders.getHeaderValue(headerName);
}
public String getRequestMethod()
{
return requestMethod;
}
public byte[] getRequestContent()
{
return requestContent;
}
public Document getXMLRequest()
{
return this.xmlRequest;
}
public HttpCookie[] getRequestCookies()
{
return this.requestCookies.keySet().toArray(new HttpCookie[0]);
}
public HttpCookie getRequestCookie(String cookieName)
{
return requestCookies.get(cookieName);
}
public void addCookie(HttpCookie cookie)
{
responseCookies.add(cookie);
}
public OutputStream getResponseOutputStream()
{
return responseOutputStream;
}
public BufferedWriter getResponseWriter()
{
return responseBufferedWriter;
}
public MessageHeaders getRepsonseHeaders()
{
return responseHeaders;
}
public void setResponseHeader(String headerName,String headerValue)
{
responseHeaders.setHeaderValue(headerName, headerValue);
}
public void addResponseHeader(String headerName,String headerValue)
{
responseHeaders.addHeaderValue(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];
}
setResponseHeader("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));
for (String headerName: responseHeaders.getHeaderNames())
{
String headerValue = responseHeaders.getHeaderValue(headerName);
connection.getBufferedWriter().write(String.format("%s: %s\r\n", headerName, headerValue));
}
for (HttpCookie cookie: responseCookies)
cookie.sendCookie(this);
connection.getBufferedWriter().write("\r\n");
connection.getBufferedWriter().flush();
connection.getClientSocket().getOutputStream().write(responseBody);
}
public Integer getResultCode() {
return resultCode;
}
public void setResultCode(Integer resultCode) {
this.resultCode = resultCode;
}
}