Skip to content

Commit

Permalink
Support comma-separated lists in Connection header
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Godbolt committed Oct 27, 2014
1 parent 17f079a commit f73e608
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 2 deletions.
20 changes: 20 additions & 0 deletions .gdb_history
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
break ConnectionTests.cpp:87
r
step
next
step
next
list
break processHeaders
break Connection.cpp:766
c
next
break Connection.cpp:198
r
c
c
r
c
p headers
q
q
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
/obj
/tags
/.gmock
.gdb_history gdb.txt
109 changes: 109 additions & 0 deletions gdb.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
Reading symbols from bin/tests...done.
Breakpoint 1 at 0x42c3eb: file src/test/c/ConnectionTests.cpp, line 87.
Starting program: /home/mgodbolt/dev/seasocks/bin/tests
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, ConnectionTests_shouldAcceptMultipleConnectionTypes_Test::TestBody (this=<optimized out>) at src/test/c/ConnectionTests.cpp:87
87 connection.handleNewData();
seasocks::Connection::handleNewData (this=0x7fffffffcf90) at src/main/c/Connection.cpp:396
396 void Connection::handleNewData() {
397 switch (_state) {
417 }
399 handleHeaders();
seasocks::Connection::handleHeaders (this=0x7fffffffcf90) at src/main/c/Connection.cpp:419
419 void Connection::handleHeaders() {
420 if (_inBuf.size() < 4) {
size (this=<optimized out>, this=<optimized out>) at /mnt/data/fighome/runtime/gcc/4.9.0-2/include/c++/4.9.0/bits/stl_vector.h:655
655 { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }
seasocks::Connection::handleHeaders (this=0x7fffffffcf90) at src/main/c/Connection.cpp:420
420 if (_inBuf.size() < 4) {
419 void Connection::handleHeaders() {
423 for (size_t i = 0; i <= _inBuf.size() - 4; ++i) {
419 void Connection::handleHeaders() {
423 for (size_t i = 0; i <= _inBuf.size() - 4; ++i) {
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
424 if (_inBuf[i] == '\r' &&
425 _inBuf[i+1] == '\n' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
426 _inBuf[i+2] == '\r' &&
421 return;
422 }
423 for (size_t i = 0; i <= _inBuf.size() - 4; ++i) {
424 if (_inBuf[i] == '\r' &&
425 _inBuf[i+1] == '\n' &&
426 _inBuf[i+2] == '\r' &&
427 _inBuf[i+3] == '\n') {
428 if (!processHeaders(&_inBuf[0], &_inBuf[i + 2])) {
429 closeInternal();
430 return;
Function "processHeaders" not defined.
Make breakpoint pending on future shared library load? (y or [n]) Breakpoint 2 at 0x45739c: file src/main/c/Connection.cpp, line 766.
Continuing.

Breakpoint 2, seasocks::Connection::processHeaders (this=0x7fffffffcf90, first=<optimized out>, last=0x6e440c "\r\n") at src/main/c/Connection.cpp:766
766 if (headers.count("Connection") && headers.count("Upgrade")
768 && caseInsensitiveSame(headers["Upgrade"], "websocket")) {
766 if (headers.count("Connection") && headers.count("Upgrade")
768 && caseInsensitiveSame(headers["Upgrade"], "websocket")) {
766 if (headers.count("Connection") && headers.count("Upgrade")
766 if (headers.count("Connection") && headers.count("Upgrade")
781 _request.reset(new PageRequest(_address, requestUri, verb, std::move(headers)));
783 const EmbeddedContent *embedded = findEmbeddedContent(requestUri);
Breakpoint 3 at 0x45795e: file src/main/c/Connection.cpp, line 198.
The program being debugged has been started already.
Start it from the beginning? (y or n) [Inferior 11543 exited]
Starting program: /home/mgodbolt/dev/seasocks/bin/tests
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, ConnectionTests_shouldAcceptMultipleConnectionTypes_Test::TestBody (this=<optimized out>) at src/test/c/ConnectionTests.cpp:87
87 connection.handleNewData();
Continuing.

Breakpoint 2, seasocks::Connection::processHeaders (this=0x7fffffffcf90, first=<optimized out>, last=0x6e440c "\r\n") at src/main/c/Connection.cpp:766
766 if (headers.count("Connection") && headers.count("Upgrade")
Continuing.
[Inferior 1 (process 11554) exited with code 01]
[Inferior 11554 exited]
Starting program: /home/mgodbolt/dev/seasocks/bin/tests
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, ConnectionTests_shouldAcceptMultipleConnectionTypes_Test::TestBody (this=<optimized out>) at src/test/c/ConnectionTests.cpp:87
87 connection.handleNewData();
Continuing.

Breakpoint 2, seasocks::Connection::processHeaders (this=0x7fffffffcf90, first=<optimized out>, last=0x6e440c "\r\n") at src/main/c/Connection.cpp:766
766 if (headers.count("Connection") && headers.count("Upgrade")
$1 = std::unordered_map with 1 elements = {
["Connection"] = "keep-alive, Upgrade\n\rUpgrade: websocket"
}
A debugging session is active.

Inferior 1 [process 11556] will be killed.

Quit anyway? (y or n) [Inferior 11556 exited]
Reading symbols from bin/tests...done.
12 changes: 11 additions & 1 deletion src/main/c/Connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,16 @@ class PrefixWrapper : public seasocks::Logger {
}
};

bool hasConnectionType(const std::string &connection, const std::string &type) {
for (auto conType : seasocks::split(connection, ',')) {
while (!conType.empty() && isspace(conType[0]))
conType = conType.substr(1);
if (seasocks::caseInsensitiveSame(conType, type))
return true;
}
return false;
}

} // namespace

namespace seasocks {
Expand Down Expand Up @@ -754,7 +764,7 @@ bool Connection::processHeaders(uint8_t* first, uint8_t* last) {
}

if (headers.count("Connection") && headers.count("Upgrade")
&& caseInsensitiveSame(headers["Connection"], "Upgrade")
&& hasConnectionType(headers["Connection"], "Upgrade")
&& caseInsensitiveSame(headers["Upgrade"], "websocket")) {
LS_INFO(_logger, "Websocket request for " << requestUri << "'");
if (verb != Request::Verb::Get) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/c/seasocks/Connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class Connection : public WebSocket {
void setHandler(std::shared_ptr<WebSocket::Handler> handler) {
_webSocketHandler = handler;
}
void handleNewData();

private:
void finalise();
Expand All @@ -98,7 +99,6 @@ class Connection : public WebSocket {
void closeWhenEmpty();
void closeInternal();

void handleNewData();
void handleHeaders();
void handleWebSocketKey3();
void handleWebSocketTextMessage(const char* message);
Expand Down
12 changes: 12 additions & 0 deletions src/test/c/ConnectionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,15 @@ TEST(ConnectionTests, shouldBreakHixieMessagesApartInSameBuffer) {
connection.handleHixieWebSocket();
SUCCEED();
}

TEST(ConnectionTests, shouldAcceptMultipleConnectionTypes) {
sockaddr_in addr = { AF_INET, 0x1234, { 0x01020304 } };
std::shared_ptr<Logger> logger(new IgnoringLogger);
testing::NiceMock<MockServerImpl> mockServer;
Connection connection(logger, mockServer, -1, addr);
const uint8_t message[] = "GET /ws-test HTTP/1.1\r\nConnection: keep-alive, Upgrade\r\nUpgrade: websocket\r\n\r\n";
connection.getInputBuffer().assign(&message[0], &message[sizeof(message)]);
EXPECT_CALL(mockServer, getWebSocketHandler(testing::StrEq("/ws-test")))
.WillOnce(testing::Return(std::shared_ptr<WebSocket::Handler>()));
connection.handleNewData();
}

0 comments on commit f73e608

Please sign in to comment.