@@ -104,7 +104,7 @@ int WebSocketImpl::sendBytes(const void* buffer, int length, int flags)
104104}
105105
106106
107- int WebSocketImpl::receiveBytes ( void * buffer, int length, int )
107+ int WebSocketImpl::receiveHeader ( char mask[ 4 ], bool & useMask )
108108{
109109 char header[MAX_HEADER_LENGTH ];
110110 int n = receiveNBytes (header, 2 );
@@ -114,82 +114,100 @@ int WebSocketImpl::receiveBytes(void* buffer, int length, int)
114114 return n;
115115 }
116116 poco_assert (n == 2 );
117+ Poco::UInt8 flags = static_cast <Poco::UInt8>(header[0 ]);
118+ _frameFlags = flags;
117119 Poco::UInt8 lengthByte = static_cast <Poco::UInt8>(header[1 ]);
118- int maskOffset = 0 ;
119- if (lengthByte & FRAME_FLAG_MASK ) maskOffset += 4 ;
120+ useMask = ((lengthByte & FRAME_FLAG_MASK ) ! = 0 ) ;
121+ int payloadLength ;
120122 lengthByte &= 0x7f ;
121- if (lengthByte > 0 || maskOffset > 0 )
123+ if (lengthByte == 127 )
122124 {
123- if (lengthByte + 2 + maskOffset < MAX_HEADER_LENGTH )
125+ n = receiveNBytes (header + 2 , 8 );
126+ if (n <= 0 )
124127 {
125- n = receiveNBytes (header + 2 , lengthByte + maskOffset);
128+ _frameFlags = 0 ;
129+ return n;
126130 }
127- else
128- {
129- n = receiveNBytes (header + 2 , MAX_HEADER_LENGTH - 2 );
130- }
131- if (n <= 0 ) throw WebSocketException (" Incomplete header received" , WebSocket::WS_ERR_INCOMPLETE_FRAME );
132- n += 2 ;
133- }
134- Poco::MemoryInputStream istr (header, n);
135- Poco::BinaryReader reader (istr, Poco::BinaryReader::NETWORK_BYTE_ORDER );
136- Poco::UInt8 flags;
137- char mask[4 ];
138- reader >> flags >> lengthByte;
139- _frameFlags = flags;
140- int payloadLength = 0 ;
141- int payloadOffset = 2 ;
142- if ((lengthByte & 0x7f ) == 127 )
143- {
131+ Poco::MemoryInputStream istr (header + 2 , 8 );
132+ Poco::BinaryReader reader (istr, Poco::BinaryReader::NETWORK_BYTE_ORDER );
144133 Poco::UInt64 l;
145134 reader >> l;
146- if (l > length) throw WebSocketException (Poco::format (" Insufficient buffer for payload size %Lu" , l), WebSocket::WS_ERR_PAYLOAD_TOO_BIG );
147135 payloadLength = static_cast <int >(l);
148- payloadOffset += 8 ;
149- }
150- else if ((lengthByte & 0x7f ) == 126 )
136+ } else if (lengthByte == 126 )
151137 {
138+ n = receiveNBytes (header + 2 , 2 );
139+ if (n <= 0 )
140+ {
141+ _frameFlags = 0 ;
142+ return n;
143+ }
144+ Poco::MemoryInputStream istr (header + 2 , 2 );
145+ Poco::BinaryReader reader (istr, Poco::BinaryReader::NETWORK_BYTE_ORDER );
152146 Poco::UInt16 l;
153147 reader >> l;
154- if (l > length) throw WebSocketException (Poco::format (" Insufficient buffer for payload size %hu" , l), WebSocket::WS_ERR_PAYLOAD_TOO_BIG );
155148 payloadLength = static_cast <int >(l);
156- payloadOffset += 2 ;
157149 }
158150 else
159151 {
160- Poco::UInt8 l = lengthByte & 0x7f ;
161- if (l > length) throw WebSocketException (Poco::format (" Insufficient buffer for payload size %u" , unsigned (l)), WebSocket::WS_ERR_PAYLOAD_TOO_BIG );
162- payloadLength = static_cast <int >(l);
163- }
164- if (lengthByte & FRAME_FLAG_MASK )
165- {
166- reader.readRaw (mask, 4 );
167- payloadOffset += 4 ;
152+ payloadLength = lengthByte;
168153 }
169- int received = 0 ;
170- if (payloadOffset < n)
171- {
172- std::memcpy (buffer, header + payloadOffset, n - payloadOffset);
173- received = n - payloadOffset;
174- }
175- if (received < payloadLength)
154+
155+ if (useMask)
176156 {
177- n = receiveNBytes (reinterpret_cast <char *>(buffer) + received, payloadLength - received);
178- if (n <= 0 ) throw WebSocketException (" Incomplete frame received" , WebSocket::WS_ERR_INCOMPLETE_FRAME );
179- received += n;
157+ n = receiveNBytes (mask, 4 );
158+ if (n <= 0 )
159+ {
160+ _frameFlags = 0 ;
161+ return n;
162+ }
180163 }
181- if (lengthByte & FRAME_FLAG_MASK )
164+
165+ return payloadLength;
166+ }
167+
168+
169+ int WebSocketImpl::receivePayload (char *buffer, int payloadLength, char mask[4 ], bool useMask)
170+ {
171+ int received = receiveNBytes (reinterpret_cast <char *>(buffer), payloadLength);
172+ if (received <= 0 ) throw WebSocketException (" Incomplete frame received" , WebSocket::WS_ERR_INCOMPLETE_FRAME );
173+
174+ if (useMask)
182175 {
183- char * p = reinterpret_cast <char *>(buffer);
184176 for (int i = 0 ; i < received; i++)
185177 {
186- p [i] ^= mask[i % 4 ];
178+ buffer [i] ^= mask[i % 4 ];
187179 }
188180 }
189181 return received;
190182}
191183
192184
185+ int WebSocketImpl::receiveBytes (void * buffer, int length, int )
186+ {
187+ char mask[4 ];
188+ bool useMask;
189+ int payloadLength = receiveHeader (mask, useMask);
190+ if (payloadLength <= 0 )
191+ return payloadLength;
192+ if (payloadLength > length)
193+ throw WebSocketException (Poco::format (" Insufficient buffer for payload size %hu" , payloadLength), WebSocket::WS_ERR_PAYLOAD_TOO_BIG );
194+ return receivePayload (reinterpret_cast <char *>(buffer), payloadLength, mask, useMask);
195+ }
196+
197+
198+ int WebSocketImpl::receiveBytes (Poco::Buffer<char >& buffer, int )
199+ {
200+ char mask[4 ];
201+ bool useMask;
202+ int payloadLength = receiveHeader (mask, useMask);
203+ if (payloadLength <= 0 )
204+ return payloadLength;
205+ int oldSize = buffer.size ();
206+ buffer.resize (oldSize + payloadLength);
207+ return receivePayload (buffer.begin () + oldSize, payloadLength, mask, useMask);
208+ }
209+
210+
193211int WebSocketImpl::receiveNBytes (void * buffer, int bytes)
194212{
195213 int received = _pStreamSocketImpl->receiveBytes (reinterpret_cast <char *>(buffer), bytes);
0 commit comments