001: /******************************************************************************
002: * Copyright (C) Lars Ivar Almli. All rights reserved. *
003: * ---------------------------------------------------------------------------*
004: * This file is part of MActor. *
005: * *
006: * MActor is free software; you can redistribute it and/or modify *
007: * it under the terms of the GNU General Public License as published by *
008: * the Free Software Foundation; either version 2 of the License, or *
009: * (at your option) any later version. *
010: * *
011: * MActor is distributed in the hope that it will be useful, *
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
014: * GNU General Public License for more details. *
015: * *
016: * You should have received a copy of the GNU General Public License *
017: * along with MActor; if not, write to the Free Software *
018: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
019: ******************************************************************************/package org.mactor.brokers.http;
020:
021: import java.io.BufferedReader;
022: import java.io.IOException;
023: import java.io.InputStreamReader;
024: import java.io.OutputStream;
025: import java.io.PrintWriter;
026: import java.net.ServerSocket;
027: import java.net.Socket;
028: import java.util.HashMap;
029: import java.util.Map;
030: import java.util.Map.Entry;
031: import org.apache.log4j.Logger;
032:
033: /**
034: * Simple HTTP server
035: *
036: * @author Lars Ivar Almli
037: */
038: public class HttpServer {
039: protected static Logger log = Logger.getLogger(HttpServer.class);
040:
041: public HttpServer(final int port) {
042: Thread httpServer = new Thread() {
043: public void run() {
044: ServerSocket ss = null;
045: try {
046: log.info("HTTP Server listening on port " + port);
047: ss = new ServerSocket(port);
048: while (true && !ss.isClosed() && !isInterrupted()) {
049: Socket client = ss.accept();
050: new RequestWorker(client).start();
051: }
052: ss.close();
053: } catch (IOException ioe) {
054: ioe.printStackTrace();
055: } finally {
056: if (ss != null && !ss.isClosed()) {
057: try {
058: ss.close();
059: } catch (IOException e) {
060: e.printStackTrace();
061: }
062: }
063: }
064: }
065: };
066: httpServer.start();
067: }
068:
069: private class RequestWorker {
070: Socket client;
071:
072: RequestWorker(Socket client) {
073: this .client = client;
074: }
075:
076: public void start() {
077: new Thread() {
078: @Override
079: public void run() {
080: handleRequest(client);
081: }
082: }.start();
083: }
084:
085: private void handleRequest(Socket client) {
086: try {
087: if (log.isDebugEnabled()) {
088: log.debug("Handling request from "
089: + client.getInetAddress());
090: }
091:
092: HttpRequest req = new HttpRequest(client
093: .getInputStream());
094: HttpRequestListener listener = listeners.get(req
095: .getRequestedUrl().toLowerCase());
096: if (listener == null) {
097: log.info("No listener for requested url '"
098: + req.getRequestedUrl().toLowerCase());
099: sendErrorResponse(client, "404");
100: } else {
101: try {
102: HttpResponse res = listener.onRequest(req);
103: if (res != null)
104: sendSuccessResponse(client, res);
105: else {
106: log
107: .info("No response produced for requested url '"
108: + req.getRequestedUrl()
109: .toLowerCase());
110: sendErrorResponse(client, "204");// No content
111: }
112: } catch (Exception e) {
113: e.printStackTrace();
114: sendErrorResponse(client, "500");
115: }
116: }
117: client.close();
118: } catch (Exception e) {
119: e.printStackTrace();
120: }
121: }
122: }
123:
124: private void sendErrorResponse(Socket client, String code)
125: throws IOException {
126: PrintWriter out = new PrintWriter(client.getOutputStream());
127: out.println("HTTP/1.0 " + code);
128: out.println("Content-Type: text/plain");
129: out.println();
130: out.flush();
131: out.close();
132: }
133:
134: private void sendSuccessResponse(Socket client,
135: HttpResponse response) throws IOException {
136: OutputStream stream = client.getOutputStream();
137: PrintWriter out = new PrintWriter(stream);
138: out.println("HTTP/1.0 200");
139: for (Entry<String, String> e : response.getHeaders().entrySet()) {
140: out.println(e.getKey() + ": " + e.getValue().trim());
141: }
142: out.println();
143: out.flush();
144: if (response.getData() != null) {
145: stream.write(response.getData());
146: stream.flush();
147: }
148: stream.close();
149: }
150:
151: Map<String, HttpRequestListener> listeners = new HashMap<String, HttpRequestListener>();
152:
153: public synchronized void addRequestListener(String url,
154: HttpRequestListener listener) {
155: url = url.toLowerCase();
156: System.out.println("adding listener for:'" + url + "'");
157: if (listeners.containsKey(url))
158: throw new RuntimeException("Listener for url '" + url
159: + "' already registered");
160: listeners.put(url, listener);
161: }
162: }
|