Logo
~Apps~
~Projects~
~Contact~


tSocket.cpp

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2005  Anders Hedstrom
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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); // remove .gz
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         // makes no difference :(
00236         AddResponseHeader( "Accept-Encoding", "gzip;q=0");
00237 #endif
00238 }
00239 
00240 
Page, code, and content Copyright (C) 2006 by Anders Hedström
Generated on Mon Aug 29 20:21:47 2005 for C++ Sockets by  doxygen 1.4.4