void web_connection_base::add_headers(std::string& request , aux::session_settings const& sett, bool using_proxy) const { request += "Host: "; request += m_host; if (m_first_request || m_settings.get_bool(settings_pack::always_send_user_agent)) { request += "\r\nUser-Agent: "; request += m_settings.get_str(settings_pack::user_agent); } if (!m_external_auth.empty()) { request += "\r\nAuthorization: "; request += m_external_auth; } else if (!m_basic_auth.empty()) { request += "\r\nAuthorization: Basic "; request += m_basic_auth; } if (sett.get_int(settings_pack::proxy_type) == settings_pack::http_pw) { request += "\r\nProxy-Authorization: Basic "; request += base64encode(sett.get_str(settings_pack::proxy_username) + ":" + sett.get_str(settings_pack::proxy_password)); } for (web_seed_entry::headers_t::const_iterator it = m_extra_headers.begin(); it != m_extra_headers.end(); ++it) { request += "\r\n"; request += it->first; request += ": "; request += it->second; } if (using_proxy) { request += "\r\nProxy-Connection: keep-alive"; } if (m_first_request || using_proxy) { request += "\r\nConnection: keep-alive"; } }
void load_struct_from_settings(aux::session_settings const& current, session_settings& ret) { for (int i = 0; i < settings_pack::num_string_settings; ++i) { if (str_settings[i].offset == 0) continue; std::string& val = *(std::string*)(((char*)&ret) + str_settings[i].offset); val = current.get_str(settings_pack::string_type_base + i); } for (int i = 0; i < settings_pack::num_int_settings; ++i) { if (int_settings[i].offset == 0) continue; int& val = *(int*)(((char*)&ret) + int_settings[i].offset); val = current.get_int(settings_pack::int_type_base + i); } for (int i = 0; i < settings_pack::num_bool_settings; ++i) { if (bool_settings[i].offset == 0) continue; bool& val = *(bool*)(((char*)&ret) + bool_settings[i].offset); val = current.get_bool(settings_pack::bool_type_base + i); } // special case for deprecated float values ret.share_ratio_limit = float(current.get_int(settings_pack::share_ratio_limit)) / 100.f; ret.seed_time_ratio_limit = float(current.get_int(settings_pack::seed_time_ratio_limit)) / 100.f; ret.peer_turnover = float(current.get_int(settings_pack::peer_turnover)) / 100.f; ret.peer_turnover_cutoff = float(current.get_int(settings_pack::peer_turnover_cutoff)) / 100.f; }
boost::shared_ptr<settings_pack> load_pack_from_struct( aux::session_settings const& current, session_settings const& s) { boost::shared_ptr<settings_pack> p = boost::make_shared<settings_pack>(); for (int i = 0; i < settings_pack::num_string_settings; ++i) { if (str_settings[i].offset == 0) continue; std::string& val = *(std::string*)(((char*)&s) + str_settings[i].offset); int setting_name = settings_pack::string_type_base + i; if (val == current.get_str(setting_name)) continue; p->set_str(setting_name, val); } for (int i = 0; i < settings_pack::num_int_settings; ++i) { if (int_settings[i].offset == 0) continue; int& val = *(int*)(((char*)&s) + int_settings[i].offset); int setting_name = settings_pack::int_type_base + i; if (val == current.get_int(setting_name)) continue; p->set_int(setting_name, val); } for (int i = 0; i < settings_pack::num_bool_settings; ++i) { if (bool_settings[i].offset == 0) continue; bool& val = *(bool*)(((char*)&s) + bool_settings[i].offset); int setting_name = settings_pack::bool_type_base + i; if (val == current.get_bool(setting_name)) continue; p->set_bool(setting_name, val); } // special case for deprecated float values int val = current.get_int(settings_pack::share_ratio_limit); if (fabs(s.share_ratio_limit - float(val) / 100.f) > 0.001f) p->set_int(settings_pack::share_ratio_limit, s.share_ratio_limit * 100); val = current.get_int(settings_pack::seed_time_ratio_limit); if (fabs(s.seed_time_ratio_limit - float(val) / 100.f) > 0.001f) p->set_int(settings_pack::seed_time_ratio_limit, s.seed_time_ratio_limit * 100); val = current.get_int(settings_pack::peer_turnover); if (fabs(s.peer_turnover - float(val) / 100.f) > 0.001) p->set_int(settings_pack::peer_turnover, s.peer_turnover * 100); val = current.get_int(settings_pack::peer_turnover_cutoff); if (fabs(s.peer_turnover_cutoff - float(val) / 100.f) > 0.001) p->set_int(settings_pack::peer_turnover_cutoff, s.peer_turnover_cutoff * 100); return p; }
void initialize_default_settings(aux::session_settings& s) { for (int i = 0; i < settings_pack::num_string_settings; ++i) { if (str_settings[i].default_value == nullptr) continue; s.set_str(settings_pack::string_type_base + i, str_settings[i].default_value); TORRENT_ASSERT(s.get_str(settings_pack::string_type_base + i) == str_settings[i].default_value); } for (int i = 0; i < settings_pack::num_int_settings; ++i) { s.set_int(settings_pack::int_type_base + i, int_settings[i].default_value); TORRENT_ASSERT(s.get_int(settings_pack::int_type_base + i) == int_settings[i].default_value); } for (int i = 0; i < settings_pack::num_bool_settings; ++i) { s.set_bool(settings_pack::bool_type_base + i, bool_settings[i].default_value); TORRENT_ASSERT(s.get_bool(settings_pack::bool_type_base + i) == bool_settings[i].default_value); } }
void apply_pack(settings_pack const* pack, aux::session_settings& sett , aux::session_impl* ses) { typedef void (aux::session_impl::*fun_t)(); std::vector<fun_t> callbacks; for (auto const& p : pack->m_strings) { // disregard setting indices that are not string types if ((p.first & settings_pack::type_mask) != settings_pack::string_type_base) continue; // ignore settings that are out of bounds int const index = p.first & settings_pack::index_mask; TORRENT_ASSERT_PRECOND(index >= 0 && index < settings_pack::num_string_settings); if (index < 0 || index >= settings_pack::num_string_settings) continue; // if the value did not change, don't call the update callback if (sett.get_str(p.first) == p.second) continue; sett.set_str(p.first, p.second); str_setting_entry_t const& sa = str_settings[index]; if (sa.fun && ses && std::find(callbacks.begin(), callbacks.end(), sa.fun) == callbacks.end()) callbacks.push_back(sa.fun); } for (auto const& p : pack->m_ints) { // disregard setting indices that are not int types if ((p.first & settings_pack::type_mask) != settings_pack::int_type_base) continue; // ignore settings that are out of bounds int const index = p.first & settings_pack::index_mask; TORRENT_ASSERT_PRECOND(index >= 0 && index < settings_pack::num_int_settings); if (index < 0 || index >= settings_pack::num_int_settings) continue; // if the value did not change, don't call the update callback if (sett.get_int(p.first) == p.second) continue; sett.set_int(p.first, p.second); int_setting_entry_t const& sa = int_settings[index]; if (sa.fun && ses && std::find(callbacks.begin(), callbacks.end(), sa.fun) == callbacks.end()) callbacks.push_back(sa.fun); } for (auto const& p : pack->m_bools) { // disregard setting indices that are not bool types if ((p.first & settings_pack::type_mask) != settings_pack::bool_type_base) continue; // ignore settings that are out of bounds int const index = p.first & settings_pack::index_mask; TORRENT_ASSERT_PRECOND(index >= 0 && index < settings_pack::num_bool_settings); if (index < 0 || index >= settings_pack::num_bool_settings) continue; // if the value did not change, don't call the update callback if (sett.get_bool(p.first) == p.second) continue; sett.set_bool(p.first, p.second); bool_setting_entry_t const& sa = bool_settings[index]; if (sa.fun && ses && std::find(callbacks.begin(), callbacks.end(), sa.fun) == callbacks.end()) callbacks.push_back(sa.fun); } // call the callbacks once all the settings have been applied, and // only once per callback for (auto const& f : callbacks) { (ses->*f)(); } }
void disk_buffer_pool::set_settings(aux::session_settings const& sett) { mutex::scoped_lock l(m_pool_mutex); // 0 cache_buffer_chunk_size means 'automatic' (i.e. // proportional to the total disk cache size) m_cache_buffer_chunk_size = sett.get_int(settings_pack::cache_buffer_chunk_size); m_lock_disk_cache = sett.get_bool(settings_pack::lock_disk_cache); #ifndef TORRENT_DISABLE_POOL_ALLOCATOR m_want_pool_allocator = sett.get_bool(settings_pack::use_disk_cache_pool); // if there are no allocated blocks, it's OK to switch allocator if (m_in_use == 0) m_using_pool_allocator = m_want_pool_allocator; #endif #if TORRENT_HAVE_MMAP // if we've already allocated an mmap, we can't change // anything unless there are no allocations in use if (m_cache_pool && m_in_use > 0) return; #endif // only allow changing size if we're not using mmapped // cache, or if we're just about to turn it off if ( #if TORRENT_HAVE_MMAP m_cache_pool == 0 || #endif sett.get_str(settings_pack::mmap_cache).empty()) { int cache_size = sett.get_int(settings_pack::cache_size); if (cache_size < 0) { boost::uint64_t phys_ram = physical_ram(); if (phys_ram == 0) m_max_use = 1024; else m_max_use = phys_ram / 8 / m_block_size; } else { m_max_use = cache_size; } m_low_watermark = m_max_use - (std::max)(16, sett.get_int(settings_pack::max_queued_disk_bytes) / 0x4000); if (m_low_watermark < 0) m_low_watermark = 0; if (m_in_use >= m_max_use && !m_exceeded_max_size) { m_exceeded_max_size = true; m_trigger_cache_trim(); } } #if TORRENT_USE_ASSERTS m_settings_set = true; #endif #if TORRENT_HAVE_MMAP // #error support resizing the map if (m_cache_pool && sett.get_str(settings_pack::mmap_cache).empty()) { TORRENT_ASSERT(m_in_use == 0); munmap(m_cache_pool, boost::uint64_t(m_max_use) * 0x4000); m_cache_pool = 0; // attempt to make MacOS not flush this to disk, making close() // block for a long time ftruncate(m_cache_fd, 0); close(m_cache_fd); m_cache_fd = -1; std::vector<int>().swap(m_free_list); } else if (m_cache_pool == 0 && !sett.get_str(settings_pack::mmap_cache).empty()) { // O_TRUNC here is because we don't actually care about what's // in the file now, there's no need to ever read that into RAM #ifndef O_EXLOCK #define O_EXLOCK 0 #endif m_cache_fd = open(sett.get_str(settings_pack::mmap_cache).c_str(), O_RDWR | O_CREAT | O_EXLOCK | O_TRUNC, 0700); if (m_cache_fd < 0) { if (m_post_alert) { error_code ec(errno, boost::system::generic_category()); m_ios.post(boost::bind(alert_callback, m_post_alert, new mmap_cache_alert(ec))); } } else { #ifndef MAP_NOCACHE #define MAP_NOCACHE 0 #endif ftruncate(m_cache_fd, boost::uint64_t(m_max_use) * 0x4000); m_cache_pool = (char*)mmap(0, boost::uint64_t(m_max_use) * 0x4000, PROT_READ | PROT_WRITE , MAP_SHARED | MAP_NOCACHE, m_cache_fd, 0); if (intptr_t(m_cache_pool) == -1) { if (m_post_alert) { error_code ec(errno, boost::system::generic_category()); m_ios.post(boost::bind(alert_callback, m_post_alert, new mmap_cache_alert(ec))); } m_cache_pool = 0; // attempt to make MacOS not flush this to disk, making close() // block for a long time ftruncate(m_cache_fd, 0); close(m_cache_fd); m_cache_fd = -1; } else { TORRENT_ASSERT((size_t(m_cache_pool) & 0xfff) == 0); m_free_list.reserve(m_max_use); for (int i = 0; i < m_max_use; ++i) m_free_list.push_back(i); } } } #endif }