// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/http/http_stream_factory_impl.h"

#include "base/string_number_conversions.h"
#include "base/stl_util.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_log.h"
#include "net/base/net_util.h"
#include "net/http/http_network_session.h"
#include "net/http/http_pipelined_connection.h"
#include "net/http/http_pipelined_host.h"
#include "net/http/http_pipelined_stream.h"
#include "net/http/http_server_properties.h"
#include "net/http/http_stream_factory_impl_job.h"
#include "net/http/http_stream_factory_impl_request.h"
#include "net/spdy/spdy_http_stream.h"

namespace net {

namespace {

GURL UpgradeUrlToHttps(const GURL& original_url, int port) {
  GURL::Replacements replacements;
  // new_sheme and new_port need to be in scope here because GURL::Replacements
  // references the memory contained by them directly.
  const std::string new_scheme = "https";
  const std::string new_port = base::IntToString(port);
  replacements.SetSchemeStr(new_scheme);
  replacements.SetPortStr(new_port);
  return original_url.ReplaceComponents(replacements);
}

}  // namespace

HttpStreamFactoryImpl::HttpStreamFactoryImpl(HttpNetworkSession* session)
    : session_(session)
#if !defined(COBALT_DISABLE_SPDY)
      ,
      http_pipelined_host_pool_(this,
                                NULL,
                                session_->http_server_properties(),
                                session_->force_http_pipelining())
#endif  // !defined(COBALT_DISABLE_SPDY)
{
}

HttpStreamFactoryImpl::~HttpStreamFactoryImpl() {
  DCHECK(request_map_.empty());
#if !defined(COBALT_DISABLE_SPDY)
  DCHECK(spdy_session_request_map_.empty());
  DCHECK(http_pipelining_request_map_.empty());
#endif  // !defined(COBALT_DISABLE_SPDY)

  std::set<const Job*> tmp_job_set;
  tmp_job_set.swap(orphaned_job_set_);
  STLDeleteContainerPointers(tmp_job_set.begin(), tmp_job_set.end());
  DCHECK(orphaned_job_set_.empty());

  tmp_job_set.clear();
  tmp_job_set.swap(preconnect_job_set_);
  STLDeleteContainerPointers(tmp_job_set.begin(), tmp_job_set.end());
  DCHECK(preconnect_job_set_.empty());
}

HttpStreamRequest* HttpStreamFactoryImpl::RequestStream(
    const HttpRequestInfo& request_info,
    const SSLConfig& server_ssl_config,
    const SSLConfig& proxy_ssl_config,
    HttpStreamRequest::Delegate* delegate,
    const BoundNetLog& net_log) {
  Request* request = new Request(request_info.url, this, delegate, net_log);

  GURL alternate_url;
  bool has_alternate_protocol =
      GetAlternateProtocolRequestFor(request_info.url, &alternate_url);
  Job* alternate_job = NULL;
  if (has_alternate_protocol) {
    HttpRequestInfo alternate_request_info = request_info;
    alternate_request_info.url = alternate_url;
    alternate_job =
        new Job(this, session_, alternate_request_info, server_ssl_config,
                proxy_ssl_config, net_log.net_log());
    request->AttachJob(alternate_job);
    alternate_job->MarkAsAlternate(request_info.url);
  }

  Job* job = new Job(this, session_, request_info, server_ssl_config,
                     proxy_ssl_config, net_log.net_log());
  request->AttachJob(job);
  if (alternate_job) {
    job->WaitFor(alternate_job);
    // Make sure to wait until we call WaitFor(), before starting
    // |alternate_job|, otherwise |alternate_job| will not notify |job|
    // appropriately.
    alternate_job->Start(request);
  }
  // Even if |alternate_job| has already finished, it won't have notified the
  // request yet, since we defer that to the next iteration of the MessageLoop,
  // so starting |job| is always safe.
  job->Start(request);
  return request;
}

void HttpStreamFactoryImpl::PreconnectStreams(
    int num_streams,
    const HttpRequestInfo& request_info,
    const SSLConfig& server_ssl_config,
    const SSLConfig& proxy_ssl_config) {
  GURL alternate_url;
  bool has_alternate_protocol =
      GetAlternateProtocolRequestFor(request_info.url, &alternate_url);
  Job* job = NULL;
  if (has_alternate_protocol) {
    HttpRequestInfo alternate_request_info = request_info;
    alternate_request_info.url = alternate_url;
    job = new Job(this, session_, alternate_request_info, server_ssl_config,
                  proxy_ssl_config, session_->net_log());
    job->MarkAsAlternate(request_info.url);
  } else {
    job = new Job(this, session_, request_info, server_ssl_config,
                  proxy_ssl_config, session_->net_log());
  }
  preconnect_job_set_.insert(job);
  job->Preconnect(num_streams);
}

base::Value* HttpStreamFactoryImpl::PipelineInfoToValue() const {
#if defined(COBALT_DISABLE_SPDY)
  return NULL;
#else
  return http_pipelined_host_pool_.PipelineInfoToValue();
#endif  // defined(COBALT_DISABLE_SPDY)
}

const HostMappingRules* HttpStreamFactoryImpl::GetHostMappingRules() const {
  return session_->params().host_mapping_rules;
}

bool HttpStreamFactoryImpl::GetAlternateProtocolRequestFor(
    const GURL& original_url,
    GURL* alternate_url) const {
  if (!spdy_enabled())
    return false;

  if (!use_alternate_protocols())
    return false;

  HostPortPair origin = HostPortPair(original_url.HostNoBrackets(),
                                     original_url.EffectiveIntPort());

  const HttpServerProperties& http_server_properties =
      *session_->http_server_properties();
  if (!http_server_properties.HasAlternateProtocol(origin))
    return false;

  PortAlternateProtocolPair alternate =
      http_server_properties.GetAlternateProtocol(origin);
  if (alternate.protocol == ALTERNATE_PROTOCOL_BROKEN)
    return false;

  DCHECK_LE(NPN_SPDY_1, alternate.protocol);
  DCHECK_GT(NUM_ALTERNATE_PROTOCOLS, alternate.protocol);

  if (alternate.protocol < NPN_SPDY_2)
    return false;

  // Some shared unix systems may have user home directories (like
  // http://foo.com/~mike) which allow users to emit headers.  This is a bad
  // idea already, but with Alternate-Protocol, it provides the ability for a
  // single user on a multi-user system to hijack the alternate protocol.
  // These systems also enforce ports <1024 as restricted ports.  So don't
  // allow protocol upgrades to user-controllable ports.
  const int kUnrestrictedPort = 1024;
  if (alternate.port >= kUnrestrictedPort && origin.port() < kUnrestrictedPort)
    return false;

  origin.set_port(alternate.port);
  if (HttpStreamFactory::HasSpdyExclusion(origin))
    return false;

  *alternate_url = UpgradeUrlToHttps(original_url, alternate.port);
  return true;
}

void HttpStreamFactoryImpl::OrphanJob(Job* job, const Request* request) {
  DCHECK(ContainsKey(request_map_, job));
  DCHECK_EQ(request_map_[job], request);
  DCHECK(!ContainsKey(orphaned_job_set_, job));

  request_map_.erase(job);

  orphaned_job_set_.insert(job);
  job->Orphan(request);
}

void HttpStreamFactoryImpl::OnSpdySessionReady(
    scoped_refptr<SpdySession> spdy_session,
    bool direct,
    const SSLConfig& used_ssl_config,
    const ProxyInfo& used_proxy_info,
    bool was_npn_negotiated,
    NextProto protocol_negotiated,
    bool using_spdy,
    const BoundNetLog& net_log) {
#if !defined(COBALT_DISABLE_SPDY)
  const HostPortProxyPair& spdy_session_key =
      spdy_session->host_port_proxy_pair();
  while (!spdy_session->IsClosed()) {
    // Each iteration may empty out the RequestSet for |spdy_session_key_ in
    // |spdy_session_request_map_|. So each time, check for RequestSet and use
    // the first one.
    //
    // TODO(willchan): If it's important, switch RequestSet out for a FIFO
    // pqueue (Order by priority first, then FIFO within same priority). Unclear
    // that it matters here.
    if (!ContainsKey(spdy_session_request_map_, spdy_session_key))
      break;
    Request* request = *spdy_session_request_map_[spdy_session_key].begin();
    request->Complete(was_npn_negotiated,
                      protocol_negotiated,
                      using_spdy,
                      net_log);
    bool use_relative_url = direct || request->url().SchemeIs("https");
    request->OnStreamReady(NULL, used_ssl_config, used_proxy_info,
                           new SpdyHttpStream(spdy_session, use_relative_url));
  }
  // TODO(mbelshe): Alert other valid requests.
#endif  // !defined(COBALT_DISABLE_SPDY)
}

void HttpStreamFactoryImpl::OnOrphanedJobComplete(const Job* job) {
  orphaned_job_set_.erase(job);
  delete job;
}

void HttpStreamFactoryImpl::OnPreconnectsComplete(const Job* job) {
  preconnect_job_set_.erase(job);
  delete job;
  OnPreconnectsCompleteInternal();
}

void HttpStreamFactoryImpl::OnHttpPipelinedHostHasAdditionalCapacity(
    HttpPipelinedHost* host) {
#if defined(COBALT_DISABLE_SPDY)
  NOTREACHED();
#else
  while (ContainsKey(http_pipelining_request_map_, host->GetKey())) {
    HttpPipelinedStream* stream =
        http_pipelined_host_pool_.CreateStreamOnExistingPipeline(
            host->GetKey());
    if (!stream) {
      break;
    }

    Request* request = *http_pipelining_request_map_[host->GetKey()].begin();
    request->Complete(stream->was_npn_negotiated(),
                      stream->protocol_negotiated(),
                      false,  // not using_spdy
                      stream->net_log());
    request->OnStreamReady(NULL,
                           stream->used_ssl_config(),
                           stream->used_proxy_info(),
                           stream);
  }
#endif  // !defined(COBALT_DISABLE_SPDY)
}

void HttpStreamFactoryImpl::AbortPipelinedRequestsWithKey(
    const Job* job, const HttpPipelinedHost::Key& key, int status,
    const SSLConfig& used_ssl_config) {
#if !defined(COBALT_DISABLE_SPDY)
  RequestVector requests_to_fail = http_pipelining_request_map_[key];
  for (RequestVector::const_iterator it = requests_to_fail.begin();
       it != requests_to_fail.end(); ++it) {
    Request* request = *it;
    if (request == request_map_[job]) {
      continue;
    }
    request->OnStreamFailed(NULL, status, used_ssl_config);
  }
#endif  // !defined(COBALT_DISABLE_SPDY)
}

}  // namespace net
