// 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.
//
// Author: jmarantz@google.com (Joshua Marantz)

#include "base/logging.h"
#include "pagespeed/apache/apache_writer.h"
#include "pagespeed/apache/header_util.h"
#include "net/instaweb/http/public/async_fetch.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/http/http_names.h"
#include "pagespeed/kernel/http/response_headers.h"

#include "apr_strings.h"  // for apr_pstrdup    // NOLINT
#include "http_protocol.h"                      // NOLINT

namespace net_instaweb {

ApacheWriter::ApacheWriter(request_rec* r, ThreadSystem* thread_system)
    : request_(r),
      headers_out_(false),
      disable_downstream_header_filters_(false),
      strip_cookies_(false),
      content_length_(AsyncFetch::kContentLengthUnknown),
      thread_system_(thread_system) {
  apache_request_thread_.reset(thread_system->GetThreadId());
}

ApacheWriter::~ApacheWriter() {
}

bool ApacheWriter::Write(const StringPiece& str, MessageHandler* handler) {
  DCHECK(apache_request_thread_->IsCurrentThread());
  DCHECK(headers_out_);
  ap_rwrite(str.data(), str.size(), request_);
  return true;
}

bool ApacheWriter::Flush(MessageHandler* handler) {
  DCHECK(apache_request_thread_->IsCurrentThread());
  DCHECK(headers_out_);
  ap_rflush(request_);
  return true;
}

void ApacheWriter::OutputHeaders(ResponseHeaders* response_headers) {
  DCHECK(apache_request_thread_->IsCurrentThread());
  DCHECK(!headers_out_);
  if (headers_out_) {
    return;
  }
  headers_out_ = true;

  // Apache2 defaults to set the status line as HTTP/1.1.  If the
  // original content was HTTP/1.0, we need to force the server to use
  // HTTP/1.0.  I'm not sure why/whether we need to do this; it was in
  // mod_static from the sdpy project, which is where I copied this
  // code from.
  if ((response_headers->major_version() == 1) &&
      (response_headers->minor_version() == 0)) {
    apr_table_set(request_->subprocess_env, "force-response-1.0", "1");
  }

  const char* content_type = response_headers->Lookup1(
      HttpAttributes::kContentType);

  // It doesn't matter how the origin transferred the request to us;
  // Apache will fill this data in when it issues the response.
  response_headers->RemoveAll(HttpAttributes::kTransferEncoding);
  response_headers->RemoveAll(HttpAttributes::kContentLength);
  if (content_length_ != AsyncFetch::kContentLengthUnknown) {
    ap_set_content_length(request_, content_length_);
  }
  ResponseHeadersToApacheRequest(*response_headers, request_);
  request_->status = response_headers->status_code();
  if (disable_downstream_header_filters_) {
    DisableDownstreamHeaderFilters(request_);
  }

  // TODO(jefftk): Sanitize strips cookies and a lot of other headers.  It's
  // being run after ResponseHeadersToApacheRequest(), however, which means it's
  // not actually doing anything.  This code is not doing what it says it does,
  // and should be fixed, but it's possible some users like the mobilizing proxy
  // are depending on the current behavior.
  if (strip_cookies_ && response_headers->Sanitize()) {
    response_headers->ComputeCaching();
  }

  if (content_type != NULL) {
    // ap_set_content_type does not make a copy of the string, we need
    // to duplicate it.  Note that we will update the content type below,
    // after transforming the headers.
    ap_set_content_type(request_, apr_pstrdup(request_->pool, content_type));
  }

  // We don't set the content-length here, because we don't know it yet.
}

}  // namespace net_instaweb
