diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/Ice/HttpParser.cpp | 40 | ||||
-rw-r--r-- | cpp/src/Ice/HttpParser.h | 8 | ||||
-rw-r--r-- | cpp/src/Ice/WSTransceiver.cpp | 12 | ||||
-rw-r--r-- | cpp/test/Ice/info/AllTests.cpp | 18 | ||||
-rw-r--r-- | cpp/test/Ice/info/TestI.cpp | 13 |
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; } - - |