Changeset 1486
- Timestamp:
- 07/17/05 18:11:08 (3 years ago)
- Files:
-
- testing/http/download.cpp (modified) (7 diffs)
- testing/http/download.h (modified) (5 diffs)
- testing/http/http.h (modified) (1 diff)
- testing/http/parser.cpp (modified) (3 diffs)
- testing/http/parser.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
testing/http/download.cpp
r1484 r1486 70 70 do { 71 71 it = m_connections.begin(); 72 deleteConnection( (++it)->first);72 deleteConnection(++it); 73 73 } while(it != m_connections.end()); 74 75 74 m_connections.clear(); 76 75 } … … 79 78 void Download::onPDEvent(PartData *pd, int evt) { 80 79 if(pd == m_pd && evt == PD_COMPLETE) { 80 logTrace(TRACE, "Download completed... now deleting"); 81 81 HttpClient::instance().deleteDownload(this); 82 82 } … … 96 96 97 97 case EVT_SF_FOUND: 98 {99 98 logTrace(TRACE, "Got EVT_SF_FOUND (sharedfile was found) --> starting download"); 100 int port = boost::lexical_cast<int>(m_url["port"]); 101 IPV4Address addr(m_url["host"], port); 102 103 Parser *p = createConnection(addr); 104 p->setHostName(m_url["hostname"]); 105 p->getFile(m_url["path"]); 106 p->writeData.connect(boost::bind(&Download::writeData, this, _b1, _b2)); 107 108 break; 109 } 99 getRandomChunk(); 100 break; 101 110 102 case EVT_ERROR: 111 103 logError("An error occured..."); … … 114 106 } 115 107 116 void Download::onParserEvent(Parser *p, ParserEvent evt) { 108 void Download::getRandomChunk(uint64_t chunksize) { 109 logTrace(TRACE, "getRandomChunk()"); 110 uint64_t reqSize = m_size/4; 111 if(chunksize) { 112 reqSize = chunksize; 113 } 114 doGet(reqSize); 115 } 116 117 void Download::getWholeFile() { 118 logTrace(TRACE, "getWholeFile()"); 119 doGet(m_size); 120 } 121 122 void Download::doGet(uint64_t chunksize) { 123 logTrace(TRACE, "doGet()"); 124 125 Detail::UsedRangePtr used = m_pd->getRange(chunksize); 126 m_locked = used->getLock(chunksize); 127 128 int port = boost::lexical_cast<int>(m_url["port"]); 129 IPV4Address addr(m_url["host"], port); 130 131 Parser *p = createConnection(addr); 132 p->setHostName(m_url["hostname"]); 133 p->writeData.connect(boost::bind(&Download::writeData, this, _b1, _b2, _b3)); 134 135 if(chunksize != m_size) { 136 Range64 *range = new Range64(m_locked->begin(), m_locked->end()); 137 138 if(range->length() > 1) { 139 logTrace(TRACE, 140 boost::format("trying to get range: %d-%d") 141 % range->begin() % range->end() 142 ); 143 p->getChunk(m_url["path"], range); 144 } 145 } else { 146 p->getFile(m_url["path"]); 147 } 148 } 149 150 void Download::onParserEvent(Parser *p, ParserEvent evt) try { 117 151 HttpSocket *s = getSocket(p); 152 boost::format fmt("Parser(%p): %s"); 153 fmt % p; 118 154 switch(evt) { 119 155 case EVT_SIZE: 120 logTrace(TRACE, 121 boost::format("Connection(%p) found new filesize") % s 122 ); 156 fmt % "found new filesize"; 123 157 if(m_size > 0) { 124 logError("Filesize is already set!");158 fmt % "Filesize is already set!"; 125 159 } else { 126 160 m_size = getParser(s)->getSize(); 127 logTrace(TRACE, 128 boost::format("setting filesize to %i") % m_size 129 ); 130 161 fmt % "setting filesize to %i" % m_size; 131 162 deleteConnection(s); 132 133 163 if(m_size > 0) { 134 164 postEvent(EVT_SET_SIZE); 135 165 } 136 166 } 137 break; 138 167 break; 168 169 case EVT_COMPLETE: 170 fmt % "completed its download..."; 171 if(!m_pd->isComplete()) { 172 getRandomChunk(); 173 } 174 break; 175 176 case EVT_MD5: 177 { 178 fmt % "found a MD5 digest: %s" % p->getMD5(); 179 Hash<MD5Hash> hash(p->getMD5()); 180 HashSet<MD5Hash> *hs = new HashSet<MD5Hash>(hash); 181 m_md->addHashSet(hs); 182 break; 183 } 184 185 case EVT_NORANGES: 186 fmt % "doesn't support ranges, getting the whole file..."; 187 getWholeFile(); 188 break; 189 139 190 case EVT_DESTROY: 140 logTrace(TRACE, 141 boost::format("Connection(%p) wants to be destroyed :D") % s 142 ); 191 fmt % "wants to be destroyed :D"; 143 192 deleteConnection(s); 144 193 break; 145 194 146 195 case EVT_FAILURE: 147 logTrace(TRACE, 148 boost::format("Connection(%p) received an " 149 "unsuccessful HTTP response: %s") 150 % s % getParser(s)->getStatusCode() 151 ); 196 fmt % "received an unsuccessful HTTP response: %s" 197 % getParser(s)->getStatusCode(); 152 198 break; 153 199 154 200 default: 155 logTrace(TRACE, 156 boost::format("Connection(%p) posted unhandled event: %p") % s % evt 157 ); 158 } 159 } 201 fmt % "posted unhandled event: %p" % evt; 202 } 203 logTrace(TRACE, fmt.str()); 204 205 } catch(std::exception &e) { 206 logError(std::string("onParserEvent():") + e.what()); 207 } 208 MSVC_ONLY(;) 160 209 161 210 void Download::createDownload() { … … 231 280 } 232 281 233 void Download::writeData( const std::string &data, uint64_t offset) {282 void Download::writeData(Parser *p, const std::string &data, uint64_t offset) { 234 283 CHECK_THROW(m_pd != NULL); 235 284 236 logTrace(TRACE, boost::format("writeData() at offset: %i") % offset); 285 logTrace(TRACE, 286 boost::format("writeData(parser=%p) at offset: %i") % p % offset 287 ); 237 288 238 289 try { 239 m_pd->write(offset, data); 290 if(m_locked) { 291 m_locked->write(offset, data); 292 } else { 293 m_pd->write(offset, data); 294 } 240 295 } catch(std::exception &e) { 241 296 logError(boost::format("Unable to write data: %s") % e.what()); … … 256 311 Parser *p = new Parser; 257 312 p->getEventTable().addHandler(p, this, &Download::onParserEvent); 258 //p->writeData.connect(boost::bind(&Download::writeData, this, _b1, _b2));259 313 p->sendData.connect(boost::bind(&Download::sendData, this, _b1, _b2)); 314 Detail::LockedRangePtr ptr; 260 315 261 m_connections.insert( std::make_pair(s, p) ); 262 316 m_connections.insert( Connection(s, p, ptr) ); 263 317 return p; 264 318 } 265 319 266 320 void Download::deleteConnection(HttpSocket *s) { 267 logTrace(TRACE, 268 boost::format("deleteConnection(%p)") % s 269 ); 270 connIter it = m_connections.find(s); 271 272 if(it != m_connections.end()) { 321 logTrace(TRACE, boost::format("deleteConnection(%p)") % s); 322 323 socketIter it = m_connections.get<socket>().find(s); 324 325 if(it != m_connections.get<socket>().end()) { 273 326 HttpSocket *tmp = s; 274 Parser *p = (*it).second;327 Parser *p = it->parser; 275 328 delete s; 276 329 delete p; … … 279 332 m_connections.erase(tmp); 280 333 } 334 281 335 logTrace(TRACE, "deleteConnection finished..."); 282 336 } 283 337 338 void Download::deleteConnection(connIter it) { 339 logTrace(TRACE, "deleteConnection(connIter)"); 340 341 if(it != m_connections.end()) { 342 HttpSocket *s = it->socket; 343 Parser *p = it->parser; 344 delete s; 345 delete p; 346 p = 0; 347 s = 0; 348 m_connections.erase(it); 349 } else { 350 throw std::runtime_error("no such Connection"); 351 } 352 } 353 284 354 void Download::sendData(Parser *p, const std::string &data) { 285 HttpSocket *s = getSocket(p); 286 s->write(data); 355 try { 356 HttpSocket *s = getSocket(p); 357 s->write(data); 358 } catch(std::exception &e) { 359 logError(boost::format("unable to get Socket: %s") % e.what()); 360 } 287 361 } 288 362 289 363 HttpSocket* Download::getSocket(Parser *p) { 290 connIter it = m_connections.begin(); 291 for( ; it != m_connections.end(); ++it) { 292 if(it->second == p) { 293 return it->first; 294 } 295 } 364 logTrace(TRACE, boost::format("getSocket(parser=%p)") % p); 365 parserIter it = m_connections.get<parser>().find(p); 366 if(it != m_connections.get<parser>().end()) { 367 logTrace(TRACE, boost::format("found socket=%p") % it->socket); 368 return it->socket; 369 } else { 370 throw std::runtime_error("couldn't find socket in MIConn"); 371 } 296 372 } 297 373 298 374 Parser* Download::getParser(HttpSocket *s) { 299 connIter it = m_connections.find(s); 300 CHECK_THROW(it != m_connections.end()); 301 return it->second; 375 logTrace(TRACE, boost::format("getParser(socket=%p)") % s); 376 socketIter it = m_connections.get<socket>().find(s); 377 if(it != m_connections.get<socket>().end()) { 378 logTrace(TRACE, boost::format("found parser=%p") % it->parser); 379 return it->parser; 380 } else { 381 throw std::runtime_error("couldn't find parser in MIConn"); 382 } 302 383 } 303 384 testing/http/download.h
r1481 r1486 26 26 #include <hn/object.h> 27 27 #include <hn/ssocket.h> 28 #include <boost/multi_index_container.hpp> 29 #include <boost/multi_index/key_extractors.hpp> 30 #include <boost/multi_index/ordered_index.hpp> 31 #include <boost/multi_index/member.hpp> 28 32 29 33 namespace Http { 30 34 35 using namespace boost; 36 using namespace boost::multi_index; 37 31 38 typedef SSocket<HttpClient, Socket::Client, Socket::TCP> HttpSocket; 32 typedef std::map<HttpSocket*, Parser*> connMap; 33 typedef connMap::iterator connIter; 39 40 typedef struct Connection { 41 HttpSocket* socket; 42 Parser* parser; 43 Detail::LockedRangePtr range; 44 45 Connection(HttpSocket *s, Parser *p, Detail::LockedRangePtr r) 46 : socket(s), parser(p), range(r) {} 47 }; 48 49 //tags for accessing the corresponding indices of MIConn 50 struct socket{}; 51 struct parser{}; 52 struct range{}; 53 54 typedef multi_index_container< 55 Connection, 56 indexed_by< 57 ordered_unique< 58 tag<socket>, 59 BOOST_MULTI_INDEX_MEMBER(Connection, HttpSocket*, socket) 60 >, 61 ordered_unique< 62 tag<parser>, 63 BOOST_MULTI_INDEX_MEMBER(Connection, Parser*, parser) 64 >, 65 ordered_unique< 66 tag<range>, 67 BOOST_MULTI_INDEX_MEMBER(Connection, Detail::LockedRangePtr, range) 68 > 69 > 70 > MIConn; 71 72 typedef MIConn::iterator connIter; 73 typedef MIConn::nth_index<0>::type::iterator socketIter; 74 typedef MIConn::nth_index<1>::type::iterator parserIter; 75 typedef MIConn::nth_index<2>::type::iterator rangeIter; 34 76 35 77 enum DownloadEvent { … … 45 87 ~Download(); 46 88 47 void writeData( const std::string &data, uint64_t offset);89 void writeData(Parser *p, const std::string &data, uint64_t offset); 48 90 void sendData(Parser *p, const std::string &data); 49 91 … … 54 96 void postEvent(DownloadEvent evt); 55 97 void onDownloadEvent(DownloadEvent evt); 98 99 void getWholeFile(); 100 void getRandomChunk(uint64_t chunksize = 0); 56 101 57 102 //! Comparison operator for std containers … … 68 113 Parser* createConnection(const IPV4Address &addr); 69 114 void deleteConnection(HttpSocket *s); 115 void deleteConnection(connIter it); 70 116 void findSharedFile(); 71 117 HttpSocket* getSocket(Parser *p); 72 118 Parser* getParser(HttpSocket *s); 73 119 void doGet(uint64_t chunksize); 120 74 121 std::map<std::string, std::string> m_url; 75 connMapm_connections;122 MIConn m_connections; 76 123 77 124 uint64_t m_size; … … 80 127 SharedFile* m_sf; 81 128 MetaData* m_md; 129 Detail::LockedRangePtr m_locked; 82 130 }; 83 131 testing/http/http.h
r1481 r1486 37 37 EVT_DATA, 38 38 EVT_FAILURE, 39 EVT_DESTROY 39 EVT_DESTROY, 40 EVT_COMPLETE, 41 EVT_NORANGES 40 42 }; 41 43 testing/http/parser.cpp
r1483 r1486 110 110 } 111 111 112 std::string Parser::getMD5() { 113 return getHeader("content-md5"); 114 } 115 112 116 void Parser::tryRequest(const std::string &file) { 113 117 //absolute path AND hostname: … … 219 223 getEventTable().postEvent(this, EVT_SIZE); 220 224 } 225 if(getHeader("accept-ranges") != "bytes") { 226 getEventTable().postEvent(this, EVT_NORANGES); 227 } 221 228 } 222 229 } … … 248 255 249 256 if(success) { 250 writeData( data, m_offset);257 writeData(this, data, m_offset); 251 258 m_offset += data.size(); 259 } 260 if(m_offset == m_range->end() + 1) { 261 getEventTable().postEvent(this, EVT_COMPLETE); 252 262 } 253 263 } testing/http/parser.h
r1482 r1486 42 42 void setHostName(const std::string &hostname); 43 43 44 std::string getHeader(const std::string &header); 45 int getStatusCode(); 46 uint64_t getSize(); 47 void getFile(const std::string &file); 48 void getInfo(const std::string &file); 49 void getChunk(const std::string &file, Range64 *range); 50 51 boost::signal<void (const std::string&, uint64_t)> writeData; 44 std::string getHeader(const std::string &header); 45 std::string getMD5(); 46 int getStatusCode(); 47 uint64_t getSize(); 48 void getFile(const std::string &file); 49 void getInfo(const std::string &file); 50 void getChunk(const std::string &file, Range64 *range); 51 52 boost::signal<void (Parser*, const std::string&, uint64_t)> writeData; 52 53 boost::signal<void (Parser*, const std::string&)> sendData; 53 54
