updates HTTP parser to use an ordered list of parameters rather than unordered

order matters as far as websocket extension negotation goes
This commit is contained in:
Peter Thorson
2013-04-04 08:18:05 -05:00
parent 73e877f1b8
commit dff7a57e3d
3 changed files with 90 additions and 83 deletions

View File

@@ -236,123 +236,123 @@ BOOST_AUTO_TEST_CASE( extract_parameters ) {
p.clear();
it = extract_parameters(s2.begin(),s2.end(),p);
BOOST_CHECK( it == s2.end() );
BOOST_CHECK( p.size() == 1 );
BOOST_CHECK( p.find("foo") != p.end() );
BOOST_CHECK( p.find("foo")->second.size() == 0 );
BOOST_CHECK_EQUAL( p.size(), 1 );
BOOST_CHECK( p[0].first == "foo" );
BOOST_CHECK_EQUAL( p[0].second.size(), 0 );
p.clear();
it = extract_parameters(s3.begin(),s3.end(),p);
BOOST_CHECK( it == s3.begin()+5 );
BOOST_CHECK( p.size() == 1 );
BOOST_CHECK( p.find("foo") != p.end() );
BOOST_CHECK( p.find("foo")->second.size() == 0 );
BOOST_CHECK_EQUAL( p.size(), 1 );
BOOST_CHECK( p[0].first == "foo" );
BOOST_CHECK_EQUAL( p[0].second.size(), 0 );
p.clear();
it = extract_parameters(s4.begin(),s4.end(),p);
BOOST_CHECK( it == s4.end() );
BOOST_CHECK( p.size() == 1 );
BOOST_CHECK( p.find("foo") != p.end() );
BOOST_CHECK( p.find("foo")->second.size() == 0 );
BOOST_CHECK_EQUAL( p.size(), 1 );
BOOST_CHECK( p[0].first == "foo" );
BOOST_CHECK_EQUAL( p[0].second.size(), 0 );
p.clear();
it = extract_parameters(s5.begin(),s5.end(),p);
BOOST_CHECK( it == s5.end() );
BOOST_CHECK( p.size() == 2 );
BOOST_CHECK( p.find("foo") != p.end() );
BOOST_CHECK( p.find("foo")->second.size() == 0 );
BOOST_CHECK( p.find("bar") != p.end() );
BOOST_CHECK( p.find("bar")->second.size() == 0 );
BOOST_CHECK_EQUAL( p.size(), 2 );
BOOST_CHECK( p[0].first == "foo" );
BOOST_CHECK_EQUAL( p[0].second.size(), 0 );
BOOST_CHECK( p[1].first == "bar" );
BOOST_CHECK_EQUAL( p[1].second.size(), 0 );
p.clear();
it = extract_parameters(s6.begin(),s6.end(),p);
BOOST_CHECK( it == s6.end() );
BOOST_CHECK( p.size() == 1 );
BOOST_CHECK( p.find("foo") != p.end() );
a = p.find("foo")->second;
BOOST_CHECK( a.size() == 1 );
BOOST_CHECK_EQUAL( p.size(), 1 );
BOOST_CHECK( p[0].first == "foo" );
a = p[0].second;
BOOST_CHECK_EQUAL( a.size(), 1 );
BOOST_CHECK( a.find("bar") != a.end() );
BOOST_CHECK( a.find("bar")->second == "" );
BOOST_CHECK_EQUAL( a.find("bar")->second, "" );
p.clear();
it = extract_parameters(s7.begin(),s7.end(),p);
BOOST_CHECK( it == s7.end() );
BOOST_CHECK( p.size() == 2 );
BOOST_CHECK( p.find("foo") != p.end() );
a = p.find("foo")->second;
BOOST_CHECK( a.size() == 1 );
BOOST_CHECK_EQUAL( p.size(), 2 );
BOOST_CHECK( p[0].first == "foo" );
a = p[0].second;
BOOST_CHECK_EQUAL( a.size(), 1 );
BOOST_CHECK( a.find("baz") != a.end() );
BOOST_CHECK( a.find("baz")->second == "" );
BOOST_CHECK( p.find("bar") != p.end() );
a = p.find("bar")->second;
BOOST_CHECK( a.size() == 0 );
BOOST_CHECK_EQUAL( a.find("baz")->second, "" );
BOOST_CHECK( p[1].first == "bar" );
a = p[1].second;
BOOST_CHECK_EQUAL( a.size(), 0 );
p.clear();
it = extract_parameters(s8.begin(),s8.end(),p);
BOOST_CHECK( it == s8.end() );
BOOST_CHECK( p.size() == 1 );
BOOST_CHECK( p.find("foo") != p.end() );
a = p.find("foo")->second;
BOOST_CHECK( a.size() == 2 );
BOOST_CHECK_EQUAL( p.size(), 1 );
BOOST_CHECK( p[0].first == "foo" );
a = p[0].second;
BOOST_CHECK_EQUAL( a.size(), 2 );
BOOST_CHECK( a.find("bar") != a.end() );
BOOST_CHECK( a.find("bar")->second == "" );
BOOST_CHECK_EQUAL( a.find("bar")->second, "" );
BOOST_CHECK( a.find("baz") != a.end() );
BOOST_CHECK( a.find("baz")->second == "" );
BOOST_CHECK_EQUAL( a.find("baz")->second, "" );
p.clear();
it = extract_parameters(s9.begin(),s9.end(),p);
BOOST_CHECK( it == s9.end() );
BOOST_CHECK( p.size() == 1 );
BOOST_CHECK( p.find("foo") != p.end() );
a = p.find("foo")->second;
BOOST_CHECK( a.size() == 1 );
BOOST_CHECK_EQUAL( p.size(), 1 );
BOOST_CHECK( p[0].first == "foo" );
a = p[0].second;
BOOST_CHECK_EQUAL( a.size(), 1 );
BOOST_CHECK( a.find("bar") != a.end() );
BOOST_CHECK( a.find("bar")->second == "baz" );
BOOST_CHECK_EQUAL( a.find("bar")->second, "baz" );
p.clear();
it = extract_parameters(s10.begin(),s10.end(),p);
BOOST_CHECK( it == s10.end() );
BOOST_CHECK( p.size() == 1 );
BOOST_CHECK( p.find("foo") != p.end() );
a = p.find("foo")->second;
BOOST_CHECK( a.size() == 2 );
BOOST_CHECK_EQUAL( p.size(), 1 );
BOOST_CHECK( p[0].first == "foo" );
a = p[0].second;
BOOST_CHECK_EQUAL( a.size(), 2 );
BOOST_CHECK( a.find("bar") != a.end() );
BOOST_CHECK( a.find("bar")->second == "baz" );
BOOST_CHECK_EQUAL( a.find("bar")->second, "baz" );
BOOST_CHECK( a.find("boo") != a.end() );
BOOST_CHECK( a.find("boo")->second == "" );
BOOST_CHECK_EQUAL( a.find("boo")->second, "" );
p.clear();
it = extract_parameters(s11.begin(),s11.end(),p);
BOOST_CHECK( it == s11.end() );
BOOST_CHECK( p.size() == 2 );
BOOST_CHECK( p.find("foo") != p.end() );
a = p.find("foo")->second;
BOOST_CHECK( a.size() == 2 );
BOOST_CHECK_EQUAL( p.size(), 2 );
BOOST_CHECK( p[0].first == "foo" );
a = p[0].second;
BOOST_CHECK_EQUAL( a.size(), 2 );
BOOST_CHECK( a.find("bar") != a.end() );
BOOST_CHECK( a.find("bar")->second == "baz" );
BOOST_CHECK_EQUAL( a.find("bar")->second, "baz" );
BOOST_CHECK( a.find("boo") != a.end() );
BOOST_CHECK( a.find("boo")->second == "" );
a = p.find("bob")->second;
BOOST_CHECK( a.size() == 0 );
BOOST_CHECK_EQUAL( a.find("boo")->second, "" );
a = p[1].second;
BOOST_CHECK_EQUAL( a.size(), 0 );
p.clear();
it = extract_parameters(s12.begin(),s12.end(),p);
BOOST_CHECK( it == s12.end() );
BOOST_CHECK( p.size() == 1 );
BOOST_CHECK( p.find("foo") != p.end() );
a = p.find("foo")->second;
BOOST_CHECK( a.size() == 1 );
BOOST_CHECK_EQUAL( p.size(), 1 );
BOOST_CHECK( p[0].first == "foo" );
a = p[0].second;
BOOST_CHECK_EQUAL( a.size(), 1 );
BOOST_CHECK( a.find("bar") != a.end() );
BOOST_CHECK( a.find("bar")->second == "a b c" );
BOOST_CHECK_EQUAL( a.find("bar")->second, "a b c" );
p.clear();
it = extract_parameters(s13.begin(),s13.end(),p);
BOOST_CHECK( it == s13.end() );
BOOST_CHECK( p.size() == 1 );
BOOST_CHECK( p.find("foo") != p.end() );
a = p.find("foo")->second;
BOOST_CHECK( a.size() == 1 );
BOOST_CHECK_EQUAL( p.size(), 1 );
BOOST_CHECK( p[0].first == "foo" );
a = p[0].second;
BOOST_CHECK_EQUAL( a.size(), 1 );
BOOST_CHECK( a.find("bar") != a.end() );
BOOST_CHECK( a.find("bar")->second == "a \"b\" c" );
BOOST_CHECK_EQUAL( a.find("bar")->second, "a \"b\" c" );
}

