• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
13 namespace rtc {
14 
15 enum {
16   MSG_TIMEOUT = SignalThread::ST_MSG_FIRST_AVAILABLE,
17   MSG_LAUNCH_REQUEST
18 };
19 static const int kDefaultHTTPTimeout = 30 * 1000;  // 30 sec
20 
21 ///////////////////////////////////////////////////////////////////////////////
22 // AsyncHttpRequest
23 ///////////////////////////////////////////////////////////////////////////////
24 
AsyncHttpRequest(const std::string & user_agent)25 AsyncHttpRequest::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 
~AsyncHttpRequest()40 AsyncHttpRequest::~AsyncHttpRequest() {
41 }
42 
OnWorkStart()43 void AsyncHttpRequest::OnWorkStart() {
44   if (start_delay_ <= 0) {
45     LaunchRequest();
46   } else {
47     Thread::Current()->PostDelayed(start_delay_, this, MSG_LAUNCH_REQUEST);
48   }
49 }
50 
OnWorkStop()51 void AsyncHttpRequest::OnWorkStop() {
52   // worker is already quitting, no need to explicitly quit
53   LOG(LS_INFO) << "HttpRequest cancelled";
54 }
55 
OnComplete(HttpClient * client,HttpErrorType error)56 void 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 
OnMessage(Message * message)74 void 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 
DoWork()90 void 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 
LaunchRequest()97 void 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