diff --git a/rfb/HTTPServer.cxx b/rfb/HTTPServer.cxx
new file mode 100644
index 0000000..55e6909
--- /dev/null
+++ b/rfb/HTTPServer.cxx
@@ -0,0 +1,386 @@
+/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+
+#include <rfb/HTTPServer.h>
+#include <rfb/LogWriter.h>
+#include <rfb/util.h>
+#include <rdr/MemOutStream.h>
+#include <time.h>
+
+// *** Shouldn't really link against this - only for ClientWaitTimeMillis
+//     and IdleTimeout
+#include <rfb/ServerCore.h>
+
+#ifdef WIN32
+#define strcasecmp _stricmp
+#endif
+
+
+using namespace rfb;
+using namespace rdr;
+
+static LogWriter vlog("HTTPServer");
+
+
+//
+// -=- LineReader
+//     Helper class which is repeatedly called until a line has been read
+//     (lines end in \n or \r\n).
+//     Returns true when line complete, and resets internal state so that
+//     next read() call will start reading a new line.
+//     Only one buffer is kept - process line before reading next line!
+//
+
+class LineReader : public CharArray {
+public:
+  LineReader(InStream& is_, int l)
+    : CharArray(l), is(is_), pos(0), len(l), bufferOverrun(false) {}
+
+  // Returns true if line complete, false otherwise
+  bool read() {
+    while (is.checkNoWait(1)) {
+      char c = is.readU8();
+
+      if (c == '\n') {
+        if (pos && (buf[pos-1] == '\r'))
+          pos--;
+        bufferOverrun = false;
+        buf[pos++] = 0;
+        pos = 0;
+        return true;
+      }
+
+      if (pos == (len-1)) {
+        bufferOverrun = true;
+        buf[pos] = 0;
+        return true;
+      }
+
+      buf[pos++] = c;
+    }
+
+    return false;
+  }
+  bool didBufferOverrun() const {return bufferOverrun;}
+protected:
+  InStream& is;
+  int pos, len;
+  bool bufferOverrun;
+};
+
+
+//
+// -=- HTTPServer::Session
+//     Manages the internal state for an HTTP session.
+//     processHTTP returns true when request has completed,
+//     indicating that socket & session data can be deleted.
+//
+
+class rfb::HTTPServer::Session {
+public:
+  Session(network::Socket& s, rfb::HTTPServer& srv)
+    : contentType(0), line(s.inStream(), 256), sock(s),
+      server(srv), state(ReadRequestLine), lastActive(time(0)) {
+  }
+  ~Session() {
+  }
+
+  void writeResponse(int result, const char* text);
+  bool writeResponse(int code);
+
+  bool processHTTP();
+
+  network::Socket* getSock() const {return &sock;}
+
+  int checkIdleTimeout();
+protected:
+  CharArray uri;
+  const char* contentType;
+  LineReader line;
+  network::Socket& sock;
+  rfb::HTTPServer& server;
+  enum {ReadRequestLine, ReadHeaders, WriteResponse} state;
+  enum {GetRequest, HeadRequest} request;
+  time_t lastActive;
+};
+
+
+// - Internal helper routines
+
+void
+copyStream(InStream& is, OutStream& os) {
+  try {
+    while (1) {
+      os.writeU8(is.readU8());
+    }
+  } catch (rdr::EndOfStream) {
+  }
+}
+
+void writeLine(OutStream& os, const char* text) {
+  os.writeBytes(text, strlen(text));
+  os.writeBytes("\r\n", 2);
+}
+
+
+// - Write an HTTP-compliant response to the client
+
+void
+HTTPServer::Session::writeResponse(int result, const char* text) {
+  char buffer[1024];
+  if (strlen(text) > 512)
+    throw new rdr::Exception("Internal error - HTTP response text too big");
+  sprintf(buffer, "%s %d %s", "HTTP/1.1", result, text);
+  OutStream& os=sock.outStream();
+  writeLine(os, buffer);
+  writeLine(os, "Server: RealVNC/4.0");
+  writeLine(os, "Connection: close");
+  os.writeBytes("Content-Type: ", 14);
+  if (result == 200) {
+    if (!contentType)
+      contentType = guessContentType(uri.buf, "text/html");
+    os.writeBytes(contentType, strlen(contentType));
+  } else {
+    os.writeBytes("text/html", 9);
+  }
+  os.writeBytes("\r\n", 2);
+  writeLine(os, "");
+  if (result != 200) {
+    writeLine(os, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">");
+    writeLine(os, "<HTML><HEAD>");
+    sprintf(buffer, "<TITLE>%d %s</TITLE>", result, text);
+    writeLine(os, buffer);
+    writeLine(os, "</HEAD><BODY><H1>");
+    writeLine(os, text);
+    writeLine(os, "</H1></BODY></HTML>");
+    sock.outStream().flush();
+  }
+}
+
+bool
+HTTPServer::Session::writeResponse(int code) {
+  switch (code) {
+  case 200: writeResponse(code, "OK"); break;
+  case 400: writeResponse(code, "Bad Request"); break;
+  case 404: writeResponse(code, "Not Found"); break;
+  case 501: writeResponse(code, "Not Implemented"); break;
+  default: writeResponse(500, "Unknown Error"); break;
+  };
+
+  // This return code is passed straight out of processHTTP().
+  // true indicates that the request has been completely processed.
+  return true;
+}
+
+// - Main HTTP request processing routine
+
+bool
+HTTPServer::Session::processHTTP() {
+  lastActive = time(0);
+
+  while (sock.inStream().checkNoWait(1)) {
+
+    switch (state) {
+
+      // Reading the Request-Line
+    case ReadRequestLine:
+
+      // Either read a line, or run out of incoming data
+      if (!line.read())
+        return false;
+
+      // We have read a line!  Skip it if it's blank
+      if (strlen(line.buf) == 0)
+        continue;
+
+      // The line contains a request to process.
+      {
+        char method[16], path[128], version[16];
+        int matched = sscanf(line.buf, "%15s%127s%15s",
+          method, path, version);
+        if (matched != 3)
+          return writeResponse(400);
+
+        // Store the required "method"
+        if (strcmp(method, "GET") == 0)
+          request = GetRequest;
+        else if (strcmp(method, "HEAD") == 0)
+          request = HeadRequest;
+        else
+          return writeResponse(501);
+
+        // Store the URI to the "document"
+        uri.buf = strDup(path);
+      }
+
+      // Move on to reading the request headers
+      state = ReadHeaders;
+      break;
+
+      // Reading the request headers
+    case ReadHeaders:
+
+      // Try to read a line
+      if (!line.read())
+        return false;
+
+      // Skip headers until we hit a blank line
+      if (strlen(line.buf) != 0)
+        continue;
+
+      // Headers ended - write the response!
+      {
+        CharArray address(sock.getPeerAddress());
+        vlog.info("getting %s for %s", uri.buf, address.buf);
+        InStream* data = server.getFile(uri.buf, &contentType);
+        if (!data)
+          return writeResponse(404);
+
+        try {
+          writeResponse(200);
+          if (request == GetRequest)
+            copyStream(*data, sock.outStream());
+          sock.outStream().flush();
+        } catch (rdr::Exception& e) {
+          vlog.error("error writing HTTP document:%s", e.str());
+        }
+        delete data;
+      }
+
+      // The operation is complete!
+      return true;
+
+    default:
+      throw rdr::Exception("invalid HTTPSession state!");
+    };
+
+  }
+
+  // Indicate that we're still processing the HTTP request.
+  return false;
+}
+
+int HTTPServer::Session::checkIdleTimeout() {
+  time_t now = time(0);
+  int timeout = (lastActive + rfb::Server::idleTimeout) - now;
+  if (timeout > 0)
+    return timeout * 1000;
+  sock.shutdown();
+  return 0;
+}
+
+// -=- Constructor / destructor
+
+HTTPServer::HTTPServer() {
+}
+
+HTTPServer::~HTTPServer() {
+  std::list<Session*>::iterator i;
+  for (i=sessions.begin(); i!=sessions.end(); i++) {
+    delete (*i)->getSock();
+    delete *i;
+  }
+}
+
+
+// -=- SocketServer interface implementation
+
+void
+HTTPServer::addClient(network::Socket* sock) {
+  Session* s = new Session(*sock, *this);
+  if (!s) {
+    sock->shutdown();
+  } else {
+    sock->inStream().setTimeout(rfb::Server::clientWaitTimeMillis);
+    sock->outStream().setTimeout(rfb::Server::clientWaitTimeMillis);
+    sessions.push_front(s);
+  }
+}
+
+bool
+HTTPServer::processSocketEvent(network::Socket* sock) {
+  std::list<Session*>::iterator i;
+  for (i=sessions.begin(); i!=sessions.end(); i++) {
+    if ((*i)->getSock() == sock) {
+      try {
+        if ((*i)->processHTTP()) {
+          vlog.info("completed HTTP request");
+          delete *i;
+          sessions.erase(i);
+          break;
+        }
+        return true;
+      } catch (rdr::Exception& e) {
+        vlog.error("untrapped: %s", e.str());
+        delete *i;
+        sessions.erase(i);
+        break;
+      }
+    }
+  }
+  delete sock;
+  return false;
+}
+
+void HTTPServer::getSockets(std::list<network::Socket*>* sockets)
+{
+  sockets->clear();
+  std::list<Session*>::iterator ci;
+  for (ci = sessions.begin(); ci != sessions.end(); ci++) {
+    sockets->push_back((*ci)->getSock());
+  }
+}
+
+int HTTPServer::checkTimeouts() {
+  std::list<Session*>::iterator ci;
+  int timeout = 0;
+  for (ci = sessions.begin(); ci != sessions.end(); ci++) {
+    soonestTimeout(&timeout, (*ci)->checkIdleTimeout());
+  }
+  return timeout;
+}
+
+
+// -=- Default getFile implementation
+
+InStream*
+HTTPServer::getFile(const char* name, const char** contentType) {
+  return 0;
+}
+
+const char*
+HTTPServer::guessContentType(const char* name, const char* defType) {
+  CharArray file, ext;
+  if (!strSplit(name, '.', &file.buf, &ext.buf))
+    return defType;
+  if (strcasecmp(ext.buf, "html") == 0 ||
+    strcasecmp(ext.buf, "htm") == 0) {
+    return "text/html";
+  } else if (strcasecmp(ext.buf, "txt") == 0) {
+    return "text/plain";
+  } else if (strcasecmp(ext.buf, "gif") == 0) {
+    return "image/gif";
+  } else if (strcasecmp(ext.buf, "jpg") == 0) {
+    return "image/jpeg";
+  } else if (strcasecmp(ext.buf, "jar") == 0) {
+    return "application/java-archive";
+  } else if (strcasecmp(ext.buf, "exe") == 0) {
+    return "application/octet-stream";
+  }
+  return defType;
+}
