mirror of https://github.com/aria2/aria2
WebSocket: Check keyword string in comma separeted values in HTTP
header field.pull/16/merge
parent
c648ca0c5c
commit
1e0068e4d4
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue