package com.openmashupos.mhttpserver.client;
import java.util.HashMap;
import java.util.Map;
import com.openmashupos.socket.client.ServerSocket;
import com.openmashupos.socket.client.ServerSocketCallback;
import com.openmashupos.socket.client.Socket;
import com.openmashupos.socket.client.SocketCallback;
import com.openmashupos.core.client.Log;
public class MHTTPServer {
//final public String MHTTP_VERSION = "0.1";
//final public String MHTTP_PROTOCOL = "MHTTP";
//final public String
// path -> service object
private Map<String, Servlet> mhttpServices = new HashMap<String, Servlet>();
private ServerSocket serverSocket;
private int port = 80;
public MHTTPServer()
{
}
public void setPort(int port)
{
this.port = port;
}
// eg. /echo/echo.srv --> echo service
public void registerService( String path,Servlet service)
{
Log.debug("registering " + path);
mhttpServices.put(path, service);
}
public void removeService(String path)
{
mhttpServices.remove(path);
}
public void run()
{
serverSocket = new ServerSocket(port);
serverSocket.accept(new ServerSocketCallback()
{
public void onConnectionAccepted(Socket s)
{
handleSocketConnection(s);
}
public void onError(String s)
{
}
}
);
}
private void handleSocketConnection(final Socket s)
{
s.setSocketCallback(
new SocketCallback()
{
public void onConnected()
{
}
public void onDataReceived(String mhttpPacket)
{
Log.debug("MHTTP Packet2: " + mhttpPacket);
assert(mhttpPacket != null);
handleMHTTPRequest(mhttpPacket, s);
}
public void onDisconnected(String message)
{
}
}
);
}
private void handleMHTTPRequest(String mhttpPacket, Socket socket)
{
Request request = constructRequest(mhttpPacket,socket.getEndpointDomainName());
if( request != null)
{
Servlet service = null;
if(mhttpServices.containsKey(request.getPath()))
{
service = mhttpServices.get(request.getPath());
}else if(mhttpServices.containsKey("/*") )
{
service = mhttpServices.get("/*");
}
else
{
Log.error("No service availble for " + request.getPath());
// respond with not found message (404)
}
if(service != null)
{
// construct the Transaction context
TransactionContext context = new TransactionContext(socket,request);
service.serve(context);
}
else
{
Log.error("MHTTP service associated to path " + request.getPath() + " is null!" );
}
}
}
// returns null if cannot construct it ..
// e.g.
// GET /echo/echo.srv MHTTP/1.1
// att1: value1
// att2: value2
//
// body
private Request constructRequest(String mhttpPacket, String hostname)
{
Request request = null;
String[] headBody = mhttpPacket.split("\n\n", 2);
String head, body="";
head = headBody[0];
if(headBody.length == 2)
{
body = headBody[1];
}
String[] headLines = head.split("\n");
String cmdLine = headLines[0];
String[] cmdLineTokens = cmdLine.split(" ");
String method, path, prot_version;
if(cmdLineTokens.length == 3)
{
method = cmdLineTokens[0];
path = cmdLineTokens[1];
prot_version = cmdLineTokens[2];
String[] elems = prot_version.split("/"); // eg MHTTP/1.0
if(elems.length == 2)
{
String protocol, version;
protocol = elems[0];
version = elems[1];
request = new Request(method, path, protocol, version,hostname);
// set the body (Text)
request.setText(body);
for(int i = 1 ; i<headLines.length; i++ )
{
String headline = headLines[i];
String[] att_value = headline.split(":",2);
if(att_value.length == 2)
{
request.setHeader(att_value[0].trim(), att_value[1].trim());
}
else
{
Log.debug("Wrong header line (ignored) : " + headline);
}
}
}
else
{
Log.error("Wrong protocol/version pair : " + prot_version);
}
}
else
{
Log.error("Received mhttp packet (cmd line) does not have proper format. cmd line: " + cmdLine);
request = null;
}
return request;
}
}