147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *
447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */
1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <algorithm>
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/httpcommon-inl.h"
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/asyncsocket.h"
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/common.h"
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/httpserver.h"
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/logging.h"
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/socketstream.h"
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/thread.h"
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// HttpServer
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::HttpServer() : next_connection_id_(1), closing_(false) {
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::~HttpServer() {
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (closing_) {
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_WARNING) << "HttpServer::CloseAll has not completed";
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (ConnectionMap::iterator it = connections_.begin();
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org       it != connections_.end();
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org       ++it) {
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    StreamInterface* stream = it->second->EndProcess();
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete stream;
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete it->second;
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::HandleConnection(StreamInterface* stream) {
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int connection_id = next_connection_id_++;
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(connection_id != HTTP_INVALID_CONNECTION_ID);
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Connection* connection = new Connection(connection_id, this);
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  connections_.insert(ConnectionMap::value_type(connection_id, connection));
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  connection->BeginProcess(stream);
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return connection_id;
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::Respond(HttpServerTransaction* transaction) {
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int connection_id = transaction->connection_id();
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (Connection* connection = Find(connection_id)) {
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    connection->Respond(transaction);
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete transaction;
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // We may be tempted to SignalHttpComplete, but that implies that a
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // connection still exists.
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::Close(int connection_id, bool force) {
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (Connection* connection = Find(connection_id)) {
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    connection->InitiateClose(force);
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::CloseAll(bool force) {
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (connections_.empty()) {
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SignalCloseAllComplete(this);
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return;
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  closing_ = true;
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::list<Connection*> connections;
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (ConnectionMap::const_iterator it = connections_.begin();
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org       it != connections_.end(); ++it) {
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    connections.push_back(it->second);
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (std::list<Connection*>::const_iterator it = connections.begin();
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      it != connections.end(); ++it) {
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    (*it)->InitiateClose(force);
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::Connection*
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::Find(int connection_id) {
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectionMap::iterator it = connections_.find(connection_id);
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (it == connections_.end())
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return NULL;
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return it->second;
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::Remove(int connection_id) {
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectionMap::iterator it = connections_.find(connection_id);
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (it == connections_.end()) {
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(false);
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return;
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Connection* connection = it->second;
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  connections_.erase(it);
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SignalConnectionClosed(this, connection_id, connection->EndProcess());
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete connection;
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (closing_ && connections_.empty()) {
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    closing_ = false;
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SignalCloseAllComplete(this);
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// HttpServer::Connection
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::Connection::Connection(int connection_id, HttpServer* server)
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  : connection_id_(connection_id), server_(server),
12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    current_(NULL), signalling_(false), close_(false) {
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::Connection::~Connection() {
12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // It's possible that an object hosted inside this transaction signalled
12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // an event which caused the connection to close.
12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread::Current()->Dispose(current_);
12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid
13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::Connection::BeginProcess(StreamInterface* stream) {
13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  base_.notify(this);
13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  base_.attach(stream);
13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  current_ = new HttpServerTransaction(connection_id_);
13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (base_.mode() != HM_CONNECT)
13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    base_.recv(&current_->request);
13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamInterface*
14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::Connection::EndProcess() {
14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  base_.notify(NULL);
14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  base_.abort(HE_DISCONNECTED);
14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return base_.detach();
14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid
14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::Connection::Respond(HttpServerTransaction* transaction) {
14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(current_ == NULL);
15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  current_ = transaction;
15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (current_->response.begin() == current_->response.end()) {
15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    current_->response.set_error(HC_INTERNAL_SERVER_ERROR);
15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool keep_alive = HttpShouldKeepAlive(current_->request);
15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  current_->response.setHeader(HH_CONNECTION,
15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                               keep_alive ? "Keep-Alive" : "Close",
15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                               false);
15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  close_ = !HttpShouldKeepAlive(current_->response);
15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  base_.send(&current_->response);
16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid
16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::Connection::InitiateClose(bool force) {
16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool request_in_progress = (HM_SEND == base_.mode()) || (NULL == current_);
16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!signalling_ && (force || !request_in_progress)) {
16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    server_->Remove(connection_id_);
16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    close_ = true;
16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//
17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// IHttpNotify Implementation
17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//
17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpError
17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::Connection::onHttpHeaderComplete(bool chunked, size_t& data_size) {
17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (data_size == SIZE_UNKNOWN) {
17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    data_size = 0;
18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(current_ != NULL);
18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool custom_document = false;
18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  server_->SignalHttpRequestHeader(server_, current_, &custom_document);
18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!custom_document) {
18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    current_->request.document.reset(new MemoryStream);
18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return HE_NONE;
18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid
19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::Connection::onHttpComplete(HttpMode mode, HttpError err) {
19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (mode == HM_SEND) {
19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(current_ != NULL);
19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    signalling_ = true;
19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    server_->SignalHttpRequestComplete(server_, current_, err);
19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    signalling_ = false;
19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (close_) {
19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // Force a close
19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      err = HE_DISCONNECTED;
20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (err != HE_NONE) {
20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    server_->Remove(connection_id_);
20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (mode == HM_CONNECT) {
20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    base_.recv(&current_->request);
20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (mode == HM_RECV) {
20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(current_ != NULL);
20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // TODO: do we need this?
20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    //request_.document_->rewind();
21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    HttpServerTransaction* transaction = current_;
21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    current_ = NULL;
21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    server_->SignalHttpRequest(server_, transaction);
21347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (mode == HM_SEND) {
21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Thread::Current()->Dispose(current_->response.document.release());
21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    current_->request.clear(true);
21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    current_->response.clear(true);
21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    base_.recv(&current_->request);
21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(false);
22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid
22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpServer::Connection::onHttpClosed(HttpError err) {
2255199d1ddc1a2d8bb9feeadc5bc684f8a1fd6b76bhenrike@webrtc.org  RTC_UNUSED(err);
22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  server_->Remove(connection_id_);
22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// HttpListenServer
23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpListenServer::HttpListenServer() {
23447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SignalConnectionClosed.connect(this, &HttpListenServer::OnConnectionClosed);
23547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHttpListenServer::~HttpListenServer() {
23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint HttpListenServer::Listen(const SocketAddress& address) {
24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AsyncSocket* sock =
24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      Thread::Current()->socketserver()->CreateAsyncSocket(address.family(),
24347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                           SOCK_STREAM);
24447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!sock) {
24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return SOCKET_ERROR;
24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  listener_.reset(sock);
24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  listener_->SignalReadEvent.connect(this, &HttpListenServer::OnReadEvent);
24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if ((listener_->Bind(address) != SOCKET_ERROR) &&
25047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      (listener_->Listen(5) != SOCKET_ERROR))
25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return 0;
25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return listener_->GetError();
25347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool HttpListenServer::GetAddress(SocketAddress* address) const {
25647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!listener_) {
25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  *address = listener_->GetLocalAddress();
26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return !address->IsNil();
26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid HttpListenServer::StopListening() {
26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (listener_) {
26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    listener_->Close();
26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid HttpListenServer::OnReadEvent(AsyncSocket* socket) {
27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(socket == listener_.get());
27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(listener_);
27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AsyncSocket* incoming = listener_->Accept(NULL);
27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (incoming) {
27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    StreamInterface* stream = new SocketStream(incoming);
27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    //stream = new LoggingAdapter(stream, LS_VERBOSE, "HttpServer", false);
27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    HandleConnection(stream);
27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid HttpListenServer::OnConnectionClosed(HttpServer* server,
28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                          int connection_id,
28247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                          StreamInterface* stream) {
28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread::Current()->Dispose(stream);
28447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
28647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
289