void test_announce() { t_user* u = find_ptr(m_users, 1); Ctracker_input i; i.m_info_hash = "IHIHIHIHIHIHIHIHIHIH"; memcpy(i.m_peer_id.data(), str_ref("PIPIPIPIPIPIPIPIPIPI")); i.m_ipa = htonl(0x7f000063); i.m_port = 54321; std::cout << srv_insert_peer(i, false, u) << std::endl; write_db_torrents(); write_db_users(); m_time++; i.m_uploaded = 1 << 30; i.m_downloaded = 1 << 20; std::cout << srv_insert_peer(i, false, u) << std::endl; write_db_torrents(); write_db_users(); m_time += 3600; clean_up(); write_db_torrents(); write_db_users(); }
void Cconnection::read(const std::string& v) { #ifndef NDEBUG std::cout << v << std::endl; #endif if (srv_config().m_log_access) { static std::ofstream f("xbt_tracker_raw.log"); f << srv_time() << '\t' << inet_ntoa(m_a.sin_addr) << '\t' << ntohs(m_a.sin_port) << '\t' << v << std::endl; } Ctracker_input ti; size_t e = v.find('?'); if (e == std::string::npos) e = v.size(); else { size_t a = e + 1; size_t b = v.find(' ', a); if (b == std::string::npos) return; while (a < b) { size_t c = v.find('=', a); if (c++ == std::string::npos) break; size_t d = v.find_first_of(" &", c); if (d == std::string::npos) break; ti.set(v.substr(a, c - a - 1), uri_decode(v.substr(c, d - c))); a = d + 1; } } if (!ti.m_ipa || !is_private_ipa(m_a.sin_addr.s_addr)) ti.m_ipa = m_a.sin_addr.s_addr; str_ref torrent_pass; size_t a = 4; if (a < e && v[a] == '/') { a++; if (a + 32 < e && v[a + 32] == '/') { torrent_pass.assign(&v[a], 32); a += 33; } } std::string h = "HTTP/1.0 200 OK\r\n"; std::string s; bool gzip = true; switch (a < v.size() ? v[a] : 0) { case 'a': if (ti.valid()) { gzip = false; std::string error = srv_insert_peer(ti, false, find_user_by_torrent_pass(torrent_pass, ti.m_info_hash)); s = error.empty() ? srv_select_peers(ti) : (boost::format("d14:failure reason%d:%se") % error.size() % error).str(); } break; case 'd': if (srv_config().m_debug) { h += "Content-Type: text/html; charset=us-ascii\r\n"; s = srv_debug(ti); } break; case 's': if (v.size() >= 7 && v[6] == 't') { h += "Content-Type: text/html; charset=us-ascii\r\n"; s = srv_statistics(); } else if (srv_config().m_full_scrape || !ti.m_info_hash.empty()) { gzip = srv_config().m_gzip_scrape && ti.m_info_hash.empty(); s = srv_scrape(ti, find_user_by_torrent_pass(torrent_pass, ti.m_info_hash)); } break; } if (s.empty()) { if (!ti.m_info_hash.empty() || srv_config().m_redirect_url.empty()) h = "HTTP/1.0 404 Not Found\r\n"; else { h = "HTTP/1.0 302 Found\r\n" "Location: " + srv_config().m_redirect_url + (ti.m_info_hash.empty() ? "" : "?info_hash=" + uri_encode(ti.m_info_hash)) + "\r\n"; } } else if (gzip) { shared_data s2 = xcc_z::gzip(s); #ifndef NDEBUG static std::ofstream f("xbt_tracker_gzip.log"); f << srv_time() << '\t' << v[5] << '\t' << s.size() << '\t' << s2.size() << std::endl; #endif if (s2.size() + 24 < s.size()) { h += "Content-Encoding: gzip\r\n"; s = to_string(s2); } } h += "\r\n"; #ifdef WIN32 m_write_b = shared_data(h.size() + s.size()); memcpy(m_write_b.data(), h); memcpy(m_write_b.data() + h.size(), s); int r = m_s.send(m_write_b); #else std::array<iovec, 2> d; d[0].iov_base = const_cast<char*>(h.data()); d[0].iov_len = h.size(); d[1].iov_base = const_cast<char*>(s.data()); d[1].iov_len = s.size(); msghdr m; m.msg_name = NULL; m.msg_namelen = 0; m.msg_iov = const_cast<iovec*>(d.data()); m.msg_iovlen = d.size(); m.msg_control = NULL; m.msg_controllen = 0; m.msg_flags = 0; int r = sendmsg(m_s, &m, MSG_NOSIGNAL); #endif if (r == SOCKET_ERROR) { if (WSAGetLastError() != WSAECONNRESET) std::cerr << "send failed: " << Csocket::error2a(WSAGetLastError()) << std::endl; } else if (r != h.size() + s.size()) { #ifndef WIN32 if (r < h.size()) { m_write_b = shared_data(h.size() + s.size()); memcpy(m_write_b.data(), h); memcpy(m_write_b.data() + h.size(), s); } else { m_write_b = make_shared_data(s); r -= h.size(); } #endif m_r = m_write_b; m_r.advance_begin(r); } if (m_r.empty()) m_write_b.clear(); }