/*
 * Copyright 2013 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "pagespeed/apache/apache_request_context.h"

#include "base/logging.h"
#include "pagespeed/apache/interface_mod_spdy.h"
#include "pagespeed/apache/mod_spdy_fetcher.h"
#include "net/instaweb/http/public/request_context.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/http/http_names.h"

#include "httpd.h"  // NOLINT

namespace net_instaweb {

ApacheRequestContext::ApacheRequestContext(
    AbstractMutex* logging_mutex, Timer* timer, request_rec* req)
    : SystemRequestContext(
          logging_mutex,
          timer,
          req->hostname,
          req->connection->local_addr->port,
          req->connection->local_ip),
      use_spdy_fetcher_(ModSpdyFetcher::ShouldUseOn(req)),
      spdy_connection_factory_(NULL) {
  // Note that at the time we create a RequestContext we have full
  // access to the Apache request_rec.  However, due to Cloning and (I
  // believe) Detaching, we can initiate fetches after the Apache
  // request_rec* has been retired.  So deep-copy the bits we need
  // from the request_rec at the time we create our RequestContext.
  // This includes the local port (for loopback fetches) and the
  // entire connection subobject, for backdoor mod_spdy fetches.  To
  // avoid temptation we do not keep a pointer to the request_rec.

  // Determines whether we should handle request as SPDY.
  // This happens in two cases:
  // 1) It's actually a SPDY request using mod_spdy
  // 2) The header X-PSA-Optimize-For-SPDY is present, with any value.
  if (mod_spdy_get_spdy_version(req->connection) != 0) {
    set_using_spdy(true);
  } else {
    const char* value = apr_table_get(req->headers_in,
                                      HttpAttributes::kXPsaOptimizeForSpdy);
    set_using_spdy(value != NULL);
  }
}

ApacheRequestContext::~ApacheRequestContext() {
  if (spdy_connection_factory_ != NULL) {
    mod_spdy_destroy_slave_connection_factory(spdy_connection_factory_);
  }
}

void ApacheRequestContext::SetupSpdyConnectionIfNeeded(request_rec* req) {
  // Independent of whether we are serving a SPDY request, we will want
  // to be able to do back door mod_spdy fetches if configured to do so.
  if (use_spdy_fetcher_) {
    // TODO(jmarantz): mdsteele indicates this is not overly expensive to
    // do per-request.  Verify this with profiling.
    spdy_connection_factory_ =
        mod_spdy_create_slave_connection_factory(req->connection);
  }
}

ApacheRequestContext* ApacheRequestContext::DynamicCast(RequestContext* rc) {
  if (rc == NULL) {
    return NULL;
  }
  ApacheRequestContext* out = dynamic_cast<ApacheRequestContext*>(rc);
  DCHECK(out != NULL) << "Invalid request conversion. Do not rely on RTTI for "
                      << "functional behavior. Apache handling flows must use "
                      << "ApacheRequestContexts.";
  return out;
}

}  // namespace net_instaweb
