1/* 2 * Copyright 2006 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include "webrtc/base/httprequest.h" 12 13#include "webrtc/base/common.h" 14#include "webrtc/base/firewallsocketserver.h" 15#include "webrtc/base/httpclient.h" 16#include "webrtc/base/logging.h" 17#include "webrtc/base/physicalsocketserver.h" 18#include "webrtc/base/socketadapters.h" 19#include "webrtc/base/socketpool.h" 20#include "webrtc/base/ssladapter.h" 21 22using namespace rtc; 23 24/////////////////////////////////////////////////////////////////////////////// 25// HttpMonitor 26/////////////////////////////////////////////////////////////////////////////// 27 28HttpMonitor::HttpMonitor(SocketServer *ss) { 29 ASSERT(Thread::Current() != NULL); 30 ss_ = ss; 31 reset(); 32} 33 34void HttpMonitor::Connect(HttpClient *http) { 35 http->SignalHttpClientComplete.connect(this, 36 &HttpMonitor::OnHttpClientComplete); 37} 38 39void HttpMonitor::OnHttpClientComplete(HttpClient * http, HttpErrorType error) { 40 complete_ = true; 41 error_ = error; 42 ss_->WakeUp(); 43} 44 45/////////////////////////////////////////////////////////////////////////////// 46// HttpRequest 47/////////////////////////////////////////////////////////////////////////////// 48 49const int kDefaultHTTPTimeout = 30 * 1000; // 30 sec 50 51HttpRequest::HttpRequest(const std::string& user_agent) 52 : firewall_(0), 53 port_(80), 54 secure_(false), 55 timeout_(kDefaultHTTPTimeout), 56 client_(user_agent.c_str(), NULL), 57 error_(HE_NONE) {} 58 59HttpRequest::~HttpRequest() = default; 60 61void HttpRequest::Send() { 62 // TODO: Rewrite this to use the thread's native socket server, and a more 63 // natural flow? 64 65 PhysicalSocketServer physical; 66 SocketServer * ss = &physical; 67 if (firewall_) { 68 ss = new FirewallSocketServer(ss, firewall_); 69 } 70 71 SslSocketFactory factory(ss, client_.agent()); 72 factory.SetProxy(proxy_); 73 if (secure_) 74 factory.UseSSL(host_.c_str()); 75 76 //factory.SetLogging("HttpRequest"); 77 78 ReuseSocketPool pool(&factory); 79 client_.set_pool(&pool); 80 81 bool transparent_proxy = (port_ == 80) && ((proxy_.type == PROXY_HTTPS) || 82 (proxy_.type == PROXY_UNKNOWN)); 83 84 if (transparent_proxy) { 85 client_.set_proxy(proxy_); 86 } 87 client_.set_redirect_action(HttpClient::REDIRECT_ALWAYS); 88 89 SocketAddress server(host_, port_); 90 client_.set_server(server); 91 92 LOG(LS_INFO) << "HttpRequest start: " << host_ + client_.request().path; 93 94 HttpMonitor monitor(ss); 95 monitor.Connect(&client_); 96 client_.start(); 97 ss->Wait(timeout_, true); 98 if (!monitor.done()) { 99 LOG(LS_INFO) << "HttpRequest request timed out"; 100 client_.reset(); 101 return; 102 } 103 104 set_error(monitor.error()); 105 if (error_) { 106 LOG(LS_INFO) << "HttpRequest request error: " << error_; 107 return; 108 } 109 110 std::string value; 111 if (client_.response().hasHeader(HH_LOCATION, &value)) { 112 response_redirect_ = value.c_str(); 113 } 114} 115