Index: Source/modules/websockets/WebSocketFrame.cpp |
diff --git a/Source/modules/websockets/WebSocketFrame.cpp b/Source/modules/websockets/WebSocketFrame.cpp |
index 30f7acaebf309ba3bf229fb022c83f6b532866bf..6f7856630c18b7a8b6467133e5499f476f109cc2 100644 |
--- a/Source/modules/websockets/WebSocketFrame.cpp |
+++ b/Source/modules/websockets/WebSocketFrame.cpp |
@@ -24,165 +24,8 @@ |
#include "modules/websockets/WebSocketFrame.h" |
-#include "wtf/CryptographicallyRandomNumber.h" |
-#include "wtf/MathExtras.h" |
- |
namespace blink { |
-// Constants for hybi-10 frame format. |
-// These are bitmasks for frame composition / decomposition. |
-// Do not mistake these constants for the flags given to the WebSocketFrame constructor. |
-const unsigned char finalBit = 0x80; |
-const unsigned char compressBit = 0x40; |
-const unsigned char reserved2Bit = 0x20; |
-const unsigned char reserved3Bit = 0x10; |
-const unsigned char opCodeMask = 0xF; |
-const unsigned char maskBit = 0x80; |
-const unsigned char payloadLengthMask = 0x7F; |
-const size_t maxPayloadLengthWithoutExtendedLengthField = 125; |
-const size_t payloadLengthWithTwoByteExtendedLengthField = 126; |
-const size_t payloadLengthWithEightByteExtendedLengthField = 127; |
-const size_t maskingKeyWidthInBytes = 4; |
- |
-bool WebSocketFrame::needsExtendedLengthField(size_t payloadLength) |
-{ |
- return payloadLength > maxPayloadLengthWithoutExtendedLengthField; |
-} |
- |
-WebSocketFrame::ParseFrameResult WebSocketFrame::parseFrame(char* data, size_t dataLength, WebSocketFrame& frame, const char*& frameEnd, String& errorString) |
-{ |
- char* p = data; |
- const char* bufferEnd = data + dataLength; |
- |
- if (dataLength < 2) |
- return FrameIncomplete; |
- |
- unsigned char firstByte = *p++; |
- unsigned char secondByte = *p++; |
- |
- bool final = firstByte & finalBit; |
- bool compress = firstByte & compressBit; |
- bool reserved2 = firstByte & reserved2Bit; |
- bool reserved3 = firstByte & reserved3Bit; |
- unsigned char opCode = firstByte & opCodeMask; |
- |
- bool masked = secondByte & maskBit; |
- uint64_t payloadLength64 = secondByte & payloadLengthMask; |
- if (payloadLength64 > maxPayloadLengthWithoutExtendedLengthField) { |
- int extendedPayloadLengthSize; |
- if (payloadLength64 == payloadLengthWithTwoByteExtendedLengthField) |
- extendedPayloadLengthSize = 2; |
- else { |
- ASSERT(payloadLength64 == payloadLengthWithEightByteExtendedLengthField); |
- extendedPayloadLengthSize = 8; |
- } |
- if (bufferEnd - p < extendedPayloadLengthSize) |
- return FrameIncomplete; |
- payloadLength64 = 0; |
- for (int i = 0; i < extendedPayloadLengthSize; ++i) { |
- payloadLength64 <<= 8; |
- payloadLength64 |= static_cast<unsigned char>(*p++); |
- } |
- if (extendedPayloadLengthSize == 2 && payloadLength64 <= maxPayloadLengthWithoutExtendedLengthField) { |
- errorString = "The minimal number of bytes MUST be used to encode the length"; |
- return FrameError; |
- } |
- if (extendedPayloadLengthSize == 8 && payloadLength64 <= 0xFFFF) { |
- errorString = "The minimal number of bytes MUST be used to encode the length"; |
- return FrameError; |
- } |
- } |
- |
- static const uint64_t maxPayloadLength = UINT64_C(0x7FFFFFFFFFFFFFFF); |
- size_t maskingKeyLength = masked ? maskingKeyWidthInBytes : 0; |
- if (payloadLength64 > maxPayloadLength || payloadLength64 + maskingKeyLength > std::numeric_limits<size_t>::max()) { |
- errorString = "WebSocket frame length too large: " + String::number(payloadLength64) + " bytes"; |
- return FrameError; |
- } |
- size_t payloadLength = static_cast<size_t>(payloadLength64); |
- |
- if (static_cast<size_t>(bufferEnd - p) < maskingKeyLength + payloadLength) |
- return FrameIncomplete; |
- |
- if (masked) { |
- const char* maskingKey = p; |
- char* payload = p + maskingKeyWidthInBytes; |
- for (size_t i = 0; i < payloadLength; ++i) |
- payload[i] ^= maskingKey[i % maskingKeyWidthInBytes]; // Unmask the payload. |
- } |
- |
- frame.opCode = static_cast<WebSocketFrame::OpCode>(opCode); |
- frame.final = final; |
- frame.compress = compress; |
- frame.reserved2 = reserved2; |
- frame.reserved3 = reserved3; |
- frame.masked = masked; |
- frame.payload = p + maskingKeyLength; |
- frame.payloadLength = payloadLength; |
- frameEnd = p + maskingKeyLength + payloadLength; |
- return FrameOK; |
-} |
- |
-static void appendFramePayload(const WebSocketFrame& frame, Vector<char>& frameData) |
-{ |
- size_t maskingKeyStart = 0; |
- if (frame.masked) { |
- maskingKeyStart = frameData.size(); |
- frameData.grow(frameData.size() + maskingKeyWidthInBytes); // Add placeholder for masking key. Will be overwritten. |
- } |
- |
- size_t payloadStart = frameData.size(); |
- frameData.append(frame.payload, frame.payloadLength); |
- |
- if (frame.masked) { |
- cryptographicallyRandomValues(frameData.data() + maskingKeyStart, maskingKeyWidthInBytes); |
- for (size_t i = 0; i < frame.payloadLength; ++i) |
- frameData[payloadStart + i] ^= frameData[maskingKeyStart + i % maskingKeyWidthInBytes]; |
- } |
-} |
- |
-void WebSocketFrame::makeFrameData(Vector<char>& frameData) |
-{ |
- ASSERT(!(opCode & ~opCodeMask)); // Checks whether "opCode" fits in the range of opCodes. |
- |
- frameData.resize(2); |
- frameData.at(0) = (final ? finalBit : 0) | (compress ? compressBit : 0) | opCode; |
- frameData.at(1) = masked ? maskBit : 0; |
- |
- if (payloadLength <= maxPayloadLengthWithoutExtendedLengthField) |
- frameData.at(1) |= payloadLength; |
- else if (payloadLength <= 0xFFFF) { |
- frameData.at(1) |= payloadLengthWithTwoByteExtendedLengthField; |
- frameData.append((payloadLength & 0xFF00) >> 8); |
- frameData.append(payloadLength & 0xFF); |
- } else { |
- frameData.at(1) |= payloadLengthWithEightByteExtendedLengthField; |
- char extendedPayloadLength[8]; |
- size_t remaining = payloadLength; |
- // Fill the length into extendedPayloadLength in the network byte order. |
- for (int i = 0; i < 8; ++i) { |
- extendedPayloadLength[7 - i] = remaining & 0xFF; |
- remaining >>= 8; |
- } |
- ASSERT(!remaining); |
- frameData.append(extendedPayloadLength, 8); |
- } |
- |
- appendFramePayload(*this, frameData); |
-} |
- |
-WebSocketFrame::WebSocketFrame() |
- : opCode(OpCodeInvalid) |
- , final(false) |
- , compress(false) |
- , reserved2(false) |
- , reserved3(false) |
- , masked(false) |
- , payload(0) |
- , payloadLength(0) |
-{ |
-} |
- |
WebSocketFrame::WebSocketFrame(OpCode opCode, const char* payload, size_t payloadLength, Flags flags) |
: opCode(opCode) |
, final(flags & Final) |