• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/flip_server/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 
StreamerSM(SMConnection * connection,SMInterface * sm_other_interface,EpollServer * epoll_server,FlipAcceptor * acceptor)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 
~StreamerSM()34 StreamerSM::~StreamerSM() {
35   VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Destroying StreamerSM object";
36   Reset();
37   delete http_framer_;
38 }
39 
set_is_request()40 void StreamerSM::set_is_request() {
41   is_request_ = true;
42   http_framer_->set_is_request(true);
43 }
44 
InitSMInterface(SMInterface * sm_other_interface,int32 server_idx)45 void StreamerSM::InitSMInterface(SMInterface* sm_other_interface,
46                                  int32 server_idx) {
47   sm_other_interface_ = sm_other_interface;
48 }
49 
InitSMConnection(SMConnectionPoolInterface * connection_pool,SMInterface * sm_interface,EpollServer * epoll_server,int fd,std::string server_ip,std::string server_port,std::string remote_ip,bool use_ssl)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, sm_interface,
61                                 epoll_server, fd, server_ip,
62                                 server_port, remote_ip, use_ssl);
63 }
64 
ProcessReadInput(const char * data,size_t len)65 size_t StreamerSM::ProcessReadInput(const char* data, size_t len) {
66   // For now we only want to parse http requests. Just stream responses
67   if (is_request_) {
68     return http_framer_->ProcessInput(data, len);
69   } else {
70     return sm_other_interface_->ProcessWriteInput(data, len);
71   }
72 }
73 
ProcessWriteInput(const char * data,size_t len)74 size_t StreamerSM::ProcessWriteInput(const char* data, size_t len) {
75   char * dataPtr = new char[len];
76   memcpy(dataPtr, data, len);
77   DataFrame* df = new DataFrame;
78   df->data = (const char *)dataPtr;
79   df->size = len;
80   df->delete_when_done = true;
81   connection_->EnqueueDataFrame(df);
82   return len;
83 }
84 
Error() const85 bool StreamerSM::Error() const {
86   return false;
87 }
88 
ErrorAsString() const89 const char* StreamerSM::ErrorAsString() const {
90   return "(none)";
91 }
92 
MessageFullyRead() const93 bool StreamerSM::MessageFullyRead() const {
94   if (is_request_) {
95     return http_framer_->MessageFullyRead();
96   } else {
97     return false;
98   }
99 }
100 
Reset()101 void StreamerSM::Reset() {
102   VLOG(1) << ACCEPTOR_CLIENT_IDENT << "StreamerSM: Reset";
103   connection_->Cleanup("Server Reset");
104   http_framer_->Reset();
105 }
106 
ResetForNewConnection()107 void StreamerSM::ResetForNewConnection() {
108   http_framer_->Reset();
109   sm_other_interface_->Reset();
110 }
111 
Cleanup()112 void StreamerSM::Cleanup() {
113   if (is_request_)
114     http_framer_->Reset();
115 }
116 
PostAcceptHook()117 int StreamerSM::PostAcceptHook() {
118   if (!sm_other_interface_) {
119     SMConnection *server_connection =
120       SMConnection::NewSMConnection(epoll_server_, NULL, NULL,
121                                     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_ = new StreamerSM(server_connection, this,
129                                          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, sm_other_interface_,
135                                         epoll_server_, -1,
136                                         acceptor_->https_server_ip_,
137                                         acceptor_->https_server_port_,
138                                         "",
139                                         false);
140 
141   return 1;
142 }
143 
SendSynStream(uint32 stream_id,const BalsaHeaders & headers)144 size_t StreamerSM::SendSynStream(uint32 stream_id,
145                                  const BalsaHeaders& headers) {
146   return 0;
147 }
148 
SendSynReply(uint32 stream_id,const BalsaHeaders & headers)149 size_t StreamerSM::SendSynReply(uint32 stream_id, const BalsaHeaders& headers) {
150   return 0;
151 }
152 
ProcessBodyInput(const char * input,size_t size)153 void StreamerSM::ProcessBodyInput(const char *input, size_t size) {
154   VLOG(2) << ACCEPTOR_CLIENT_IDENT
155           << "StreamerHttpSM: Process Body Input Data: "
156           << "size " << size;
157   sm_other_interface_->ProcessWriteInput(input, size);
158 }
159 
MessageDone()160 void StreamerSM::MessageDone() {
161   if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) {
162     VLOG(2) << ACCEPTOR_CLIENT_IDENT << "StreamerHttpSM: MessageDone.";
163     // TODO(kelindsay): anything need to be done ehre?
164   } else {
165     VLOG(2) << ACCEPTOR_CLIENT_IDENT << "StraemerHttpSM: MessageDone.";
166   }
167 }
168 
ProcessHeaders(const BalsaHeaders & headers)169 void StreamerSM::ProcessHeaders(const BalsaHeaders& headers) {
170   VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpStreamerSM: Process Headers";
171   BalsaHeaders mod_headers;
172   mod_headers.CopyFrom(headers);
173   if (forward_ip_header_.length()) {
174     LOG(INFO) << "Adding forward header: " << forward_ip_header_;
175     mod_headers.ReplaceOrAppendHeader(forward_ip_header_,
176                                       connection_->client_ip());
177   } else {
178     LOG(INFO) << "NOT adding forward header.";
179   }
180   SimpleBuffer sb;
181   char* buffer;
182   int size;
183   mod_headers.WriteHeaderAndEndingToBuffer(&sb);
184   sb.GetReadablePtr(&buffer, &size);
185   sm_other_interface_->ProcessWriteInput(buffer, size);
186 }
187 
HandleHeaderError(BalsaFrame * framer)188 void StreamerSM::HandleHeaderError(BalsaFrame* framer) {
189   HandleError();
190 }
191 
HandleChunkingError(BalsaFrame * framer)192 void StreamerSM::HandleChunkingError(BalsaFrame* framer) {
193   HandleError();
194 }
195 
HandleBodyError(BalsaFrame * framer)196 void StreamerSM::HandleBodyError(BalsaFrame* framer) {
197   HandleError();
198 }
199 
HandleError()200 void StreamerSM::HandleError() {
201   VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Error detected";
202 }
203 
204 }  // namespace net
205 
206