void http_tracker_connection::on_response(error_code const& ec , http_parser const& parser, char const* data, int size) { // keep this alive boost::intrusive_ptr<http_tracker_connection> me(this); if (ec && ec != asio::error::eof) { fail(-1, ec.message().c_str()); return; } if (!parser.header_finished()) { fail(-1, "premature end of file"); return; } if (parser.status_code() != 200) { fail(parser.status_code(), parser.message().c_str()); return; } if (ec && ec != asio::error::eof) { fail(parser.status_code(), ec.message().c_str()); return; } received_bytes(size + parser.body_start()); // handle tracker response lazy_entry e; int res = lazy_bdecode(data, data + size, e); if (res == 0 && e.type() == lazy_entry::dict_t) { parse(parser.status_code(), e); } else { std::string error_str("invalid encoding of tracker response: \""); for (char const* i = data, *end(data + size); i != end; ++i) { if (*i >= ' ' && *i <= '~') error_str += *i; else { char val[30]; snprintf(val, sizeof(val), "0x%02x ", *i); error_str += val; } } error_str += "\""; fail(parser.status_code(), error_str.c_str()); } close(); }
void http_tracker_connection::on_response(error_code const& ec , http_parser const& parser, char const* data, int size) { // keep this alive boost::intrusive_ptr<http_tracker_connection> me(this); if (ec && ec != asio::error::eof) { fail(ec); return; } if (!parser.header_finished()) { fail(asio::error::eof); return; } if (parser.status_code() != 200) { fail(error_code(parser.status_code(), get_http_category()) , parser.status_code(), parser.message().c_str()); return; } if (ec && ec != asio::error::eof) { fail(ec, parser.status_code()); return; } received_bytes(size + parser.body_start()); // Howdy Patch to work around extra lines in tracker responses. while (data && (*data == 0x0d || *data == 0x0a)) { data++; size--; } // handle tracker response lazy_entry e; error_code ecode; int res = lazy_bdecode(data, data + size, e, ecode); if (res == 0 && e.type() == lazy_entry::dict_t) { parse(parser.status_code(), e); } else { fail(ecode, parser.status_code()); } close(); }
void http_tracker_connection::on_response(error_code const& ec , http_parser const& parser, char const* data, int size) { // keep this alive boost::shared_ptr<http_tracker_connection> me(shared_from_this()); if (ec && ec != boost::asio::error::eof) { fail(ec); return; } if (!parser.header_finished()) { fail(boost::asio::error::eof); return; } if (parser.status_code() != 200) { fail(error_code(parser.status_code(), get_http_category()) , parser.status_code(), parser.message().c_str()); return; } if (ec && ec != boost::asio::error::eof) { fail(ec, parser.status_code()); return; } received_bytes(size + parser.body_start()); // handle tracker response error_code ecode; boost::shared_ptr<request_callback> cb = requester(); if (!cb) { close(); return; } tracker_response resp = parse_tracker_response(data, size, ecode , tracker_req().kind, tracker_req().info_hash); if (!resp.warning_message.empty()) cb->tracker_warning(tracker_req(), resp.warning_message); if (ecode) { fail(ecode, parser.status_code(), resp.failure_reason.c_str() , resp.interval, resp.min_interval); close(); return; } // do slightly different things for scrape requests if (0 != (tracker_req().kind & tracker_request::scrape_request)) { cb->tracker_scrape_response(tracker_req(), resp.complete , resp.incomplete, resp.downloaded, resp.downloaders); } else { std::list<address> ip_list; if (m_tracker_connection) { error_code ignore; std::vector<tcp::endpoint> const& epts = m_tracker_connection->endpoints(); for (std::vector<tcp::endpoint>::const_iterator i = epts.begin() , end(epts.end()); i != end; ++i) { ip_list.push_back(i->address()); } } cb->tracker_response(tracker_req(), m_tracker_ip, ip_list, resp); } close(); }