summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2015-02-16 12:44:31 +0100
committerBenoit Foucher <benoit@zeroc.com>2015-02-16 12:44:31 +0100
commitc4b35b30b99898e9ef1ae44655011b3575d634a3 (patch)
tree87879b8d66e9a85bb0c9022731cff7fe72756183 /cpp
parentICE-6307 - Fixed ruby makefile to add ruby static lib path to linker for cust... (diff)
downloadice-c4b35b30b99898e9ef1ae44655011b3575d634a3.tar.bz2
ice-c4b35b30b99898e9ef1ae44655011b3575d634a3.tar.xz
ice-c4b35b30b99898e9ef1ae44655011b3575d634a3.zip
Fixed ICE-6225 - Added headers attribute to WSConnectionInfo
Diffstat (limited to 'cpp')
-rw-r--r--cpp/src/Ice/HttpParser.cpp40
-rw-r--r--cpp/src/Ice/HttpParser.h8
-rw-r--r--cpp/src/Ice/WSTransceiver.cpp12
-rw-r--r--cpp/test/Ice/info/AllTests.cpp18
-rw-r--r--cpp/test/Ice/info/TestI.cpp13
5 files changed, 62 insertions, 29 deletions
diff --git a/cpp/src/Ice/HttpParser.cpp b/cpp/src/Ice/HttpParser.cpp
index 4c18f5ecf82..7030d187f0a 100644
--- a/cpp/src/Ice/HttpParser.cpp
+++ b/cpp/src/Ice/HttpParser.cpp
@@ -258,10 +258,9 @@ IceInternal::HttpParser::parse(const Ice::Byte* begin, const Ice::Byte* end)
{
throw WebSocketException("malformed header");
}
- HeaderMap::iterator q = _headers.find(_headerName);
+ HeaderFields::iterator q = _headers.find(_headerName);
assert(q != _headers.end());
- string newValue = q->second + " " + string(start, p);
- _headers[_headerName] = newValue;
+ q->second.second = q->second.second + " " + string(start, p);
_state = c == CR ? StateHeaderFieldLF : StateHeaderFieldStart;
}
else
@@ -301,13 +300,13 @@ IceInternal::HttpParser::parse(const Ice::Byte* begin, const Ice::Byte* end)
if(_headerName.empty())
{
_headerName = IceUtilInternal::toLower(string(start, p));
- HeaderMap::iterator q = _headers.find(_headerName);
+ HeaderFields::iterator q = _headers.find(_headerName);
//
// Add a placeholder entry if necessary.
//
if(q == _headers.end())
{
- _headers[_headerName] = "";
+ _headers[_headerName] = make_pair(string(start, p), "");
}
}
@@ -362,14 +361,18 @@ IceInternal::HttpParser::parse(const Ice::Byte* begin, const Ice::Byte* end)
assert(c == CR || c == LF);
if(p > start)
{
- HeaderMap::iterator q = _headers.find(_headerName);
- if(q == _headers.end() || q->second.empty())
+ HeaderFields::iterator q = _headers.find(_headerName);
+ if(q == _headers.end())
+ {
+ throw WebSocketException("malformed header");
+ }
+ else if(q->second.second.empty())
{
- _headers[_headerName] = string(start, p);
+ q->second.second = string(start, p);
}
else
{
- _headers[_headerName] = q->second + ", " + string(start, p);
+ q->second.second = q->second.second + ", " + string(start, p);
}
}
@@ -663,18 +666,27 @@ IceInternal::HttpParser::reason() const
bool
IceInternal::HttpParser::getHeader(const string& name, string& value, bool toLower) const
{
- HeaderMap::const_iterator q = _headers.find(IceUtilInternal::toLower(name));
+ HeaderFields::const_iterator q = _headers.find(IceUtilInternal::toLower(name));
if(q != _headers.end())
{
- value = toLower ? IceUtilInternal::toLower(IceUtilInternal::trim(q->second)) : IceUtilInternal::trim(q->second);
+ value = IceUtilInternal::trim(q->second.second);
+ if(toLower)
+ {
+ value = IceUtilInternal::toLower(value);
+ }
return true;
}
return false;
}
-const HttpParser::HeaderMap&
-IceInternal::HttpParser::headers() const
+map<string, string>
+IceInternal::HttpParser::getHeaders() const
{
- return _headers;
+ map<string, string> headers;
+ for(HeaderFields::const_iterator q = _headers.begin(); q != _headers.end(); ++q)
+ {
+ headers.insert(make_pair(q->second.first, IceUtilInternal::trim(q->second.second)));
+ }
+ return headers;
}
diff --git a/cpp/src/Ice/HttpParser.h b/cpp/src/Ice/HttpParser.h
index d1141a719b7..65500771fcd 100644
--- a/cpp/src/Ice/HttpParser.h
+++ b/cpp/src/Ice/HttpParser.h
@@ -19,7 +19,7 @@ namespace IceInternal
std::vector<unsigned char> calcSHA1(const std::vector<unsigned char>&);
-typedef std::map<std::string, std::string> HeaderFields;
+typedef std::map<std::string, std::pair<std::string, std::string> > HeaderFields;
class WebSocketException
{
@@ -58,9 +58,7 @@ public:
bool getHeader(const std::string&, std::string&, bool) const;
- typedef std::map<std::string, std::string> HeaderMap;
-
- const HeaderMap& headers() const;
+ std::map<std::string, std::string> getHeaders() const;
private:
@@ -69,7 +67,7 @@ private:
std::string _method;
std::string _uri;
- HeaderMap _headers;
+ HeaderFields _headers;
std::string _headerName;
int _versionMajor;
diff --git a/cpp/src/Ice/WSTransceiver.cpp b/cpp/src/Ice/WSTransceiver.cpp
index c333824a9a5..4f17d4e8b81 100644
--- a/cpp/src/Ice/WSTransceiver.cpp
+++ b/cpp/src/Ice/WSTransceiver.cpp
@@ -507,7 +507,7 @@ IceInternal::WSTransceiver::write(Buffer& buf)
{
return s;
}
- }
+ }
else if(_incoming && !buf.b.empty() && _writeState == WriteStatePayload)
{
SocketOperation s = _delegate->write(buf);
@@ -804,6 +804,7 @@ IceInternal::WSTransceiver::getInfo() const
info->localPort = di->localPort;
info->remoteAddress = di->remoteAddress;
info->remotePort = di->remotePort;
+ info->headers = _parser->getHeaders();
return info;
}
@@ -836,7 +837,7 @@ IceInternal::WSTransceiver::WSTransceiver(const ProtocolInstancePtr& instance, c
_closingInitiator(false),
_closingReason(CLOSURE_NORMAL)
{
- //
+ //
// Use 1KB read and 16KB write buffer sizes. We use 16KB for the
// write buffer size because all the data needs to be copied to
// the write buffer for the purpose of masking. A 16KB buffer
@@ -865,7 +866,7 @@ IceInternal::WSTransceiver::WSTransceiver(const ProtocolInstancePtr& instance, c
_closingInitiator(false),
_closingReason(CLOSURE_NORMAL)
{
- //
+ //
// Use 1KB read and write buffer sizes.
//
}
@@ -1497,7 +1498,7 @@ IceInternal::WSTransceiver::preWrite(Buffer& buf)
// For an outgoing connection, each message must be masked with a random
// 32-bit value, so we copy the entire message into the internal buffer
// for writing. For incoming connections, we just copy the start of the
- // message in the internal buffer after the hedaer. If the message is
+ // message in the internal buffer after the hedaer. If the message is
// larger, the reminder is sent directly from the message buffer to avoid
// copying.
//
@@ -1508,7 +1509,7 @@ IceInternal::WSTransceiver::preWrite(Buffer& buf)
{
_writeBuffer.i = _writeBuffer.b.begin();
}
-
+
size_t n = buf.i - buf.b.begin();
for(; n < buf.b.size() && _writeBuffer.i < _writeBuffer.b.end(); ++_writeBuffer.i, ++n)
{
@@ -1712,4 +1713,3 @@ IceInternal::WSTransceiver::prepareWriteHeader(Byte opCode, IceInternal::Buffer:
_writeBuffer.i += sizeof(_writeMask);
}
}
-
diff --git a/cpp/test/Ice/info/AllTests.cpp b/cpp/test/Ice/info/AllTests.cpp
index dd0acba9168..da312fb83d8 100644
--- a/cpp/test/Ice/info/AllTests.cpp
+++ b/cpp/test/Ice/info/AllTests.cpp
@@ -177,6 +177,23 @@ allTests(const Ice::CommunicatorPtr& communicator)
os << info->remotePort;
test(ctx["localPort"] == os.str());
+ if(base->ice_getConnection()->type() == "ws" || base->ice_getConnection()->type() == "wss")
+ {
+ Ice::WSConnectionInfoPtr wsinfo = Ice::WSConnectionInfoPtr::dynamicCast(info);
+ test(wsinfo);
+
+ test(wsinfo->headers["Upgrade"] == "websocket");
+ test(wsinfo->headers["Connection"] == "Upgrade");
+ test(wsinfo->headers["Sec-WebSocket-Protocol"] == "ice.zeroc.com");
+ test(wsinfo->headers.find("Sec-WebSocket-Accept") != wsinfo->headers.end());
+
+ test(ctx["ws.Upgrade"] == "websocket");
+ test(ctx["ws.Connection"] == "Upgrade");
+ test(ctx["ws.Sec-WebSocket-Protocol"] == "ice.zeroc.com");
+ test(ctx["ws.Sec-WebSocket-Version"] == "13");
+ test(ctx.find("ws.Sec-WebSocket-Key") != ctx.end());
+ }
+
info = Ice::IPConnectionInfoPtr::dynamicCast(base->ice_datagram()->ice_getConnection()->getInfo());
test(!info->incoming);
test(info->adapterName.empty());
@@ -187,7 +204,6 @@ allTests(const Ice::CommunicatorPtr& communicator)
test(info->remoteAddress == defaultHost);
test(info->localAddress == defaultHost);
}
-
}
cout << "ok" << endl;
diff --git a/cpp/test/Ice/info/TestI.cpp b/cpp/test/Ice/info/TestI.cpp
index 4b8c97b7556..ba63bf96744 100644
--- a/cpp/test/Ice/info/TestI.cpp
+++ b/cpp/test/Ice/info/TestI.cpp
@@ -63,7 +63,7 @@ TestI::getConnectionInfoAsContext(const Ice::Current& c)
ctx["adapterName"] = info->adapterName;
ctx["incoming"] = info->incoming ? "true" : "false";
ostringstream os;
-
+
Ice::IPConnectionInfoPtr ipinfo = Ice::IPConnectionInfoPtr::dynamicCast(info);
test(ipinfo);
ctx["localAddress"] = ipinfo->localAddress;
@@ -75,7 +75,14 @@ TestI::getConnectionInfoAsContext(const Ice::Current& c)
os << ipinfo->remotePort;
ctx["remotePort"] = os.str();
+ Ice::WSConnectionInfoPtr wsinfo = Ice::WSConnectionInfoPtr::dynamicCast(info);
+ if(wsinfo)
+ {
+ for(Ice::HeaderDict::const_iterator p = wsinfo->headers.begin(); p != wsinfo->headers.end(); ++p)
+ {
+ ctx["ws." + p->first] = p->second;
+ }
+ }
+
return ctx;
}
-
-