3 Copyright (c) 2007, Arvid Norberg
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the distribution.
15 * Neither the name of the author nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
33 #ifndef TORRENT_HTTP_CONNECTION
34 #define TORRENT_HTTP_CONNECTION
36 #include <boost/function.hpp>
37 #include <boost/bind.hpp>
38 #include <boost/shared_ptr.hpp>
39 #include <boost/enable_shared_from_this.hpp>
40 #include <boost/noncopyable.hpp>
45 #include "libtorrent/socket.hpp"
46 #include "libtorrent/http_parser.hpp"
47 #include "libtorrent/time.hpp"
48 #include "libtorrent/assert.hpp"
49 #include "libtorrent/socket_type.hpp"
50 #include "libtorrent/session_settings.hpp"
52 #ifdef TORRENT_USE_OPENSSL
53 #include "libtorrent/ssl_stream.hpp"
54 #include "libtorrent/variant_stream.hpp"
60 struct http_connection
;
61 class connection_queue
;
63 typedef boost::function
<void(error_code
const&
64 , http_parser
const&, char const* data
, int size
, http_connection
&)> http_handler
;
66 typedef boost::function
<void(http_connection
&)> http_connect_handler
;
68 // TODO: add bind interface
70 // when bottled, the last two arguments to the handler
72 struct http_connection
: boost::enable_shared_from_this
<http_connection
>, boost::noncopyable
74 http_connection(io_service
& ios
, connection_queue
& cc
75 , http_handler
const& handler
, bool bottled
= true
76 , http_connect_handler
const& ch
= http_connect_handler())
81 , m_connect_handler(ch
)
83 , m_last_receive(time_now())
88 , m_limiter_timer_active(false)
89 , m_limiter_timer(ios
)
91 , m_connection_ticket(-1)
97 TORRENT_ASSERT(!m_handler
.empty());
100 void rate_limit(int limit
);
102 int rate_limit() const
103 { return m_rate_limit
; }
105 std::string sendbuffer
;
107 void get(std::string
const& url
, time_duration timeout
= seconds(30)
108 , int prio
= 0, proxy_settings
const* ps
= 0, int handle_redirects
= 5
109 , std::string
const& user_agent
= "", address
const& bind_addr
= address_v4::any());
111 void start(std::string
const& hostname
, std::string
const& port
112 , time_duration timeout
, int prio
= 0, proxy_settings
const* ps
= 0
113 , bool ssl
= false, int handle_redirect
= 5
114 , address
const& bind_addr
= address_v4::any());
118 #ifdef TORRENT_USE_OPENSSL
119 variant_stream
<socket_type
, ssl_stream
<socket_type
> > const& socket() const { return m_sock
; }
121 socket_type
const& socket() const { return m_sock
; }
126 void on_resolve(error_code
const& e
127 , tcp::resolver::iterator i
);
128 void queue_connect();
129 void connect(int ticket
, tcp::endpoint target_address
);
130 void on_connect_timeout();
131 void on_connect(error_code
const& e
);
132 void on_write(error_code
const& e
);
133 void on_read(error_code
const& e
, std::size_t bytes_transferred
);
134 static void on_timeout(boost::weak_ptr
<http_connection
> p
135 , error_code
const& e
);
136 void on_assign_bandwidth(error_code
const& e
);
138 void callback(error_code
const& e
, char const* data
= 0, int size
= 0);
140 std::vector
<char> m_recvbuffer
;
141 #ifdef TORRENT_USE_OPENSSL
142 variant_stream
<socket_type
, ssl_stream
<socket_type
> > m_sock
;
147 tcp::resolver m_resolver
;
148 http_parser m_parser
;
149 http_handler m_handler
;
150 http_connect_handler m_connect_handler
;
151 deadline_timer m_timer
;
152 time_duration m_timeout
;
153 ptime m_last_receive
;
154 // bottled means that the handler is called once, when
155 // everything is received (and buffered in memory).
156 // non bottled means that once the headers have been
157 // received, data is streamed to the handler
159 // set to true the first time the handler is called
161 std::string m_hostname
;
165 std::list
<tcp::endpoint
> m_endpoints
;
167 // the current download limit, in bytes per second
171 // the number of bytes we are allowed to receive
172 int m_download_quota
;
174 // only hand out new quota 4 times a second if the
175 // quota is 0. If it isn't 0 wait for it to reach
176 // 0 and continue to hand out quota at that time.
177 bool m_limiter_timer_active
;
179 // the timer fires every 250 millisecond as long
180 // as all the quota was used.
181 deadline_timer m_limiter_timer
;
183 // the number of redirects to follow (in sequence)
186 int m_connection_ticket
;
187 connection_queue
& m_cc
;
189 // specifies whether or not the connection is
190 // configured to use a proxy
191 proxy_settings m_proxy
;
193 // true if the connection is using ssl
196 // the address to bind to. address_v4::any()
200 // the priority we have in the connection queue.
201 // 0 is normal, 1 is high