00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef _WIN32
00024 #pragma warning(disable:4786)
00025 #endif
00026 #include <Utility.h>
00027
00028 #include "PeerHandler.h"
00029 #include "Session.h"
00030 #include "BString.h"
00031 #include "BTDictionary.h"
00032 #include "Exception.h"
00033 #include "Peer.h"
00034 #include "tSocket.h"
00035
00036 #ifdef _DEBUG
00037 #define DEB(x) x
00038 #else
00039 #define DEB(x)
00040 #endif
00041
00042
00043
00044 int tSocket::m_next_id = 0;
00045
00046
00047 tSocket::tSocket(ISocketHandler& h,const std::string& hash)
00048 :HttpGetSocket(h)
00049 ,m_hash(hash)
00050 ,m_gzip(false)
00051 {
00052 DEB(printf("tSocket()\n");)
00053 Session *p = static_cast<PeerHandler&>(Handler()).GetSession(hash);
00054 if (p)
00055 {
00056 std::string announce = p -> GetAnnounceUrl("started");
00057 std::string host;
00058 port_t port;
00059 Url(announce, host, port);
00060 if (host.size() && port)
00061 {
00062 PeerHandler& ref = static_cast<PeerHandler&>(Handler());
00063 m_filename = ref.GetTorrentDirectory() + "/" + hash + "/tracker." + Utility::l2string(++m_next_id);
00064 ref.mkpath( m_filename );
00065 SetFilename(m_filename);
00066 SetConnectTimeout(30);
00067 Open(host, port);
00068 DEB(printf("Tracker host : %s\n", host.c_str());)
00069 DEB(printf("Tracker port : %d\n", port);)
00070 DEB(printf("Tracker URL : %s\n", announce.c_str());)
00071 }
00072 else
00073 SetCloseAndDelete();
00074 }
00075 else
00076 SetCloseAndDelete();
00077 }
00078
00079
00080 tSocket::~tSocket()
00081 {
00082 DEB(printf("~tSocket()\n");)
00083 unlink(m_filename.c_str());
00084 }
00085
00086
00087 void tSocket::OnDelete()
00088 {
00089 HttpGetSocket::OnDelete();
00090 if (!Complete())
00091 {
00092 DEB(printf("Tracker reply incomplete\n");)
00093 return;
00094 }
00095 Session *sess = static_cast<PeerHandler&>(Handler()).GetSession(m_hash);
00096 if (!sess)
00097 {
00098 return;
00099 }
00100 if (m_gzip)
00101 {
00102 char cmd[1000];
00103 DEB(printf("Tracker reply gzipped\n");)
00104 unlink(m_filename.substr(0, m_filename.size() - 3).c_str());
00105 #ifdef _WIN32
00106 sprintf(cmd, "gzip.exe -d %s", m_filename.c_str());
00107 #else
00108 sprintf(cmd, "/usr/bin/gzip -d %s", m_filename.c_str());
00109 #endif
00110 system( cmd );
00111 m_filename = m_filename.substr(0, m_filename.size() - 3);
00112 }
00113 DEB(printf("TrackerReply() in file '%s'\n",m_filename.c_str());)
00114 try
00115 {
00116 FILE *fil;
00117 if ((fil = fopen(m_filename.c_str(),"rb")) != NULL)
00118 {
00119 BString bstr;
00120 bstr.read_file(fil);
00121 fclose(fil);
00122 BTInteger *p = dynamic_cast<BTInteger *>(bstr.GetBTObject("interval"));
00123 if (p)
00124 {
00125 int interval = atoi(p -> GetValue().c_str());
00126 DEB(printf("Tracker contact interval: %d\n",interval);)
00127 sess -> SetInterval( interval );
00128 }
00129 BTList *l = dynamic_cast<BTList *>(bstr.GetBTObject("peers"));
00130 if (l)
00131 {
00132 DEB(printf(" peers found\n");)
00133 for (btobject_v::iterator it = l -> GetList().begin(); it != l -> GetList().end(); it++)
00134 {
00135 BTDictionary *p = dynamic_cast<BTDictionary *>(*it);
00136 std::string ip;
00137 std::string id;
00138 int port = 0;
00139 if (p)
00140 {
00141 DEB(printf(" dictionary found\n");)
00142 for (btmap_t::iterator it = p -> GetMap().begin(); it != p -> GetMap().end(); it++)
00143 {
00144 std::string key = (*it).first;
00145 BTObject *p0 = (*it).second;
00146 if (key == "ip")
00147 {
00148 BTString *p = dynamic_cast<BTString *>(p0);
00149 if (p)
00150 ip = p -> GetValue();
00151 }
00152 else
00153 if (key == "peer id")
00154 {
00155 BTString *p = dynamic_cast<BTString *>(p0);
00156 if (p)
00157 id = p -> GetValue();
00158 }
00159 else
00160 if (key == "port")
00161 {
00162 BTInteger *p = dynamic_cast<BTInteger *>(p0);
00163 if (p)
00164 port = atoi(p -> GetValue().c_str());
00165 }
00166 }
00167 }
00168 if (ip.size() && id.size() == 20 && port)
00169 {
00170 Peer *p = sess -> GetPeer(ip);
00171 if (!p)
00172 {
00173 Peer *p = new Peer(Handler(),m_hash,ip,id,port);
00174 sess -> AddPeer(p);
00175 }
00176 else
00177 {
00178 p -> SetPort(port);
00179 }
00180 }
00181 }
00182 }
00183 }
00184 }
00185 catch (const Exception& DEB(e))
00186 {
00187 DEB(printf("Exception when reading response from tracker: %s\n", e.GetText().c_str());)
00188 }
00189 }
00190
00191
00192 void tSocket::OnFirst()
00193 {
00194 HttpGetSocket::OnFirst();
00195
00196 DEB( printf("IsRequest: %s\n",IsRequest() ? "YES" : "NO");
00197 if (IsRequest())
00198 {
00199 printf(" Method: %s\n",GetMethod().c_str());
00200 printf(" URL: %s\n",GetUrl().c_str());
00201 printf(" Http version: %s\n",GetHttpVersion().c_str());
00202 })
00203
00204 DEB( printf("IsResponse: %s\n",IsResponse() ? "YES" : "NO");
00205 if (IsResponse())
00206 {
00207 printf(" Http version: %s\n",GetHttpVersion().c_str());
00208 printf(" Status: %s\n",GetStatus().c_str());
00209 printf(" Status text: %s\n",GetStatusText().c_str());
00210 })
00211 }
00212
00213
00214 void tSocket::OnHeader(const std::string& key,const std::string& value)
00215 {
00216 HttpGetSocket::OnHeader(key,value);
00217 DEB(printf("%s: %s\n", key.c_str(), value.c_str());)
00218 if (!strcasecmp(key.c_str(), "content-encoding"))
00219 {
00220 DEB(printf(" *** ENCODING: %s\n", value.c_str());)
00221 if (!strcasecmp(value.c_str(), "gzip"))
00222 {
00223 m_filename += ".gz";
00224 SetFilename(m_filename);
00225 m_gzip = true;
00226 }
00227 }
00228 }
00229
00230
00231 void tSocket::OnConnect()
00232 {
00233 HttpGetSocket::OnConnect();
00234 #ifdef _WIN32
00235
00236 AddResponseHeader( "Accept-Encoding", "gzip;q=0");
00237 #endif
00238 }
00239
00240