WebSocket: Check keyword string in comma separeted values in HTTP

header field.
pull/16/merge
Tatsuhiro Tsujikawa 2012-04-08 19:00:07 +09:00
parent c648ca0c5c
commit 1e0068e4d4
4 changed files with 50 additions and 4 deletions

View File

@ -293,4 +293,28 @@ const std::string& HttpHeader::getRequestPath() const
return requestPath_;
}
bool HttpHeader::fieldContains(const std::string& name,
const std::string& value)
{
std::pair<std::multimap<std::string, std::string>::const_iterator,
std::multimap<std::string, std::string>::const_iterator> range =
equalRange(name);
for(std::multimap<std::string, std::string>::const_iterator i = range.first;
i != range.second; ++i) {
std::vector<Scip> values;
util::splitIter((*i).second.begin(), (*i).second.end(),
std::back_inserter(values),
',',
true // doStrip
);
for(std::vector<Scip>::const_iterator j = values.begin(),
eoj = values.end(); j != eoj; ++j) {
if(util::strieq((*j).first, (*j).second, value.begin(), value.end())) {
return true;
}
}
}
return false;
}
} // namespace aria2

View File

@ -66,6 +66,7 @@ public:
HttpHeader();
~HttpHeader();
// For all methods, use lowercased header field name.
void put(const std::string& name, const std::string& value);
bool defined(const std::string& name) const;
const std::string& find(const std::string& name) const;
@ -121,6 +122,10 @@ public:
// Clears table_. responseStatus_ and version_ are unchanged.
void clearField();
// Returns true if heder field |name| contains |value|. This method
// assumes the values of the header field is delimited by ','.
bool fieldContains(const std::string& name, const std::string& value);
static const std::string LOCATION;
static const std::string TRANSFER_ENCODING;
static const std::string CONTENT_ENCODING;

View File

@ -174,10 +174,8 @@ bool HttpServerCommand::execute()
e_->setNoWait(true);
return true;
}
const std::string& upgradeHd = header->find("upgrade");
const std::string& connectionHd = header->find("connection");
if(util::strieq(upgradeHd.begin(), upgradeHd.end(), "websocket") &&
util::strieq(connectionHd.begin(), connectionHd.end(), "upgrade")) {
if(header->fieldContains("upgrade", "websocket") &&
header->fieldContains("connection", "upgrade")) {
#ifdef ENABLE_WEBSOCKET
int status = websocketHandshake(header);
Command* command;

View File

@ -14,6 +14,7 @@ class HttpHeaderTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testFindAll);
CPPUNIT_TEST(testClearField);
CPPUNIT_TEST(testFill);
CPPUNIT_TEST(testFieldContains);
CPPUNIT_TEST_SUITE_END();
public:
@ -21,6 +22,7 @@ public:
void testFindAll();
void testClearField();
void testFill();
void testFieldContains();
};
@ -175,4 +177,21 @@ void HttpHeaderTest::testFill()
h.findAll("duplicate")[1]);
}
void HttpHeaderTest::testFieldContains()
{
HttpHeader h;
h.put("connection", "Keep-Alive, Upgrade");
h.put("upgrade", "WebSocket");
h.put("sec-websocket-version", "13");
h.put("sec-websocket-version", "8, 7");
CPPUNIT_ASSERT(h.fieldContains("connection", "upgrade"));
CPPUNIT_ASSERT(h.fieldContains("connection", "keep-alive"));
CPPUNIT_ASSERT(!h.fieldContains("connection", "close"));
CPPUNIT_ASSERT(h.fieldContains("upgrade", "websocket"));
CPPUNIT_ASSERT(!h.fieldContains("upgrade", "spdy"));
CPPUNIT_ASSERT(h.fieldContains("sec-websocket-version", "13"));
CPPUNIT_ASSERT(h.fieldContains("sec-websocket-version", "8"));
CPPUNIT_ASSERT(!h.fieldContains("sec-websocket-version", "6"));
}
} // namespace aria2