forked from LupusNobilis/java-org.hwo
308 lines
6.9 KiB
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;
|
|
}
|
|
|
|
}
|