websocket-server – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.IO;
6 using System.Net.Sockets;
7 using System.Diagnostics;
8  
9 namespace WebSockets.Common
10 {
11 // see http://tools.ietf.org/html/rfc6455 for specification
12  
13 public class WebSocketFrameReader
14 {
15 private byte[] _buffer;
16  
17 public WebSocketFrameReader()
18 {
19 _buffer = new byte[1024*64];
20 }
21  
22 public WebSocketFrame Read(Stream stream, Socket socket)
23 {
24 byte byte1;
25  
26 try
27 {
28 byte1 = (byte) stream.ReadByte();
29 }
30 catch (IOException)
31 {
32 if (socket.Connected)
33 {
34 throw;
35 }
36 else
37 {
38 return null;
39 }
40 }
41  
42 // process first byte
43 byte finBitFlag = 0x80;
44 byte opCodeFlag = 0x0F;
45 bool isFinBitSet = (byte1 & finBitFlag) == finBitFlag;
46 WebSocketOpCode opCode = (WebSocketOpCode) (byte1 & opCodeFlag);
47  
48 // read and process second byte
49 byte byte2 = (byte) stream.ReadByte();
50 byte maskFlag = 0x80;
51 bool isMaskBitSet = (byte2 & maskFlag) == maskFlag;
52 uint len = ReadLength(byte2, stream);
53 byte[] decodedPayload;
54  
55 // use the masking key to decode the data if needed
56 if (isMaskBitSet)
57 {
58 const int maskKeyLen = 4;
59 byte[] maskKey = BinaryReaderWriter.ReadExactly(maskKeyLen, stream);
60 byte[] encodedPayload = BinaryReaderWriter.ReadExactly((int) len, stream);
61 decodedPayload = new byte[len];
62  
63 // apply the mask key
64 for (int i = 0; i < encodedPayload.Length; i++)
65 {
66 decodedPayload[i] = (Byte) (encodedPayload[i] ^ maskKey[i%maskKeyLen]);
67 }
68 }
69 else
70 {
71 decodedPayload = BinaryReaderWriter.ReadExactly((int) len, stream);
72 }
73  
74 WebSocketFrame frame = new WebSocketFrame(isFinBitSet, opCode, decodedPayload, true);
75 return frame;
76 }
77  
78 private static uint ReadLength(byte byte2, Stream stream)
79 {
80 byte payloadLenFlag = 0x7F;
81 uint len = (uint) (byte2 & payloadLenFlag);
82  
83 // read a short length or a long length depending on the value of len
84 if (len == 126)
85 {
86 len = BinaryReaderWriter.ReadUShortExactly(stream, false);
87 }
88 else if (len == 127)
89 {
90 len = (uint) BinaryReaderWriter.ReadULongExactly(stream, false);
91 const uint maxLen = 2147483648; // 2GB
92  
93 // protect ourselves against bad data
94 if (len > maxLen || len < 0)
95 {
96 throw new ArgumentOutOfRangeException(string.Format("Payload length out of range. Min 0 max 2GB. Actual {0:#,##0} bytes.", len));
97 }
98 }
99  
100 return len;
101 }
102 }
103 }