// Copyright 2014 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/quic/quic_spdy_server_stream.h"

#include "base/memory/singleton.h"
#include "base/strings/string_number_conversions.h"
#include "net/quic/quic_in_memory_cache.h"
#include "net/quic/quic_session.h"
#include "net/quic/spdy_utils.h"
#include "net/spdy/spdy_framer.h"
#include "net/spdy/spdy_header_block.h"
#include "net/spdy/spdy_http_utils.h"

using base::StringPiece;
using std::string;

namespace net {

static const size_t kHeaderBufInitialSize = 4096;

QuicSpdyServerStream::QuicSpdyServerStream(QuicStreamId id,
                                           QuicSession* session)
    : QuicDataStream(id, session),
      read_buf_(new GrowableIOBuffer()),
      request_headers_received_(false) {
  read_buf_->SetCapacity(kHeaderBufInitialSize);
}

QuicSpdyServerStream::~QuicSpdyServerStream() {
}

uint32 QuicSpdyServerStream::ProcessData(const char* data, uint32 data_len) {
  if (data_len > INT_MAX) {
    LOG(DFATAL) << "Data length too long: " << data_len;
    return 0;
  }
  // Are we still reading the request headers.
  if (!request_headers_received_) {
    // Grow the read buffer if necessary.
    while (read_buf_->RemainingCapacity() < static_cast<int>(data_len)) {
      read_buf_->SetCapacity(read_buf_->capacity() * 2);
    }
    memcpy(read_buf_->data(), data, data_len);
    read_buf_->set_offset(read_buf_->offset() + data_len);
    // Try parsing the request headers. This will set request_headers_received_
    // if successful; if not, it will be tried again with more data.
    ParseRequestHeaders();
  } else {
    body_.append(data, data_len);
  }
  return data_len;
}

void QuicSpdyServerStream::OnFinRead() {
  ReliableQuicStream::OnFinRead();
  if (write_side_closed() || fin_buffered()) {
    return;
  }

  if (!request_headers_received_) {
    SendErrorResponse();  // We're not done reading headers.
    return;
  }

  SpdyHeaderBlock::const_iterator it = headers_.find("content-length");
  size_t content_length;
  if (it != headers_.end() &&
      (!base::StringToSizeT(it->second, &content_length) ||
       body_.size() != content_length)) {
    SendErrorResponse();  // Invalid content length
    return;
  }

  SendResponse();
}

// Try parsing the request headers. If successful, sets
// request_headers_received_. If not successful, it can just be tried again once
// there's more data.
void QuicSpdyServerStream::ParseRequestHeaders() {
  SpdyFramer framer((kDefaultSpdyMajorVersion));
  const char* data = read_buf_->StartOfBuffer();
  size_t read_buf_len = static_cast<size_t>(read_buf_->offset());
  size_t len = framer.ParseHeaderBlockInBuffer(data, read_buf_len, &headers_);
  if (len == 0) {
    // Not enough data yet, presumably. (If we still don't succeed by the end of
    // the stream, then we'll error in OnFinRead().)
    return;
  }

  // Headers received and parsed: extract the request URL.
  request_url_ = GetUrlFromHeaderBlock(headers_,
                                       kDefaultSpdyMajorVersion,
                                       false);
  if (!request_url_.is_valid()) {
    SendErrorResponse();
    return;
  }

  // Add any data past the headers to the request body.
  size_t delta = read_buf_len - len;
  if (delta > 0) {
    body_.append(data + len, delta);
  }

  request_headers_received_ = true;
}

void QuicSpdyServerStream::SendResponse() {
  // Find response in cache. If not found, send error response.
  const QuicInMemoryCache::Response* response =
      QuicInMemoryCache::GetInstance()->GetResponse(request_url_);
  if (response == nullptr) {
    SendErrorResponse();
    return;
  }

  if (response->response_type() == QuicInMemoryCache::CLOSE_CONNECTION) {
    DVLOG(1) << "Special response: closing connection.";
    CloseConnection(QUIC_NO_ERROR);
    return;
  }

  if (response->response_type() == QuicInMemoryCache::IGNORE_REQUEST) {
    DVLOG(1) << "Special response: ignoring request.";
    return;
  }

  DVLOG(1) << "Sending response for stream " << id();
  SendHeadersAndBody(response->headers(), response->body());
}

void QuicSpdyServerStream::SendErrorResponse() {
  DVLOG(1) << "Sending error response for stream " << id();
  scoped_refptr<HttpResponseHeaders> headers
      = new HttpResponseHeaders(string("HTTP/1.1 500 Server Error") + '\0' +
                                "content-length: 3" + '\0' + '\0');
  SendHeadersAndBody(*headers.get(), "bad");
}

void QuicSpdyServerStream::SendHeadersAndBody(
    const HttpResponseHeaders& response_headers,
    StringPiece body) {
  // We only support SPDY and HTTP, and neither handles bidirectional streaming.
  if (!read_side_closed()) {
    CloseReadSide();
  }

  SpdyHeaderBlock header_block;
  CreateSpdyHeadersFromHttpResponse(response_headers,
                                    kDefaultSpdyMajorVersion,
                                    &header_block);

  WriteHeaders(header_block, body.empty(), nullptr);

  if (!body.empty()) {
    WriteOrBufferData(body, true, nullptr);
  }
}

}  // namespace net
