From 053f499ec6666aaa4fe51c50fd0c95ecacf0f91d Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Thu, 20 Sep 2007 23:25:40 +0000 Subject: [PATCH] better upnp support --- .../libtorrent/http_tracker_connection.hpp | 4 +++ src/http_tracker_connection.cpp | 16 ++++++++---- src/upnp.cpp | 25 ++++++++++++++++--- test/test_primitives.cpp | 19 ++++++++++++++ 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/include/libtorrent/http_tracker_connection.hpp b/include/libtorrent/http_tracker_connection.hpp index 35d529504..76c3aac98 100755 --- a/include/libtorrent/http_tracker_connection.hpp +++ b/include/libtorrent/http_tracker_connection.hpp @@ -73,6 +73,8 @@ namespace libtorrent T header(char const* key) const; std::string const& protocol() const { return m_protocol; } int status_code() const { return m_status_code; } + std::string const& method() const { return m_method; } + std::string const& path() const { return m_path; } std::string message() const { return m_server_message; } buffer::const_interval get_body() const; bool header_finished() const { return m_state == read_body; } @@ -85,6 +87,8 @@ namespace libtorrent private: int m_recv_pos; int m_status_code; + std::string m_method; + std::string m_path; std::string m_protocol; std::string m_server_message; diff --git a/src/http_tracker_connection.cpp b/src/http_tracker_connection.cpp index 3fcd97dbc..0a0e59c48 100755 --- a/src/http_tracker_connection.cpp +++ b/src/http_tracker_connection.cpp @@ -148,13 +148,19 @@ namespace libtorrent pos = newline; line >> m_protocol; - if (m_protocol.substr(0, 5) != "HTTP/") + if (m_protocol.substr(0, 5) == "HTTP/") { - throw std::runtime_error("unknown protocol in HTTP response: " - + m_protocol + " line: " + std::string(pos, newline)); + line >> m_status_code; + std::getline(line, m_server_message); + } + else + { + m_method = m_protocol; + std::transform(m_method.begin(), m_method.end(), m_method.begin(), &to_lower); + m_protocol.clear(); + line >> m_path >> m_protocol; + m_status_code = 0; } - line >> m_status_code; - std::getline(line, m_server_message); m_state = read_header; } diff --git a/src/upnp.cpp b/src/upnp.cpp index ad50595a2..87f950b48 100644 --- a/src/upnp.cpp +++ b/src/upnp.cpp @@ -247,6 +247,18 @@ try EXT: Cache-Control:max-age=180 DATE: Fri, 02 Jan 1970 08:10:38 GMT + + a notification looks like this: + + NOTIFY * HTTP/1.1 + Host:239.255.255.250:1900 + NT:urn:schemas-upnp-org:device:MediaServer:1 + NTS:ssdp:alive + Location:http://10.0.3.169:2869/upnphost/udhisapi.dll?content=uuid:c17f0c32-d19b-4938-ae94-65f945c3a26e + USN:uuid:c17f0c32-d19b-4938-ae94-65f945c3a26e::urn:schemas-upnp-org:device:MediaServer:1 + Cache-Control:max-age=900 + Server:Microsoft-Windows-NT/5.1 UPnP/1.0 UPnP-Device-Host/1.0 + */ http_parser p; try @@ -263,12 +275,17 @@ try return; } - if (p.status_code() != 200) + if (p.status_code() != 200 && p.method() != "notify") { #ifdef TORRENT_UPNP_LOGGING - m_log << time_now_string() - << " <== Rootdevice responded with HTTP status: " << p.status_code() - << ". Ignoring device" << std::endl; + if (p.method().empty()) + m_log << time_now_string() + << " <== Device responded with HTTP status: " << p.status_code() + << ". Ignoring device" << std::endl; + else + m_log << time_now_string() + << " <== Device with HTTP method: " << p.method() + << ". Ignoring device" << std::endl; #endif return; } diff --git a/test/test_primitives.cpp b/test/test_primitives.cpp index 99951160a..d328177a4 100644 --- a/test/test_primitives.cpp +++ b/test/test_primitives.cpp @@ -127,6 +127,25 @@ int test_main() TEST_CHECK(parser.header("ext") == ""); TEST_CHECK(parser.header("date") == "Fri, 02 Jan 1970 08:10:38 GMT"); + parser.reset(); + TEST_CHECK(!parser.finished()); + + char const* upnp_notify = + "NOTIFY * HTTP/1.1\r\n" + "Host:239.255.255.250:1900\r\n" + "NT:urn:schemas-upnp-org:device:MediaServer:1\r\n" + "NTS:ssdp:alive\r\n" + "Location:http://10.0.1.15:2353/upnphost/udhisapi.dll?content=uuid:c17f2c31-d19b-4912-af94-651945c8a84e\r\n" + "USN:uuid:c17f0c32-d1db-4be8-ae94-25f94583026e::urn:schemas-upnp-org:device:MediaServer:1\r\n" + "Cache-Control:max-age=900\r\n" + "Server:Microsoft-Windows-NT/5.1 UPnP/1.0 UPnP-Device-Host/1.0\r\n"; + + received = feed_bytes(parser, upnp_notify); + + TEST_CHECK(received == make_tuple(0, int(strlen(upnp_notify)))); + TEST_CHECK(parser.method() == "notify"); + TEST_CHECK(parser.path() == "*"); + // test xml parser char xml1[] = "foobar";