1/* 2 * Copyright 2004 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/asynchttprequest.h" 12 13namespace rtc { 14 15enum { 16 MSG_TIMEOUT = SignalThread::ST_MSG_FIRST_AVAILABLE, 17 MSG_LAUNCH_REQUEST 18}; 19static const int kDefaultHTTPTimeout = 30 * 1000; // 30 sec 20 21/////////////////////////////////////////////////////////////////////////////// 22// AsyncHttpRequest 23/////////////////////////////////////////////////////////////////////////////// 24 25AsyncHttpRequest::AsyncHttpRequest(const std::string &user_agent) 26 : start_delay_(0), 27 firewall_(NULL), 28 port_(80), 29 secure_(false), 30 timeout_(kDefaultHTTPTimeout), 31 fail_redirect_(false), 32 factory_(Thread::Current()->socketserver(), user_agent), 33 pool_(&factory_), 34 client_(user_agent.c_str(), &pool_), 35 error_(HE_NONE) { 36 client_.SignalHttpClientComplete.connect(this, 37 &AsyncHttpRequest::OnComplete); 38} 39 40AsyncHttpRequest::~AsyncHttpRequest() { 41} 42 43void AsyncHttpRequest::OnWorkStart() { 44 if (start_delay_ <= 0) { 45 LaunchRequest(); 46 } else { 47 Thread::Current()->PostDelayed(start_delay_, this, MSG_LAUNCH_REQUEST); 48 } 49} 50 51void AsyncHttpRequest::OnWorkStop() { 52 // worker is already quitting, no need to explicitly quit 53 LOG(LS_INFO) << "HttpRequest cancelled"; 54} 55 56void AsyncHttpRequest::OnComplete(HttpClient* client, HttpErrorType error) { 57 Thread::Current()->Clear(this, MSG_TIMEOUT); 58 59 set_error(error); 60 if (!error) { 61 LOG(LS_INFO) << "HttpRequest completed successfully"; 62 63 std::string value; 64 if (client_.response().hasHeader(HH_LOCATION, &value)) { 65 response_redirect_ = value.c_str(); 66 } 67 } else { 68 LOG(LS_INFO) << "HttpRequest completed with error: " << error; 69 } 70 71 worker()->Quit(); 72} 73 74void AsyncHttpRequest::OnMessage(Message* message) { 75 switch (message->message_id) { 76 case MSG_TIMEOUT: 77 LOG(LS_INFO) << "HttpRequest timed out"; 78 client_.reset(); 79 worker()->Quit(); 80 break; 81 case MSG_LAUNCH_REQUEST: 82 LaunchRequest(); 83 break; 84 default: 85 SignalThread::OnMessage(message); 86 break; 87 } 88} 89 90void AsyncHttpRequest::DoWork() { 91 // Do nothing while we wait for the request to finish. We only do this so 92 // that we can be a SignalThread; in the future this class should not be 93 // a SignalThread, since it does not need to spawn a new thread. 94 Thread::Current()->ProcessMessages(kForever); 95} 96 97void AsyncHttpRequest::LaunchRequest() { 98 factory_.SetProxy(proxy_); 99 if (secure_) 100 factory_.UseSSL(host_.c_str()); 101 102 bool transparent_proxy = (port_ == 80) && 103 ((proxy_.type == PROXY_HTTPS) || (proxy_.type == PROXY_UNKNOWN)); 104 if (transparent_proxy) { 105 client_.set_proxy(proxy_); 106 } 107 client_.set_fail_redirect(fail_redirect_); 108 client_.set_server(SocketAddress(host_, port_)); 109 110 LOG(LS_INFO) << "HttpRequest start: " << host_ + client_.request().path; 111 112 Thread::Current()->PostDelayed(timeout_, this, MSG_TIMEOUT); 113 client_.start(); 114} 115 116} // namespace rtc 117