diff options
author | Benoit Foucher <benoit@zeroc.com> | 2014-11-13 11:47:10 +0100 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2014-11-13 11:47:10 +0100 |
commit | 9cb2519efe1c9e56c25f2dcdcdb8aaa26ddf2969 (patch) | |
tree | fb419cfcaab0d8aff7ef211db4a6eddbac31f8d0 /cpp/src/Ice/WSTransceiver.cpp | |
parent | remove timeout.jar from git (diff) | |
download | ice-9cb2519efe1c9e56c25f2dcdcdb8aaa26ddf2969.tar.bz2 ice-9cb2519efe1c9e56c25f2dcdcdb8aaa26ddf2969.tar.xz ice-9cb2519efe1c9e56c25f2dcdcdb8aaa26ddf2969.zip |
Fixed ICE-5852: added support for WS continuation frames
Diffstat (limited to 'cpp/src/Ice/WSTransceiver.cpp')
-rw-r--r-- | cpp/src/Ice/WSTransceiver.cpp | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/cpp/src/Ice/WSTransceiver.cpp b/cpp/src/Ice/WSTransceiver.cpp index 2e97aa219b4..3f5c3a83f43 100644 --- a/cpp/src/Ice/WSTransceiver.cpp +++ b/cpp/src/Ice/WSTransceiver.cpp @@ -579,7 +579,6 @@ IceInternal::WSTransceiver::read(Buffer& buf, bool& hasMoreData) { s = _delegate->read(buf, hasMoreData); } - } else { @@ -817,7 +816,7 @@ IceInternal::WSTransceiver::WSTransceiver(const ProtocolInstancePtr& instance, c _parser(new HttpParser), _readState(ReadStateOpcode), _readBufferSize(1024), - _readLastFrame(false), + _readLastFrame(true), _readOpCode(0), _readHeaderLength(0), _readPayloadLength(0), @@ -851,7 +850,7 @@ IceInternal::WSTransceiver::WSTransceiver(const ProtocolInstancePtr& instance, c _parser(new HttpParser), _readState(ReadStateOpcode), _readBufferSize(1024), - _readLastFrame(false), + _readLastFrame(true), _readOpCode(0), _readHeaderLength(0), _readPayloadLength(0), @@ -1119,9 +1118,30 @@ IceInternal::WSTransceiver::preRead(Buffer& buf) // opcode. // unsigned char ch = static_cast<unsigned char>(*_readI++); - _readLastFrame = (ch & FLAG_FINAL) == FLAG_FINAL; _readOpCode = ch & 0xf; + // + // Remember if last frame if we're going to read a data or + // continuation frame, this is only for protocol + // correctness checking purpose. + // + if(_readOpCode == OP_DATA) + { + if(!_readLastFrame) + { + throw ProtocolException(__FILE__, __LINE__, "invalid data frame, no FIN on previous frame"); + } + _readLastFrame = (ch & FLAG_FINAL) == FLAG_FINAL; + } + else if(_readOpCode == OP_CONT) + { + if(_readLastFrame) + { + throw ProtocolException(__FILE__, __LINE__, "invalid continuation frame, previous frame FIN set"); + } + _readLastFrame = (ch & FLAG_FINAL) == FLAG_FINAL; + } + ch = static_cast<unsigned char>(*_readI++); // @@ -1203,33 +1223,27 @@ IceInternal::WSTransceiver::preRead(Buffer& buf) switch(_readOpCode) { - case OP_CONT: // Continuation frame - { - // TODO: Add support for continuation frames? - throw ProtocolException(__FILE__, __LINE__, "continuation frames not supported"); - } case OP_TEXT: // Text frame { throw ProtocolException(__FILE__, __LINE__, "text frames not supported"); } case OP_DATA: // Data frame + case OP_CONT: // Continuation frame { if(_instance->traceLevel() >= 2) { Trace out(_instance->logger(), _instance->traceCategory()); - out << "received " << protocol() << " data frame with payload length of " << _readPayloadLength; + out << "received " << protocol() << (_readOpCode == OP_DATA ? " data" : " continuation"); + out << " frame with payload length of " << _readPayloadLength; out << " bytes\n" << toString(); } - if(!_readLastFrame) - { - throw ProtocolException(__FILE__, __LINE__, "continuation frames not supported"); - } if(_readPayloadLength <= 0) { throw ProtocolException(__FILE__, __LINE__, "payload length is 0"); } _readState = ReadStatePayload; + _readFrameStart = buf.i; break; } case OP_CLOSE: // Connection close @@ -1384,7 +1398,7 @@ IceInternal::WSTransceiver::postRead(Buffer& buf) // Unmask the data we just read. // IceInternal::Buffer::Container::iterator p = _readStart; - for(size_t n = _readStart - buf.b.begin(); p < buf.i; ++p, ++n) + for(size_t n = _readStart - _readFrameStart; p < buf.i; ++p, ++n) { *p ^= _readMask[n % 4]; } |