00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef TORRENT_HTTP_TRACKER_CONNECTION_HPP_INCLUDED
00034 #define TORRENT_HTTP_TRACKER_CONNECTION_HPP_INCLUDED
00035
00036 #include <vector>
00037 #include <string>
00038 #include <utility>
00039 #include <ctime>
00040
00041 #ifdef _MSC_VER
00042 #pragma warning(push, 1)
00043 #endif
00044
00045 #include <boost/shared_ptr.hpp>
00046 #include <boost/date_time/posix_time/posix_time.hpp>
00047 #include <boost/cstdint.hpp>
00048 #include <boost/tuple/tuple.hpp>
00049
00050 #ifdef _MSC_VER
00051 #pragma warning(pop)
00052 #endif
00053
00054 #include "libtorrent/socket.hpp"
00055 #include "libtorrent/entry.hpp"
00056 #include "libtorrent/session_settings.hpp"
00057 #include "libtorrent/peer_id.hpp"
00058 #include "libtorrent/peer.hpp"
00059 #include "libtorrent/tracker_manager.hpp"
00060 #include "libtorrent/config.hpp"
00061 #include "libtorrent/buffer.hpp"
00062
00063 namespace libtorrent
00064 {
00065
00066 class http_parser
00067 {
00068 public:
00069 http_parser();
00070 template <class T>
00071 T header(char const* key) const;
00072 std::string const& protocol() const { return m_protocol; }
00073 int status_code() const { return m_status_code; }
00074 std::string message() const { return m_server_message; }
00075 buffer::const_interval get_body() const;
00076 bool header_finished() const { return m_state == read_body; }
00077 bool finished() const { return m_finished; }
00078 boost::tuple<int, int> incoming(buffer::const_interval recv_buffer);
00079 int body_start() const { return m_body_start_pos; }
00080 int content_length() const { return m_content_length; }
00081
00082 void reset();
00083 private:
00084 int m_recv_pos;
00085 int m_status_code;
00086 std::string m_protocol;
00087 std::string m_server_message;
00088
00089 int m_content_length;
00090
00091 enum { read_status, read_header, read_body } m_state;
00092
00093 std::map<std::string, std::string> m_header;
00094 buffer::const_interval m_recv_buffer;
00095 int m_body_start_pos;
00096
00097 bool m_finished;
00098 };
00099
00100 template <class T>
00101 T http_parser::header(char const* key) const
00102 {
00103 std::map<std::string, std::string>::const_iterator i
00104 = m_header.find(key);
00105 if (i == m_header.end()) return T();
00106 return boost::lexical_cast<T>(i->second);
00107 }
00108
00109 class TORRENT_EXPORT http_tracker_connection
00110 : public tracker_connection
00111 {
00112 friend class tracker_manager;
00113 public:
00114
00115 http_tracker_connection(
00116 asio::strand& str
00117 , tracker_manager& man
00118 , tracker_request const& req
00119 , std::string const& hostname
00120 , unsigned short port
00121 , std::string request
00122 , address bind_infc
00123 , boost::weak_ptr<request_callback> c
00124 , session_settings const& stn
00125 , std::string const& password = "");
00126
00127 private:
00128
00129 boost::intrusive_ptr<http_tracker_connection> self()
00130 { return boost::intrusive_ptr<http_tracker_connection>(this); }
00131
00132 void on_response();
00133
00134 void init_send_buffer(
00135 std::string const& hostname
00136 , std::string const& request);
00137
00138 void name_lookup(asio::error_code const& error, tcp::resolver::iterator i);
00139 void connected(asio::error_code const& error);
00140 void sent(asio::error_code const& error);
00141 void receive(asio::error_code const& error
00142 , std::size_t bytes_transferred);
00143
00144 virtual void on_timeout();
00145
00146 void parse(const entry& e);
00147 peer_entry extract_peer_info(const entry& e);
00148
00149 tracker_manager& m_man;
00150 http_parser m_parser;
00151
00152 asio::strand& m_strand;
00153 tcp::resolver m_name_lookup;
00154 int m_port;
00155 boost::shared_ptr<stream_socket> m_socket;
00156 int m_recv_pos;
00157 std::vector<char> m_buffer;
00158 std::string m_send_buffer;
00159
00160 session_settings const& m_settings;
00161 std::string m_password;
00162
00163 bool m_timed_out;
00164 };
00165
00166 }
00167
00168 #endif // TORRENT_HTTP_TRACKER_CONNECTION_HPP_INCLUDED
00169