diff --git a/common/rfb/HTTPServer.cxx b/common/rfb/HTTPServer.cxx
new file mode 100644
index 0000000..e40d480
--- /dev/null
+++ b/common/rfb/HTTPServer.cxx
@@ -0,0 +1,411 @@
+/* Copyright (C) 2002-2005 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>
+
+#ifdef WIN32
+#define strcasecmp _stricmp
+#endif
+
+
+using namespace rfb;
+using namespace rdr;
+
+static LogWriter vlog("HTTPServer");
+
+const int clientWaitTimeMillis = 20000;
+const int idleTimeoutSecs = 5 * 60;
+
+
+//
+// -=- 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), contentLength(-1), lastModified(-1),
+      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;
+  int contentLength;
+  time_t lastModified;
+  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: TightVNC/4.0");
+  time_t now = time(0);
+  struct tm* tm = gmtime(&now);
+  strftime(buffer, 1024, "Date: %a, %d %b %Y %H:%M:%S GMT", tm);
+  writeLine(os, buffer);
+  if (lastModified == (time_t)-1 || lastModified == 0)
+    lastModified = now;
+  tm = gmtime(&lastModified);
+  strftime(buffer, 1024, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT", tm);
+  writeLine(os, buffer);
+  if (contentLength != -1) {
+    sprintf(buffer,"Content-Length: %d",contentLength);
+    writeLine(os, buffer);
+  }
+  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);
+        contentLength = -1;
+        lastModified = -1;
+        InStream* data = server.getFile(uri.buf, &contentType, &contentLength,
+                                        &lastModified);
+        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 + idleTimeoutSecs) - now;
+  if (timeout > 0)
+    return secsToMillis(timeout);
+  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;
+}
+
+
+// -=- SocketServer interface implementation
+
+void
+HTTPServer::addSocket(network::Socket* sock, bool) {
+  Session* s = new Session(*sock, *this);
+  if (!s) {
+    sock->shutdown();
+  } else {
+    sock->inStream().setTimeout(clientWaitTimeMillis);
+    sock->outStream().setTimeout(clientWaitTimeMillis);
+    sessions.push_front(s);
+  }
+}
+
+void
+HTTPServer::removeSocket(network::Socket* sock) {
+  std::list<Session*>::iterator i;
+  for (i=sessions.begin(); i!=sessions.end(); i++) {
+    if ((*i)->getSock() == sock) {
+      delete *i;
+      sessions.erase(i);
+      return;
+    }
+  }
+}
+
+void
+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");
+          sock->shutdown();
+        }
+      } catch (rdr::Exception& e) {
+        vlog.error("untrapped: %s", e.str());
+        sock->shutdown();
+      }
+      return;
+    }
+  }
+  throw rdr::Exception("invalid Socket in HTTPServer");
+}
+
+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,
+                    int* contentLength, time_t* lastModified)
+{
+  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;
+}
