fixed error handling and added support for relative http redirects (which aren't allowed by the standard)

This commit is contained in:
Arvid Norberg 2008-05-18 04:48:06 +00:00
parent 031cfe09da
commit b952d85734
4 changed files with 39 additions and 8 deletions

View File

@ -158,6 +158,7 @@ private:
bool m_called;
std::string m_hostname;
std::string m_port;
std::string m_url;
// the current download limit, in bytes per second
// 0 is unlimited.

View File

@ -114,6 +114,7 @@ void http_connection::get(std::string const& url, time_duration timeout, int pri
"\r\n";
sendbuffer = headers.str();
m_url = url;
start(hostname, boost::lexical_cast<std::string>(port), timeout, prio
, ps, ssl, handle_redirects, bind_addr);
}
@ -417,17 +418,44 @@ void http_connection::on_read(error_code const& e
if (code >= 300 && code < 400)
{
// attempt a redirect
std::string const& url = m_parser.header("location");
if (url.empty())
std::string const& location = m_parser.header("location");
if (location.empty())
{
// missing location header
callback(e);
callback(asio::error::fault);
close();
return;
}
error_code ec;
m_sock.close(ec);
get(url, m_timeout, m_priority, &m_proxy, m_redirects - 1);
using boost::tuples::ignore;
char const* error;
boost::tie(ignore, ignore, ignore, ignore, ignore, error)
= parse_url_components(location);
if (error == 0)
{
get(location, m_timeout, m_priority, &m_proxy, m_redirects - 1);
}
else
{
// some broken web servers send out relative paths
// in the location header.
std::string url = m_url;
// remove the leaf filename
std::size_t i = url.find_last_of('/');
if (i == std::string::npos)
{
url += '/';
}
else
{
url.resize(i + 1);
}
url += location;
get(url, m_timeout, m_priority, &m_proxy, m_redirects - 1);
}
return;
}

View File

@ -97,10 +97,11 @@ void start_web_server(int port, bool ssl)
"server.range-requests = \"enable\"\n"
"server.port = " << port << "\n"
"server.pid-file = \"./lighty" << port << ".pid\"\n"
"url.redirect = (\"^/redirect$\" => \""
<< (ssl?"https":"http") << "://127.0.0.1:" << port << "/test_file\", "
"\"^/infinite_redirect$\" => \""
<< (ssl?"https":"http") << "://127.0.0.1:" << port << "/infinite_redirect\")\n"
"url.redirect = ("
"\"^/redirect$\" => \"" << (ssl?"https":"http") << "://127.0.0.1:" << port << "/test_file\""
", \"^/infinite_redirect$\" => \"" << (ssl?"https":"http") << "://127.0.0.1:" << port << "/infinite_redirect\""
", \"^/relative/redirect$\" => \"../test_file\""
")\n"
"$HTTP[\"url\"] == \"/test_file.gz\" {\n"
" setenv.add-response-header = ( \"Content-Encoding\" => \"gzip\" )\n"
"# mimetype.assign = ()\n"

View File

@ -104,6 +104,7 @@ void run_suite(std::string const& protocol, proxy_settings const& ps)
<< " proxy **********************\n" << std::endl;
typedef boost::optional<error_code> err;
run_test(protocol + "://127.0.0.1:8001/relative/redirect", 3216, 200, 2, error_code(), ps);
run_test(protocol + "://127.0.0.1:8001/redirect", 3216, 200, 2, error_code(), ps);
run_test(protocol + "://127.0.0.1:8001/infinite_redirect", 0, 301, 6, error_code(), ps);
run_test(protocol + "://127.0.0.1:8001/test_file", 3216, 200, 1, error_code(), ps);