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