1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace SocketHttpListener
{
internal class PayloadData : IEnumerable<byte>
{
#region Private Fields
private byte[] _applicationData;
private byte[] _extensionData;
private bool _masked;
#endregion
#region Public Const Fields
public const ulong MaxLength = long.MaxValue;
#endregion
#region Public Constructors
public PayloadData()
: this(new byte[0], new byte[0], false)
{
}
public PayloadData(byte[] applicationData)
: this(new byte[0], applicationData, false)
{
}
public PayloadData(string applicationData)
: this(new byte[0], Encoding.UTF8.GetBytes(applicationData), false)
{
}
public PayloadData(byte[] applicationData, bool masked)
: this(new byte[0], applicationData, masked)
{
}
public PayloadData(byte[] extensionData, byte[] applicationData, bool masked)
{
_extensionData = extensionData;
_applicationData = applicationData;
_masked = masked;
}
#endregion
#region Internal Properties
internal bool ContainsReservedCloseStatusCode =>
_applicationData.Length > 1 &&
_applicationData.SubArray(0, 2).ToUInt16(ByteOrder.Big).IsReserved();
#endregion
#region Public Properties
public byte[] ApplicationData => _applicationData;
public byte[] ExtensionData => _extensionData;
public bool IsMasked => _masked;
public ulong Length => (ulong)(_extensionData.Length + _applicationData.Length);
#endregion
#region Private Methods
private static void mask(byte[] src, byte[] key)
{
for (long i = 0; i < src.Length; i++)
src[i] = (byte)(src[i] ^ key[i % 4]);
}
#endregion
#region Public Methods
public IEnumerator<byte> GetEnumerator()
{
foreach (byte b in _extensionData)
yield return b;
foreach (byte b in _applicationData)
yield return b;
}
public void Mask(byte[] maskingKey)
{
if (_extensionData.Length > 0)
mask(_extensionData, maskingKey);
if (_applicationData.Length > 0)
mask(_applicationData, maskingKey);
_masked = !_masked;
}
public byte[] ToByteArray()
{
return _extensionData.Length > 0
? new List<byte>(this).ToArray()
: _applicationData;
}
public override string ToString()
{
return BitConverter.ToString(ToByteArray());
}
#endregion
#region Explicitly Implemented Interface Members
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
}
|