blob: 23042f17de4bfb29c77a03481701173d05ef9395 [file] [log] [blame]
henrike@webrtc.orgf7795df2014-05-13 18:00:26 +00001/*
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