Home | History | Annotate | Download | only in flip_server
      1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/tools/flip_server/streamer_interface.h"
      6 
      7 #include <string>
      8 
      9 #include "net/tools/balsa/balsa_frame.h"
     10 #include "net/tools/flip_server/constants.h"
     11 #include "net/tools/flip_server/flip_config.h"
     12 #include "net/tools/flip_server/sm_connection.h"
     13 
     14 namespace net {
     15 
     16 std::string StreamerSM::forward_ip_header_;
     17 
     18 StreamerSM::StreamerSM(SMConnection* connection,
     19                        SMInterface* sm_other_interface,
     20                        EpollServer* epoll_server,
     21                        FlipAcceptor* acceptor)
     22     : connection_(connection),
     23       sm_other_interface_(sm_other_interface),
     24       epoll_server_(epoll_server),
     25       acceptor_(acceptor),
     26       is_request_(false),
     27       http_framer_(new BalsaFrame) {
     28   VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Creating StreamerSM object";
     29   http_framer_->set_balsa_visitor(this);
     30   http_framer_->set_balsa_headers(&headers_);
     31   http_framer_->set_is_request(false);
     32 }
     33 
     34 StreamerSM::~StreamerSM() {
     35   VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Destroying StreamerSM object";
     36   Reset();
     37   delete http_framer_;
     38 }
     39 
     40 void StreamerSM::set_is_request() {
     41   is_request_ = true;
     42   http_framer_->set_is_request(true);
     43 }
     44 
     45 void StreamerSM::InitSMInterface(SMInterface* sm_other_interface,
     46                                  int32 server_idx) {
     47   sm_other_interface_ = sm_other_interface;
     48 }
     49 
     50 void StreamerSM::InitSMConnection(SMConnectionPoolInterface* connection_pool,
     51                                   SMInterface* sm_interface,
     52                                   EpollServer* epoll_server,
     53                                   int fd,
     54                                   std::string server_ip,
     55                                   std::string server_port,
     56                                   std::string remote_ip,
     57                                   bool use_ssl) {
     58   VLOG(2) << ACCEPTOR_CLIENT_IDENT << "StreamerSM: Initializing server "
     59           << "connection.";
     60   connection_->InitSMConnection(connection_pool,
     61                                 sm_interface,
     62                                 epoll_server,
     63                                 fd,
     64                                 server_ip,
     65                                 server_port,
     66                                 remote_ip,
     67                                 use_ssl);
     68 }
     69 
     70 size_t StreamerSM::ProcessReadInput(const char* data, size_t len) {
     71   // For now we only want to parse http requests. Just stream responses
     72   if (is_request_) {
     73     return http_framer_->ProcessInput(data, len);
     74   } else {
     75     return sm_other_interface_->ProcessWriteInput(data, len);
     76   }
     77 }
     78 
     79 size_t StreamerSM::ProcessWriteInput(const char* data, size_t len) {
     80   char* dataPtr = new char[len];
     81   memcpy(dataPtr, data, len);
     82   DataFrame* df = new DataFrame;
     83   df->data = (const char*)dataPtr;
     84   df->size = len;
     85   df->delete_when_done = true;
     86   connection_->EnqueueDataFrame(df);
     87   return len;
     88 }
     89 
     90 bool StreamerSM::Error() const { return false; }
     91 
     92 const char* StreamerSM::ErrorAsString() const { return "(none)"; }
     93 
     94 bool StreamerSM::MessageFullyRead() const {
     95   if (is_request_) {
     96     return http_framer_->MessageFullyRead();
     97   } else {
     98     return false;
     99   }
    100 }
    101 
    102 void StreamerSM::Reset() {
    103   VLOG(1) << ACCEPTOR_CLIENT_IDENT << "StreamerSM: Reset";
    104   connection_->Cleanup("Server Reset");
    105   http_framer_->Reset();
    106 }
    107 
    108 void StreamerSM::ResetForNewConnection() {
    109   http_framer_->Reset();
    110   sm_other_interface_->Reset();
    111 }
    112 
    113 void StreamerSM::Cleanup() {
    114   if (is_request_)
    115     http_framer_->Reset();
    116 }
    117 
    118 int StreamerSM::PostAcceptHook() {
    119   if (!sm_other_interface_) {
    120     SMConnection* server_connection = SMConnection::NewSMConnection(
    121         epoll_server_, NULL, NULL, acceptor_, "server_conn: ");
    122     if (server_connection == NULL) {
    123       LOG(ERROR) << "StreamerSM: Could not create server conenction.";
    124       return 0;
    125     }
    126     VLOG(2) << ACCEPTOR_CLIENT_IDENT << "StreamerSM: Creating new server "
    127             << "connection.";
    128     sm_other_interface_ =
    129         new StreamerSM(server_connection, this, epoll_server_, acceptor_);
    130     sm_other_interface_->InitSMInterface(this, 0);
    131   }
    132   // The Streamer interface is used to stream HTTPS connections, so we
    133   // will always use the https_server_ip/port here.
    134   sm_other_interface_->InitSMConnection(NULL,
    135                                         sm_other_interface_,
    136                                         epoll_server_,
    137                                         -1,
    138                                         acceptor_->https_server_ip_,
    139                                         acceptor_->https_server_port_,
    140                                         std::string(),
    141                                         false);
    142 
    143   return 1;
    144 }
    145 
    146 size_t StreamerSM::SendSynStream(uint32 stream_id,
    147                                  const BalsaHeaders& headers) {
    148   return 0;
    149 }
    150 
    151 size_t StreamerSM::SendSynReply(uint32 stream_id, const BalsaHeaders& headers) {
    152   return 0;
    153 }
    154 
    155 void StreamerSM::ProcessBodyInput(const char* input, size_t size) {
    156   VLOG(2) << ACCEPTOR_CLIENT_IDENT
    157           << "StreamerHttpSM: Process Body Input Data: "
    158           << "size " << size;
    159   sm_other_interface_->ProcessWriteInput(input, size);
    160 }
    161 
    162 void StreamerSM::MessageDone() {
    163   if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) {
    164     VLOG(2) << ACCEPTOR_CLIENT_IDENT << "StreamerHttpSM: MessageDone.";
    165     // TODO(kelindsay): anything need to be done ehre?
    166   } else {
    167     VLOG(2) << ACCEPTOR_CLIENT_IDENT << "StraemerHttpSM: MessageDone.";
    168   }
    169 }
    170 
    171 void StreamerSM::ProcessHeaders(const BalsaHeaders& headers) {
    172   VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpStreamerSM: Process Headers";
    173   BalsaHeaders mod_headers;
    174   mod_headers.CopyFrom(headers);
    175   if (forward_ip_header_.length()) {
    176     LOG(INFO) << "Adding forward header: " << forward_ip_header_;
    177     mod_headers.ReplaceOrAppendHeader(forward_ip_header_,
    178                                       connection_->client_ip());
    179   } else {
    180     LOG(INFO) << "NOT adding forward header.";
    181   }
    182   SimpleBuffer sb;
    183   char* buffer;
    184   int size;
    185   mod_headers.WriteHeaderAndEndingToBuffer(&sb);
    186   sb.GetReadablePtr(&buffer, &size);
    187   sm_other_interface_->ProcessWriteInput(buffer, size);
    188 }
    189 
    190 void StreamerSM::HandleHeaderError(BalsaFrame* framer) { HandleError(); }
    191 
    192 void StreamerSM::HandleChunkingError(BalsaFrame* framer) { HandleError(); }
    193 
    194 void StreamerSM::HandleBodyError(BalsaFrame* framer) { HandleError(); }
    195 
    196 void StreamerSM::HandleError() {
    197   VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Error detected";
    198 }
    199 
    200 }  // namespace net
    201