void feed::load_state(lazy_entry const& rd) { load_struct(rd, this, feed_map, sizeof(feed_map)/sizeof(feed_map[0])); lazy_entry const* e = rd.dict_find_list("items"); if (e) { m_items.reserve(e->list_size()); for (int i = 0; i < e->list_size(); ++i) { if (e->list_at(i)->type() != lazy_entry::dict_t) continue; m_items.push_back(feed_item()); load_struct(*e->list_at(i), &m_items.back(), feed_item_map , sizeof(feed_item_map)/sizeof(feed_item_map[0])); // don't load duplicates if (m_urls.find(m_items.back().url) != m_urls.end()) { m_items.pop_back(); continue; } m_urls.insert(m_items.back().url); } } load_struct(rd, &m_settings, feed_settings_map , sizeof(feed_settings_map)/sizeof(feed_settings_map[0])); e = rd.dict_find_dict("add_params"); if (e) { load_struct(*e, &m_settings.add_args, add_torrent_map , sizeof(add_torrent_map)/sizeof(add_torrent_map[0])); } e = rd.dict_find_list("history"); if (e) { for (int i = 0; i < e->list_size(); ++i) { if (e->list_at(i)->type() != lazy_entry::list_t) continue; lazy_entry const* item = e->list_at(i); if (item->list_size() != 2 || item->list_at(0)->type() != lazy_entry::string_t || item->list_at(1)->type() != lazy_entry::int_t) continue; m_added.insert(std::pair<std::string, time_t>( item->list_at(0)->string_value() , item->list_at(1)->int_value())); } } }
void http_tracker_connection::parse(int status_code, lazy_entry const& e) { boost::shared_ptr<request_callback> cb = requester(); if (!cb) return; int interval = int(e.dict_find_int_value("interval", 1800)); int min_interval = int(e.dict_find_int_value("min interval", 60)); std::string trackerid; lazy_entry const* tracker_id = e.dict_find_string("tracker id"); if (tracker_id) trackerid = tracker_id->string_value(); // parse the response lazy_entry const* failure = e.dict_find_string("failure reason"); if (failure) { fail(error_code(errors::tracker_failure), status_code , failure->string_value().c_str(), interval, min_interval); return; } lazy_entry const* warning = e.dict_find_string("warning message"); if (warning) cb->tracker_warning(tracker_req(), warning->string_value()); std::vector<peer_entry> peer_list; if (tracker_req().kind == tracker_request::scrape_request) { std::string ih = tracker_req().info_hash.to_string(); lazy_entry const* files = e.dict_find_dict("files"); if (files == 0) { fail(error_code(errors::invalid_files_entry), -1, "" , interval, min_interval); return; } lazy_entry const* scrape_data = files->dict_find_dict(ih.c_str()); if (scrape_data == 0) { fail(error_code(errors::invalid_hash_entry), -1, "" , interval, min_interval); return; } int complete = int(scrape_data->dict_find_int_value("complete", -1)); int incomplete = int(scrape_data->dict_find_int_value("incomplete", -1)); int downloaded = int(scrape_data->dict_find_int_value("downloaded", -1)); int downloaders = int(scrape_data->dict_find_int_value("downloaders", -1)); cb->tracker_scrape_response(tracker_req(), complete , incomplete, downloaded, downloaders); return; } lazy_entry const* peers_ent = e.dict_find("peers"); if (peers_ent && peers_ent->type() == lazy_entry::string_t) { char const* peers = peers_ent->string_ptr(); int len = peers_ent->string_length(); for (int i = 0; i < len; i += 6) { if (len - i < 6) break; peer_entry p; p.pid.clear(); error_code ec; p.ip = detail::read_v4_address(peers).to_string(ec); p.port = detail::read_uint16(peers); if (ec) continue; peer_list.push_back(p); } } else if (peers_ent && peers_ent->type() == lazy_entry::list_t) { int len = peers_ent->list_size(); for (int i = 0; i < len; ++i) { peer_entry p; if (!extract_peer_info(*peers_ent->list_at(i), p)) return; peer_list.push_back(p); } } else { peers_ent = 0; } #if TORRENT_USE_IPV6 lazy_entry const* ipv6_peers = e.dict_find_string("peers6"); if (ipv6_peers) { char const* peers = ipv6_peers->string_ptr(); int len = ipv6_peers->string_length(); for (int i = 0; i < len; i += 18) { if (len - i < 18) break; peer_entry p; p.pid.clear(); error_code ec; p.ip = detail::read_v6_address(peers).to_string(ec); p.port = detail::read_uint16(peers); if (ec) continue; peer_list.push_back(p); } } else { ipv6_peers = 0; } #else lazy_entry const* ipv6_peers = 0; #endif // if we didn't receive any peers. We don't care if we're stopping anyway if (peers_ent == 0 && ipv6_peers == 0 && tracker_req().event != tracker_request::stopped) { fail(error_code(errors::invalid_peers_entry), -1, "" , interval, min_interval); return; } // look for optional scrape info address external_ip; lazy_entry const* ip_ent = e.dict_find_string("external ip"); if (ip_ent) { char const* p = ip_ent->string_ptr(); if (ip_ent->string_length() == address_v4::bytes_type().size()) external_ip = detail::read_v4_address(p); #if TORRENT_USE_IPV6 else if (ip_ent->string_length() == address_v6::bytes_type().size()) external_ip = detail::read_v6_address(p); #endif } int complete = int(e.dict_find_int_value("complete", -1)); int incomplete = int(e.dict_find_int_value("incomplete", -1)); std::list<address> ip_list; if (m_tracker_connection) { error_code ec; ip_list.push_back(m_tracker_connection->socket().remote_endpoint(ec).address()); std::list<tcp::endpoint> const& epts = m_tracker_connection->endpoints(); for (std::list<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, peer_list , interval, min_interval, complete, incomplete, external_ip, trackerid); }