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