View File

@@ -156,8 +156,12 @@ struct parameter {
typedef std::vector<parameter> parameter_list;
*/
//typedef std::map<std::string,std::string> string_map;
//typedef std::vector< std::pair< std::string, attribute_list > > parameter_list;
typedef std::map<std::string,std::string> attribute_list;
typedef std::map<std::string,attribute_list> parameter_list;
//typedef std::map<std::string,attribute_list> parameter_list;
typedef std::vector< std::pair< std::string, attribute_list > > parameter_list;
template <typename InputIterator>
InputIterator extract_attributes(InputIterator begin, InputIterator end,
@@ -286,7 +290,8 @@ InputIterator extract_parameters(InputIterator begin, InputIterator end,
// Safe break point, insert parameter with blank attributes and exit
cursor = http::parser::extract_all_lws(cursor,end);
if (cursor == end) {
parameters[parameter_name] = attributes;
//parameters[parameter_name] = attributes;
parameters.push_back(std::make_pair(parameter_name,attributes));
break;
}
@@ -306,7 +311,8 @@ InputIterator extract_parameters(InputIterator begin, InputIterator end,
}
// insert parameter into output list
parameters[parameter_name] = attributes;
//parameters[parameter_name] = attributes;
parameters.push_back(std::make_pair(parameter_name,attributes));
cursor = http::parser::extract_all_lws(cursor,end);
if (cursor == end) {break;}

View File

@@ -116,26 +116,27 @@ public:
typename request_type::parameter_list::const_iterator it;
// if permessage_compress is implimented, check if it was requested
if (m_permessage_compress.is_implimented()) {
it = p.find("permessage-compress");
if (m_permessage_deflate.is_implimented()) {
err_str_pair neg_ret;
for (it = p.begin(); it != p.end(); ++it) {
// look through each extension, if the key is permessage-deflate
if (it->first == "permessage-deflate") {
std::cout << "mark3: " << std::endl;
neg_ret = m_permessage_deflate.negotiate(it->second);
std::cout << neg_ret.first.message() << " - " << neg_ret.second << std::endl;
if (it != p.end()) {
neg_ret = m_permessage_compress.negotiate(it->second);
if (neg_ret.first) {
// Figure out if this is an error that should halt all
// extension negotiations or simply cause negotiation of
// this specific extension to fail.
std::cout << "permessage-compress negotiation failed: "
<< neg_ret.first << " and message "
<< neg_ret.second << std::endl;
} else {
// Note: this list will need commas if WebSocket++ ever
// supports more than one extension
ret.second += neg_ret.second;
if (neg_ret.first) {
// Figure out if this is an error that should halt all
// extension negotiations or simply cause negotiation of
// this specific extension to fail.
std::cout << "permessage-compress negotiation failed: "
<< neg_ret.first.message() << std::endl;
} else {
// Note: this list will need commas if WebSocket++ ever
// supports more than one extension
ret.second += neg_ret.second;
continue;
}
}
}
}