better upnp support

This commit is contained in:
Arvid Norberg
2007-09-20 23:25:40 +00:00
parent 587d40e1ae
commit 053f499ec6
4 changed files with 55 additions and 9 deletions

View File

@@ -73,6 +73,8 @@ namespace libtorrent
T header(char const* key) const; T header(char const* key) const;
std::string const& protocol() const { return m_protocol; } std::string const& protocol() const { return m_protocol; }
int status_code() const { return m_status_code; } 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; } std::string message() const { return m_server_message; }
buffer::const_interval get_body() const; buffer::const_interval get_body() const;
bool header_finished() const { return m_state == read_body; } bool header_finished() const { return m_state == read_body; }
@@ -85,6 +87,8 @@ namespace libtorrent
private: private:
int m_recv_pos; int m_recv_pos;
int m_status_code; int m_status_code;
std::string m_method;
std::string m_path;
std::string m_protocol; std::string m_protocol;
std::string m_server_message; std::string m_server_message;

View File

@@ -148,13 +148,19 @@ namespace libtorrent
pos = newline; pos = newline;
line >> m_protocol; 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: " line >> m_status_code;
+ m_protocol + " line: " + std::string(pos, newline)); 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; m_state = read_header;
} }

View File

@@ -247,6 +247,18 @@ try
EXT: EXT:
Cache-Control:max-age=180 Cache-Control:max-age=180
DATE: Fri, 02 Jan 1970 08:10:38 GMT 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; http_parser p;
try try
@@ -263,12 +275,17 @@ try
return; return;
} }
if (p.status_code() != 200) if (p.status_code() != 200 && p.method() != "notify")
{ {
#ifdef TORRENT_UPNP_LOGGING #ifdef TORRENT_UPNP_LOGGING
m_log << time_now_string() if (p.method().empty())
<< " <== Rootdevice responded with HTTP status: " << p.status_code() m_log << time_now_string()
<< ". Ignoring device" << std::endl; << " <== 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 #endif
return; return;
} }

View File

@@ -127,6 +127,25 @@ int test_main()
TEST_CHECK(parser.header<std::string>("ext") == ""); TEST_CHECK(parser.header<std::string>("ext") == "");
TEST_CHECK(parser.header<std::string>("date") == "Fri, 02 Jan 1970 08:10:38 GMT"); TEST_CHECK(parser.header<std::string>("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 // test xml parser
char xml1[] = "<a>foo<b/>bar</a>"; char xml1[] = "<a>foo<b/>bar</a>";