diff --git a/peerconnection/samples/server/data_socket.cc b/peerconnection/samples/server/data_socket.cc
new file mode 100644
index 0000000..6abe8c4
--- /dev/null
+++ b/peerconnection/samples/server/data_socket.cc
@@ -0,0 +1,288 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "peerconnection/samples/server/data_socket.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "peerconnection/samples/server/utils.h"
+
+static const char kHeaderTerminator[] = "\r\n\r\n";
+static const int kHeaderTerminatorLength = sizeof(kHeaderTerminator) - 1;
+
+// static
+const char DataSocket::kCrossOriginAllowHeaders[] =
+    "Access-Control-Allow-Origin: *\r\n"
+    "Access-Control-Allow-Credentials: true\r\n"
+    "Access-Control-Allow-Methods: POST, GET, OPTIONS\r\n"
+    "Access-Control-Allow-Headers: Content-Type, "
+        "Content-Length, Connection, Cache-Control\r\n"
+    "Access-Control-Expose-Headers: Content-Length, X-Peer-Id\r\n";
+
+#if defined(WIN32)
+class WinsockInitializer {
+  static WinsockInitializer singleton;
+
+  WinsockInitializer() {
+    WSADATA data;
+    WSAStartup(MAKEWORD(1, 0), &data);
+  }
+
+ public:
+  ~WinsockInitializer() { WSACleanup(); }
+};
+WinsockInitializer WinsockInitializer::singleton;
+#endif
+
+//
+// SocketBase
+//
+
+bool SocketBase::Create() {
+  assert(!valid());
+  socket_ = ::socket(AF_INET, SOCK_STREAM, 0);
+  return valid();
+}
+
+void SocketBase::Close() {
+  if (socket_ != INVALID_SOCKET) {
+    closesocket(socket_);
+    socket_ = INVALID_SOCKET;
+  }
+}
+
+//
+// DataSocket
+//
+
+std::string DataSocket::request_arguments() const {
+  size_t args = request_path_.find('?');
+  if (args != std::string::npos)
+    return request_path_.substr(args + 1);
+  return "";
+}
+
+bool DataSocket::PathEquals(const char* path) const {
+  assert(path);
+  size_t args = request_path_.find('?');
+  if (args != std::string::npos)
+    return request_path_.substr(0, args).compare(path) == 0;
+  return request_path_.compare(path) == 0;
+}
+
+bool DataSocket::OnDataAvailable(bool* close_socket) {
+  assert(valid());
+  char buffer[0xfff] = {0};
+  int bytes = recv(socket_, buffer, sizeof(buffer), 0);
+  if (bytes == SOCKET_ERROR || bytes == 0) {
+    *close_socket = true;
+    return false;
+  }
+
+  *close_socket = false;
+
+  bool ret = true;
+  if (headers_received()) {
+    if (method_ != POST) {
+      // unexpectedly received data.
+      ret = false;
+    } else {
+      data_.append(buffer, bytes);
+    }
+  } else {
+    request_headers_.append(buffer, bytes);
+    size_t found = request_headers_.find(kHeaderTerminator);
+    if (found != std::string::npos) {
+      data_ = request_headers_.substr(found + kHeaderTerminatorLength);
+      request_headers_.resize(found + kHeaderTerminatorLength);
+      ret = ParseHeaders();
+    }
+  }
+  return ret;
+}
+
+bool DataSocket::Send(const std::string& data) const {
+  return send(socket_, data.data(), data.length(), 0) != SOCKET_ERROR;
+}
+
+bool DataSocket::Send(const std::string& status, bool connection_close,
+                      const std::string& content_type,
+                      const std::string& extra_headers,
+                      const std::string& data) const {
+  assert(valid());
+  assert(!status.empty());
+  std::string buffer("HTTP/1.1 " + status + "\r\n");
+
+  buffer += "Server: PeerConnectionTestServer/0.1\r\n"
+            "Cache-Control: no-cache\r\n";
+
+  if (connection_close)
+    buffer += "Connection: close\r\n";
+
+  if (!content_type.empty())
+    buffer += "Content-Type: " + content_type + "\r\n";
+
+  buffer += "Content-Length: " + int2str(data.size()) + "\r\n";
+
+  if (!extra_headers.empty()) {
+    buffer += extra_headers;
+    // Extra headers are assumed to have a separator per header.
+  }
+
+  buffer += kCrossOriginAllowHeaders;
+
+  buffer += "\r\n";
+  buffer += data;
+
+  return Send(buffer);
+}
+
+void DataSocket::Clear() {
+  method_ = INVALID;
+  content_length_ = 0;
+  content_type_.clear();
+  request_path_.clear();
+  request_headers_.clear();
+  data_.clear();
+}
+
+bool DataSocket::ParseHeaders() {
+  assert(!request_headers_.empty());
+  assert(method_ == INVALID);
+  size_t i = request_headers_.find("\r\n");
+  if (i == std::string::npos)
+    return false;
+
+  if (!ParseMethodAndPath(request_headers_.data(), i))
+    return false;
+
+  assert(method_ != INVALID);
+  assert(!request_path_.empty());
+
+  if (method_ == POST) {
+    const char* headers = request_headers_.data() + i + 2;
+    size_t len = request_headers_.length() - i - 2;
+    if (!ParseContentLengthAndType(headers, len))
+      return false;
+  }
+
+  return true;
+}
+
+bool DataSocket::ParseMethodAndPath(const char* begin, size_t len) {
+  struct {
+    const char* method_name;
+    size_t method_name_len;
+    RequestMethod id;
+  } supported_methods[] = {
+    { "GET", 3, GET },
+    { "POST", 4, POST },
+    { "OPTIONS", 7, OPTIONS },
+  };
+
+  const char* path = NULL;
+  for (size_t i = 0; i < ARRAYSIZE(supported_methods); ++i) {
+    if (len > supported_methods[i].method_name_len &&
+        isspace(begin[supported_methods[i].method_name_len]) &&
+        strncmp(begin, supported_methods[i].method_name,
+                supported_methods[i].method_name_len) == 0) {
+      method_ = supported_methods[i].id;
+      path = begin + supported_methods[i].method_name_len;
+      break;
+    }
+  }
+
+  const char* end = begin + len;
+  if (!path || path >= end)
+    return false;
+
+  ++path;
+  begin = path;
+  while (!isspace(*path) && path < end)
+    ++path;
+
+  request_path_.assign(begin, path - begin);
+
+  return true;
+}
+
+bool DataSocket::ParseContentLengthAndType(const char* headers, size_t length) {
+  assert(content_length_ == 0);
+  assert(content_type_.empty());
+
+  const char* end = headers + length;
+  while (headers && headers < end) {
+    if (!isspace(headers[0])) {
+      static const char kContentLength[] = "Content-Length:";
+      static const char kContentType[] = "Content-Type:";
+      if ((headers + ARRAYSIZE(kContentLength)) < end &&
+          strncmp(headers, kContentLength,
+                  ARRAYSIZE(kContentLength) - 1) == 0) {
+        headers += ARRAYSIZE(kContentLength) - 1;
+        while (headers[0] == ' ')
+          ++headers;
+        content_length_ = atoi(headers);
+      } else if ((headers + ARRAYSIZE(kContentType)) < end &&
+                 strncmp(headers, kContentType,
+                         ARRAYSIZE(kContentType) - 1) == 0) {
+        headers += ARRAYSIZE(kContentType) - 1;
+        while (headers[0] == ' ')
+          ++headers;
+        const char* type_end = strstr(headers, "\r\n");
+        if (type_end == NULL)
+          type_end = end;
+        content_type_.assign(headers, type_end);
+      }
+    } else {
+      ++headers;
+    }
+    headers = strstr(headers, "\r\n");
+    if (headers)
+      headers += 2;
+  }
+
+  return !content_type_.empty() && content_length_ != 0;
+}
+
+//
+// ListeningSocket
+//
+
+bool ListeningSocket::Listen(unsigned short port) {
+  assert(valid());
+  int enabled = 1;
+  setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR,
+      reinterpret_cast<const char*>(&enabled), sizeof(enabled));
+  struct sockaddr_in addr = {0};
+  addr.sin_family = AF_INET;
+  addr.sin_addr.s_addr = htonl(INADDR_ANY);
+  addr.sin_port = htons(port);
+  if (bind(socket_, reinterpret_cast<const sockaddr*>(&addr),
+           sizeof(addr)) == SOCKET_ERROR) {
+    printf("bind failed\n");
+    return false;
+  }
+  return listen(socket_, 5) != SOCKET_ERROR;
+}
+
+DataSocket* ListeningSocket::Accept() const {
+  assert(valid());
+  struct sockaddr_in addr = {0};
+  socklen_t size = sizeof(addr);
+  int client = accept(socket_, reinterpret_cast<sockaddr*>(&addr), &size);
+  if (client == INVALID_SOCKET)
+    return NULL;
+
+  return new DataSocket(client);
+}
+
diff --git a/peerconnection/samples/server/data_socket.h b/peerconnection/samples/server/data_socket.h
new file mode 100644
index 0000000..c35da83
--- /dev/null
+++ b/peerconnection/samples/server/data_socket.h
@@ -0,0 +1,151 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef PEERCONNECTION_SAMPLES_SERVER_DATA_SOCKET_H_
+#define PEERCONNECTION_SAMPLES_SERVER_DATA_SOCKET_H_
+#pragma once
+
+#ifdef WIN32
+#include <winsock2.h>
+typedef int socklen_t;
+#else
+#include <netinet/in.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#define closesocket close
+#endif
+
+#include <string>
+
+#ifndef SOCKET_ERROR
+#define SOCKET_ERROR (-1)
+#endif
+
+#ifndef INVALID_SOCKET
+#define INVALID_SOCKET  static_cast<int>(~0)
+#endif
+
+class SocketBase {
+ public:
+  SocketBase() : socket_(INVALID_SOCKET) { }
+  explicit SocketBase(int socket) : socket_(socket) { }
+  ~SocketBase() { Close(); }
+
+  int socket() const { return socket_; }
+  bool valid() const { return socket_ != INVALID_SOCKET; }
+
+  bool Create();
+  void Close();
+
+ protected:
+  int socket_;
+};
+
+// Represents an HTTP server socket.
+class DataSocket : public SocketBase {
+ public:
+  enum RequestMethod {
+    INVALID,
+    GET,
+    POST,
+    OPTIONS,
+  };
+
+  explicit DataSocket(int socket)
+      : SocketBase(socket),
+        method_(INVALID),
+        content_length_(0) {
+  }
+
+  ~DataSocket() {
+  }
+
+  static const char kCrossOriginAllowHeaders[];
+
+  bool headers_received() const { return method_ != INVALID; }
+
+  RequestMethod method() const { return method_; }
+
+  const std::string& request_path() const { return request_path_; }
+  std::string request_arguments() const;
+
+  const std::string& data() const { return data_; }
+
+  const std::string& content_type() const { return content_type_; }
+
+  size_t content_length() const { return content_length_; }
+
+  bool request_received() const {
+    return headers_received() && (method_ != POST || data_received());
+  }
+
+  bool data_received() const {
+    return method_ != POST || data_.length() >= content_length_;
+  }
+
+  // Checks if the request path (minus arguments) matches a given path.
+  bool PathEquals(const char* path) const;
+
+  // Called when we have received some data from clients.
+  // Returns false if an error occurred.
+  bool OnDataAvailable(bool* close_socket);
+
+  // Send a raw buffer of bytes.
+  bool Send(const std::string& data) const;
+
+  // Send an HTTP response.  The |status| should start with a valid HTTP
+  // response code, followed by a string.  E.g. "200 OK".
+  // If |connection_close| is set to true, an extra "Connection: close" HTTP
+  // header will be included.  |content_type| is the mime content type, not
+  // including the "Content-Type: " string.
+  // |extra_headers| should be either empty or a list of headers where each
+  // header terminates with "\r\n".
+  // |data| is the body of the message.  It's length will be specified via
+  // a "Content-Length" header.
+  bool Send(const std::string& status, bool connection_close,
+            const std::string& content_type,
+            const std::string& extra_headers, const std::string& data) const;
+
+  // Clears all held state and prepares the socket for receiving a new request.
+  void Clear();
+
+ protected:
+  // A fairly relaxed HTTP header parser.  Parses the method, path and
+  // content length (POST only) of a request.
+  // Returns true if a valid request was received and no errors occurred.
+  bool ParseHeaders();
+
+  // Figures out whether the request is a GET or POST and what path is
+  // being requested.
+  bool ParseMethodAndPath(const char* begin, size_t len);
+
+  // Determines the length of the body and it's mime type.
+  bool ParseContentLengthAndType(const char* headers, size_t length);
+
+ protected:
+  RequestMethod method_;
+  size_t content_length_;
+  std::string content_type_;
+  std::string request_path_;
+  std::string request_headers_;
+  std::string data_;
+};
+
+// The server socket.  Accepts connections and generates DataSocket instances
+// for each new connection.
+class ListeningSocket : public SocketBase {
+ public:
+  ListeningSocket() {}
+
+  bool Listen(unsigned short port);
+  DataSocket* Accept() const;
+};
+
+#endif  // PEERCONNECTION_SAMPLES_SERVER_DATA_SOCKET_H_
diff --git a/peerconnection/samples/server/main.cc b/peerconnection/samples/server/main.cc
new file mode 100644
index 0000000..1c46ce2
--- /dev/null
+++ b/peerconnection/samples/server/main.cc
@@ -0,0 +1,160 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <vector>
+
+#include "peerconnection/samples/server/data_socket.h"
+#include "peerconnection/samples/server/peer_channel.h"
+#include "peerconnection/samples/server/utils.h"
+
+static const int kMaxConnections = (FD_SETSIZE - 2);
+
+void HandleBrowserRequest(DataSocket* ds, bool* quit) {
+  assert(ds && ds->valid());
+  assert(quit);
+
+  const std::string& path = ds->request_path();
+
+  *quit = (path.compare("/quit") == 0);
+
+  if (*quit) {
+    ds->Send("200 OK", true, "text/html", "",
+             "<html><body>Quitting...</body></html>");
+  } else if (ds->method() == DataSocket::OPTIONS) {
+    // We'll get this when a browsers do cross-resource-sharing requests.
+    // The headers to allow cross-origin script support will be set inside
+    // Send.
+    ds->Send("200 OK", true, "", "", "");
+  } else {
+    // Here we could write some useful output back to the browser depending on
+    // the path.
+    printf("Received an invalid request: %s\n", ds->request_path().c_str());
+    ds->Send("500 Sorry", true, "text/html", "",
+             "<html><body>Sorry, not yet implemented</body></html>");
+  }
+}
+
+int main(int argc, char** argv) {
+  // TODO(tommi): make configurable.
+  static const unsigned short port = 8888;
+
+  ListeningSocket listener;
+  if (!listener.Create()) {
+    printf("Failed to create server socket\n");
+    return -1;
+  } else if (!listener.Listen(port)) {
+    printf("Failed to listen on server socket\n");
+    return -1;
+  }
+
+  printf("Server listening on port %i\n", port);
+
+  PeerChannel clients;
+  typedef std::vector<DataSocket*> SocketArray;
+  SocketArray sockets;
+  bool quit = false;
+  while (!quit) {
+    fd_set socket_set;
+    FD_ZERO(&socket_set);
+    if (listener.valid())
+      FD_SET(listener.socket(), &socket_set);
+
+    for (SocketArray::iterator i = sockets.begin(); i != sockets.end(); ++i)
+      FD_SET((*i)->socket(), &socket_set);
+
+    struct timeval timeout = { 10, 0 };
+    if (select(FD_SETSIZE, &socket_set, NULL, NULL, &timeout) == SOCKET_ERROR) {
+      printf("select failed\n");
+      break;
+    }
+
+    for (SocketArray::iterator i = sockets.begin(); i != sockets.end(); ++i) {
+      DataSocket* s = *i;
+      bool socket_done = true;
+      if (FD_ISSET(s->socket(), &socket_set)) {
+        if (s->OnDataAvailable(&socket_done) && s->request_received()) {
+          ChannelMember* member = clients.Lookup(s);
+          if (member || PeerChannel::IsPeerConnection(s)) {
+            if (!member) {
+              if (s->PathEquals("/sign_in")) {
+                clients.AddMember(s);
+              } else {
+                printf("No member found for: %s\n",
+                    s->request_path().c_str());
+                s->Send("500 Error", true, "text/plain", "",
+                        "Peer most likely gone.");
+              }
+            } else if (member->is_waiting_socket(s)) {
+              // no need to do anything.
+              socket_done = false;
+            } else {
+              ChannelMember* target = clients.IsTargetedRequest(s);
+              if (target) {
+                member->ForwardRequestToPeer(s, target);
+              } else if (s->PathEquals("/sign_out")) {
+                s->Send("200 OK", true, "text/plain", "", "");
+              } else {
+                printf("Couldn't find target for request: %s\n",
+                    s->request_path().c_str());
+                s->Send("500 Error", true, "text/plain", "",
+                        "Peer most likely gone.");
+              }
+            }
+          } else {
+            HandleBrowserRequest(s, &quit);
+            if (quit) {
+              printf("Quitting...\n");
+              FD_CLR(listener.socket(), &socket_set);
+              listener.Close();
+              clients.CloseAll();
+            }
+          }
+        }
+      } else {
+        socket_done = false;
+      }
+
+      if (socket_done) {
+        printf("Disconnecting socket\n");
+        clients.OnClosing(s);
+        assert(s->valid());  // Close must not have been called yet.
+        FD_CLR(s->socket(), &socket_set);
+        delete (*i);
+        i = sockets.erase(i);
+        if (i == sockets.end())
+          break;
+      }
+    }
+
+    clients.CheckForTimeout();
+
+    if (FD_ISSET(listener.socket(), &socket_set)) {
+      DataSocket* s = listener.Accept();
+      if (sockets.size() >= kMaxConnections) {
+        delete s;  // sorry, that's all we can take.
+        printf("Connection limit reached\n");
+      } else {
+        sockets.push_back(s);
+        printf("New connection...\n");
+      }
+    }
+  }
+
+  for (SocketArray::iterator i = sockets.begin(); i != sockets.end(); ++i)
+    delete (*i);
+  sockets.clear();
+
+  return 0;
+}
diff --git a/peerconnection/samples/server/peer_channel.cc b/peerconnection/samples/server/peer_channel.cc
new file mode 100644
index 0000000..1c8cf98
--- /dev/null
+++ b/peerconnection/samples/server/peer_channel.cc
@@ -0,0 +1,342 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "peerconnection/samples/server/peer_channel.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <algorithm>
+
+#include "peerconnection/samples/server/data_socket.h"
+#include "peerconnection/samples/server/utils.h"
+
+// Set to the peer id of the originator when messages are being
+// exchanged between peers, but set to the id of the receiving peer
+// itself when notifications are sent from the server about the state
+// of other peers.
+//
+// WORKAROUND: Since support for CORS varies greatly from one browser to the
+// next, we don't use a custom name for our peer-id header (originally it was
+// "X-Peer-Id: ").  Instead, we use a "simple header", "Pragma" which should
+// always be exposed to CORS requests.  There is a special CORS header devoted
+// to exposing proprietary headers (Access-Control-Expose-Headers), however
+// at this point it is not working correctly in some popular browsers.
+static const char kPeerIdHeader[] = "Pragma: ";
+
+//
+// ChannelMember
+//
+
+int ChannelMember::s_member_id_ = 0;
+
+ChannelMember::ChannelMember(DataSocket* socket)
+  : waiting_socket_(NULL), id_(++s_member_id_),
+    connected_(true), timestamp_(time(NULL)) {
+  assert(socket);
+  assert(socket->method() == DataSocket::GET);
+  assert(socket->PathEquals("/sign_in"));
+  name_ = socket->request_arguments();  // TODO(tommi): urldecode
+  if (!name_.length())
+    name_ = "peer_" + int2str(id_);
+  std::replace(name_.begin(), name_.end(), ',', '_');
+}
+
+ChannelMember::~ChannelMember() {
+}
+
+bool ChannelMember::TimedOut() {
+  return waiting_socket_ == NULL && (time(NULL) - timestamp_) > 30;
+}
+
+std::string ChannelMember::GetPeerIdHeader() const {
+  std::string ret(kPeerIdHeader + int2str(id_) + "\r\n");
+  return ret;
+}
+
+bool ChannelMember::NotifyOfOtherMember(const ChannelMember& other) {
+  assert(&other != this);
+  QueueResponse("200 OK", "text/plain", GetPeerIdHeader(),
+                other.GetEntry());
+  return true;
+}
+
+// Returns a string in the form "name,id\n".
+std::string ChannelMember::GetEntry() const {
+  char entry[1024] = {0};
+  sprintf(entry, "%s,%i,%i\n", name_.c_str(), id_, connected_);  // NOLINT
+  return entry;
+}
+
+void ChannelMember::ForwardRequestToPeer(DataSocket* ds, ChannelMember* peer) {
+  assert(peer);
+  assert(ds);
+
+  std::string extra_headers(GetPeerIdHeader());
+
+  if (peer == this) {
+    ds->Send("200 OK", true, ds->content_type(), extra_headers,
+             ds->data());
+  } else {
+    printf("Client %s sending to %s\n",
+        name_.c_str(), peer->name().c_str());
+    peer->QueueResponse("200 OK", ds->content_type(), extra_headers,
+                        ds->data());
+    ds->Send("200 OK", true, "text/plain", "", "");
+  }
+}
+
+void ChannelMember::OnClosing(DataSocket* ds) {
+  if (ds == waiting_socket_) {
+    waiting_socket_ = NULL;
+    timestamp_ = time(NULL);
+  }
+}
+
+void ChannelMember::QueueResponse(const std::string& status,
+                                  const std::string& content_type,
+                                  const std::string& extra_headers,
+                                  const std::string& data) {
+  if (waiting_socket_) {
+    assert(queue_.size() == 0);
+    assert(waiting_socket_->method() == DataSocket::GET);
+    bool ok = waiting_socket_->Send(status, true, content_type, extra_headers,
+                                    data);
+    if (!ok) {
+      printf("Failed to deliver data to waiting socket\n");
+    }
+    waiting_socket_ = NULL;
+    timestamp_ = time(NULL);
+  } else {
+    QueuedResponse qr;
+    qr.status = status;
+    qr.content_type = content_type;
+    qr.extra_headers = extra_headers;
+    qr.data = data;
+    queue_.push(qr);
+  }
+}
+
+void ChannelMember::SetWaitingSocket(DataSocket* ds) {
+  assert(ds->method() == DataSocket::GET);
+  if (ds && !queue_.empty()) {
+    assert(waiting_socket_ == NULL);
+    const QueuedResponse& response = queue_.back();
+    ds->Send(response.status, true, response.content_type,
+             response.extra_headers, response.data);
+    queue_.pop();
+  } else {
+    waiting_socket_ = ds;
+  }
+}
+
+
+//
+// PeerChannel
+//
+
+// static
+bool PeerChannel::IsPeerConnection(const DataSocket* ds) {
+  assert(ds);
+  return (ds->method() == DataSocket::POST && ds->content_length() > 0) ||
+         (ds->method() == DataSocket::GET && ds->PathEquals("/sign_in"));
+}
+
+ChannelMember* PeerChannel::Lookup(DataSocket* ds) const {
+  assert(ds);
+
+  if (ds->method() != DataSocket::GET && ds->method() != DataSocket::POST)
+    return NULL;
+
+  static const char* kRequests[] = {
+    "/wait", "/sign_out", "/message",
+  };
+  int i = 0;
+  for (; i < ARRAYSIZE(kRequests); ++i) {
+    if (ds->PathEquals(kRequests[i]))
+      break;
+  }
+
+  if (i == ARRAYSIZE(kRequests))
+    return NULL;
+
+  std::string args(ds->request_arguments());
+  static const char kPeerId[] = "peer_id=";
+  size_t found = args.find(kPeerId);
+  if (found == std::string::npos)
+    return NULL;
+
+  int id = atoi(&args[found + ARRAYSIZE(kPeerId) - 1]);
+  Members::const_iterator iter = members_.begin();
+  for (; iter != members_.end(); ++iter) {
+    if (id == (*iter)->id()) {
+      if (i == 0)  // wait
+        (*iter)->SetWaitingSocket(ds);
+      if (i == 1)  // sign_out
+        (*iter)->set_disconnected();
+      return *iter;
+    }
+  }
+
+  return NULL;
+}
+
+ChannelMember* PeerChannel::IsTargetedRequest(const DataSocket* ds) const {
+  assert(ds);
+  // Regardless of GET or POST, we look for the peer_id parameter
+  // only in the request_path.
+  const std::string& path = ds->request_path();
+  size_t args = path.find('?');
+  if (args == std::string::npos)
+    return NULL;
+  size_t found;
+  const char kTargetPeerIdParam[] = "to=";
+  do {
+    found = path.find(kTargetPeerIdParam, args);
+    if (found == std::string::npos)
+      return NULL;
+    if (found == (args + 1) || path[found - 1] == '&') {
+      found += ARRAYSIZE(kTargetPeerIdParam) - 1;
+      break;
+    }
+    args = found + ARRAYSIZE(kTargetPeerIdParam) - 1;
+  } while (true);
+  int id = atoi(&path[found]);
+  Members::const_iterator i = members_.begin();
+  for (; i != members_.end(); ++i) {
+    if ((*i)->id() == id) {
+      return *i;
+    }
+  }
+  return NULL;
+}
+
+bool PeerChannel::AddMember(DataSocket* ds) {
+  assert(IsPeerConnection(ds));
+  ChannelMember* new_guy = new ChannelMember(ds);
+  Members failures;
+  BroadcastChangedState(*new_guy, &failures);
+  HandleDeliveryFailures(&failures);
+  members_.push_back(new_guy);
+
+  printf("New member added (total=%i): %s\n",
+      members_.size(), new_guy->name().c_str());
+
+  // Let the newly connected peer know about other members of the channel.
+  std::string content_type;
+  std::string response = BuildResponseForNewMember(*new_guy, &content_type);
+  ds->Send("200 Added", true, content_type, new_guy->GetPeerIdHeader(),
+           response);
+  return true;
+}
+
+void PeerChannel::CloseAll() {
+  Members::const_iterator i = members_.begin();
+  for (; i != members_.end(); ++i) {
+    (*i)->QueueResponse("200 OK", "text/plain", "", "Server shutting down");
+  }
+  DeleteAll();
+}
+
+void PeerChannel::OnClosing(DataSocket* ds) {
+  for (Members::iterator i = members_.begin(); i != members_.end(); ++i) {
+    ChannelMember* m = (*i);
+    m->OnClosing(ds);
+    if (!m->connected()) {
+      i = members_.erase(i);
+      Members failures;
+      BroadcastChangedState(*m, &failures);
+      HandleDeliveryFailures(&failures);
+      delete m;
+      if (i == members_.end())
+        break;
+    }
+  }
+  printf("Total connected: %i\n", members_.size());
+}
+
+void PeerChannel::CheckForTimeout() {
+  for (Members::iterator i = members_.begin(); i != members_.end(); ++i) {
+    ChannelMember* m = (*i);
+    if (m->TimedOut()) {
+      printf("Timeout: %s\n", m->name().c_str());
+      m->set_disconnected();
+      i = members_.erase(i);
+      Members failures;
+      BroadcastChangedState(*m, &failures);
+      HandleDeliveryFailures(&failures);
+      delete m;
+      if (i == members_.end())
+        break;
+    }
+  }
+}
+
+void PeerChannel::DeleteAll() {
+  for (Members::iterator i = members_.begin(); i != members_.end(); ++i)
+    delete (*i);
+  members_.clear();
+}
+
+void PeerChannel::BroadcastChangedState(const ChannelMember& member,
+                                        Members* delivery_failures) {
+  // This function should be called prior to DataSocket::Close().
+  assert(delivery_failures);
+
+  if (!member.connected()) {
+    printf("Member disconnected: %s\n", member.name().c_str());
+  }
+
+  Members::iterator i = members_.begin();
+  for (; i != members_.end(); ++i) {
+    if (&member != (*i)) {
+      if (!(*i)->NotifyOfOtherMember(member)) {
+        (*i)->set_disconnected();
+        delivery_failures->push_back(*i);
+        i = members_.erase(i);
+        if (i == members_.end())
+          break;
+      }
+    }
+  }
+}
+
+void PeerChannel::HandleDeliveryFailures(Members* failures) {
+  assert(failures);
+
+  while (!failures->empty()) {
+    Members::iterator i = failures->begin();
+    ChannelMember* member = *i;
+    assert(!member->connected());
+    failures->erase(i);
+    BroadcastChangedState(*member, failures);
+    delete member;
+  }
+}
+
+// Builds a simple list of "name,id\n" entries for each member.
+std::string PeerChannel::BuildResponseForNewMember(const ChannelMember& member,
+                                                   std::string* content_type) {
+  assert(content_type);
+
+  *content_type = "text/plain";
+  // The peer itself will always be the first entry.
+  std::string response(member.GetEntry());
+  for (Members::iterator i = members_.begin(); i != members_.end(); ++i) {
+    if (member.id() != (*i)->id()) {
+      assert((*i)->connected());
+      response += (*i)->GetEntry();
+    }
+  }
+
+  return response;
+}
diff --git a/peerconnection/samples/server/peer_channel.h b/peerconnection/samples/server/peer_channel.h
new file mode 100644
index 0000000..f845a85
--- /dev/null
+++ b/peerconnection/samples/server/peer_channel.h
@@ -0,0 +1,120 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef PEERCONNECTION_SAMPLES_SERVER_PEER_CHANNEL_H_
+#define PEERCONNECTION_SAMPLES_SERVER_PEER_CHANNEL_H_
+#pragma once
+
+#include <time.h>
+
+#include <queue>
+#include <string>
+#include <vector>
+
+class DataSocket;
+
+// Represents a single peer connected to the server.
+class ChannelMember {
+ public:
+  explicit ChannelMember(DataSocket* socket);
+  ~ChannelMember();
+
+  bool connected() const { return connected_; }
+  int id() const { return id_; }
+  void set_disconnected() { connected_ = false; }
+  bool is_waiting_socket(DataSocket* ds) const { return waiting_socket_ == ds; }
+  const std::string& name() const { return name_; }
+
+  bool TimedOut();
+
+  std::string GetPeerIdHeader() const;
+
+  bool NotifyOfOtherMember(const ChannelMember& other);
+
+  // Returns a string in the form "name,id\n".
+  std::string GetEntry() const;
+
+  void ForwardRequestToPeer(DataSocket* ds, ChannelMember* peer);
+
+  void OnClosing(DataSocket* ds);
+
+  void QueueResponse(const std::string& status, const std::string& content_type,
+                     const std::string& extra_headers, const std::string& data);
+
+  void SetWaitingSocket(DataSocket* ds);
+
+ protected:
+  struct QueuedResponse {
+    std::string status, content_type, extra_headers, data;
+  };
+
+  DataSocket* waiting_socket_;
+  int id_;
+  bool connected_;
+  time_t timestamp_;
+  std::string name_;
+  std::queue<QueuedResponse> queue_;
+  static int s_member_id_;
+};
+
+// Manages all currently connected peers.
+class PeerChannel {
+ public:
+  typedef std::vector<ChannelMember*> Members;
+
+  PeerChannel() {
+  }
+
+  ~PeerChannel() {
+    DeleteAll();
+  }
+
+  const Members& members() const { return members_; }
+
+  // Returns true if the request should be treated as a new ChannelMember
+  // request.  Otherwise the request is not peerconnection related.
+  static bool IsPeerConnection(const DataSocket* ds);
+
+  // Finds a connected peer that's associated with the |ds| socket.
+  ChannelMember* Lookup(DataSocket* ds) const;
+
+  // Checks if the request has a "peer_id" parameter and if so, looks up the
+  // peer for which the request is targeted at.
+  ChannelMember* IsTargetedRequest(const DataSocket* ds) const;
+
+  // Adds a new ChannelMember instance to the list of connected peers and
+  // associates it with the socket.
+  bool AddMember(DataSocket* ds);
+
+  // Closes all connections and sends a "shutting down" message to all
+  // connected peers.
+  void CloseAll();
+
+  // Called when a socket was determined to be closing by the peer (or if the
+  // connection went dead).
+  void OnClosing(DataSocket* ds);
+
+  void CheckForTimeout();
+
+ protected:
+  void DeleteAll();
+  void BroadcastChangedState(const ChannelMember& member,
+                             Members* delivery_failures);
+  void HandleDeliveryFailures(Members* failures);
+
+  // Builds a simple list of "name,id\n" entries for each member.
+  std::string BuildResponseForNewMember(const ChannelMember& member,
+                                        std::string* content_type);
+
+ protected:
+  Members members_;
+};
+
+#endif  // PEERCONNECTION_SAMPLES_SERVER_PEER_CHANNEL_H_
diff --git a/peerconnection/samples/server/server_test.html b/peerconnection/samples/server/server_test.html
new file mode 100644
index 0000000..a02858e
--- /dev/null
+++ b/peerconnection/samples/server/server_test.html
@@ -0,0 +1,210 @@
+<html>
+<head>
+<title>PeerConnection server test page</title>
+
+<script>
+var request = null;
+var hangingGet = null;
+var localName;
+var server;
+var my_id = -1;
+var other_peers = {};
+
+function trace(txt) {
+  var elem = document.getElementById("debug");
+  elem.innerHTML += txt + "<br>";
+}
+
+function handleServerNotification(data) {
+  trace("Server notification: " + data);
+  var parsed = data.split(',');
+  if (parseInt(parsed[2]) != 0)
+    other_peers[parseInt(parsed[1])] = parsed[0];
+}
+
+function handlePeerMessage(peer_id, data) {
+  trace("Message from '" + other_peers[peer_id] + "': " + data);
+  if (document.getElementById("loopback").checked) {
+    if (data.search('"port" : "0"') == -1) {
+      sendToPeer(peer_id, data);
+    } else {
+      trace("Not looping back quit message");
+    }
+  }
+}
+
+function GetIntHeader(r, name) {
+  var val = r.getResponseHeader(name);
+  trace("header value: " + val);
+  return val != null && val.length ? parseInt(val) : -1;
+}
+
+function hangingGetCallback() {
+  try {
+    if (hangingGet.readyState != 4)
+      return;
+    if (hangingGet.status != 200) {
+      trace("server error: " + hangingGet.statusText);
+      disconnect();
+    } else {
+      var peer_id = GetIntHeader(hangingGet, "Pragma");
+      if (peer_id == my_id) {
+        handleServerNotification(hangingGet.responseText);
+      } else {
+        handlePeerMessage(peer_id, hangingGet.responseText);
+      }
+    }
+
+    if (hangingGet) {
+      hangingGet.abort();
+      hangingGet = null;
+    }
+
+    if (my_id != -1)
+      window.setTimeout(startHangingGet, 0);
+  } catch (e) {
+    trace("Hanging get error: " + e.description);
+  }
+}
+
+function startHangingGet() {
+  try {
+    hangingGet = new XMLHttpRequest();
+    hangingGet.onreadystatechange = hangingGetCallback;
+    hangingGet.ontimeout = onHangingGetTimeout;
+    hangingGet.open("GET", server + "/wait?peer_id=" + my_id, true);
+    hangingGet.send();  
+  } catch (e) {
+    trace("error" + e.description);
+  }
+}
+
+function onHangingGetTimeout() {
+  trace("hanging get timeout. issuing again.");
+  hangingGet.abort();
+  hangingGet = null;
+  if (my_id != -1)
+    window.setTimeout(startHangingGet, 0);
+}
+
+function signInCallback() {
+  try {
+    if (request.readyState == 4) {
+      if (request.status == 200) {
+        var peers = request.responseText.split("\n");
+        my_id = parseInt(peers[0].split(',')[1]);
+        trace("My id: " + my_id);
+        for (var i = 1; i < peers.length; ++i) {
+          if (peers[i].length > 0) {
+            trace("Peer " + i + ": " + peers[i]);
+            var parsed = peers[i].split(',');
+            other_peers[parseInt(parsed[1])] = parsed[0];
+          }
+        }
+        startHangingGet();
+        request = null;
+      }
+    }
+  } catch (e) {
+    trace("error: " + e.description);
+  }
+}
+
+function signIn() {
+  try {
+    request = new XMLHttpRequest();
+    request.onreadystatechange = signInCallback;
+    request.open("GET", server + "/sign_in?" + localName, true);
+    request.send();
+  } catch (e) {
+    trace("error: " + e.description);
+  }
+}
+
+function sendToPeer(peer_id, data) {
+  if (my_id == -1) {
+    alert("Not connected");
+    return;
+  }
+  if (peer_id == my_id) {
+    alert("Can't send a message to oneself :)");
+    return;
+  }
+  var r = new XMLHttpRequest();
+  r.open("POST", server + "/message?peer_id=" + my_id + "&to=" + peer_id, false);
+  r.setRequestHeader("Content-Type", "text/plain");
+  r.send(data);
+  r = null;
+}
+
+function connect() {
+  localName = document.getElementById("local").value.toLowerCase();
+  server = document.getElementById("server").value.toLowerCase();
+  if (localName.length == 0) {
+    alert("I need a name please.");
+    document.getElementById("local").focus();
+  } else {
+    document.getElementById("connect").disabled = true;
+    document.getElementById("disconnect").disabled = false;
+    document.getElementById("send").disabled = false;
+    signIn();
+  }
+}
+
+function disconnect() {
+  if (request) {
+    request.abort();
+    request = null;
+  }
+  
+  if (hangingGet) {
+    hangingGet.abort();
+    hangingGet = null;
+  }
+
+  if (my_id != -1) {
+    request = new XMLHttpRequest();
+    request.open("GET", server + "/sign_out?peer_id=" + my_id, false);
+    request.send();
+    request = null;
+    my_id = -1;
+  }
+
+  document.getElementById("connect").disabled = false;
+  document.getElementById("disconnect").disabled = true;
+  document.getElementById("send").disabled = true;
+}
+
+window.onbeforeunload = disconnect;
+
+function send() {
+  var text = document.getElementById("message").value;
+  var peer_id = parseInt(document.getElementById("peer_id").value);
+  if (!text.length || peer_id == 0) {
+    alert("No text supplied or invalid peer id");
+  } else {
+    sendToPeer(peer_id, text);
+  }
+}
+
+</script>
+
+</head>
+<body>
+
+Server: <input type="text" id="server" value="http://localhost:8888" /><br>
+<input type="checkbox" id="loopback"/> Loopback (just send received messages right back)<br>
+Your name: <input type="text" id="local" value="my_name"/>
+<button id="connect" onclick="connect();">Connect</button>
+<button disabled="true" id="disconnect" onclick="disconnect();">Disconnect</button><br>
+<table><tr><td>
+Target peer id: <input type="text" id="peer_id" size="3"/></td><td>
+Message: <input type="text" id="message"/></td><td>
+<button disabled="true" id="send" onclick="send();">Send</button></td></tr></table>
+<button onclick="document.getElementById('debug').innerHTML='';">Clear log</button>
+
+<pre id="debug">
+</pre>
+<br><hr>
+</body>
+</html>
\ No newline at end of file
diff --git a/peerconnection/samples/server/utils.cc b/peerconnection/samples/server/utils.cc
new file mode 100644
index 0000000..7cdd045
--- /dev/null
+++ b/peerconnection/samples/server/utils.cc
@@ -0,0 +1,19 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "peerconnection/samples/server/utils.h"
+
+#include <stdio.h>
+
+std::string int2str(int i) {
+  char buffer[11] = {0};
+  sprintf(buffer, "%d", i);  // NOLINT
+  return buffer;
+}
diff --git a/peerconnection/samples/server/utils.h b/peerconnection/samples/server/utils.h
new file mode 100644
index 0000000..74672d3
--- /dev/null
+++ b/peerconnection/samples/server/utils.h
@@ -0,0 +1,22 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef PEERCONNECTION_SAMPLES_SERVER_UTILS_H_
+#define PEERCONNECTION_SAMPLES_SERVER_UTILS_H_
+#pragma once
+
+#include <string>
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+std::string int2str(int i);
+
+#endif  // PEERCONNECTION_SAMPLES_SERVER_UTILS_H_
