Fix for issue #3

This commit is contained in:
sta 2012-08-10 22:20:42 +09:00
parent 18c225c99d
commit b76418c482
51 changed files with 127 additions and 77 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,12 @@
<Properties> <Properties>
<MonoDevelop.Ide.Workspace ActiveConfiguration="Release_Ubuntu" /> <MonoDevelop.Ide.Workspace ActiveConfiguration="Debug_Ubuntu" />
<MonoDevelop.Ide.Workbench /> <MonoDevelop.Ide.Workbench ActiveDocument="websocket-sharp/Frame/WsFrame.cs">
<Files>
<File FileName="websocket-sharp/WebSocket.cs" Line="795" Column="25" />
<File FileName="websocket-sharp/Frame/WsFrame.cs" Line="278" Column="1" />
<File FileName="websocket-sharp/Ext.cs" Line="121" Column="23" />
</Files>
</MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.DebuggingService.Breakpoints> <MonoDevelop.Ide.DebuggingService.Breakpoints>
<BreakpointStore /> <BreakpointStore />
</MonoDevelop.Ide.DebuggingService.Breakpoints> </MonoDevelop.Ide.DebuggingService.Breakpoints>

View File

@ -112,24 +112,24 @@ namespace WebSocketSharp
public static byte[] ReadBytes<TStream>(this TStream stream, ulong length, int bufferLength) public static byte[] ReadBytes<TStream>(this TStream stream, ulong length, int bufferLength)
where TStream : System.IO.Stream where TStream : System.IO.Stream
{ {
List<byte> readData = new List<byte>();
ulong count = length / (ulong)bufferLength; ulong count = length / (ulong)bufferLength;
int remainder = (int)(length % (ulong)bufferLength); int remainder = (int)(length % (ulong)bufferLength);
List<byte> readData = new List<byte>();
byte[] buffer1 = new byte[bufferLength]; byte[] buffer1 = new byte[bufferLength];
int readLen = 0;
count.Times(() => count.Times(() =>
{ {
stream.Read(buffer1, 0, bufferLength); readLen = stream.Read(buffer1, 0, bufferLength);
readData.AddRange(buffer1); if (readLen > 0) readData.AddRange(buffer1.SubArray(0, readLen));
}); });
if (remainder > 0) if (remainder > 0)
{ {
byte[] buffer2 = new byte[remainder]; byte[] buffer2 = new byte[remainder];
stream.Read(buffer2, 0, remainder); readLen = stream.Read(buffer2, 0, remainder);
readData.AddRange(buffer2); if (readLen > 0) readData.AddRange(buffer2.SubArray(0, readLen));
} }
return readData.ToArray(); return readData.ToArray();

View File

@ -179,9 +179,14 @@ namespace WebSocketSharp.Frame
int buffer2Len = 0; int buffer2Len = 0;
ulong buffer3Len = 0; ulong buffer3Len = 0;
int maskingKeyLen = 4; int maskingKeyLen = 4;
int readLen = 0;
buffer1 = new byte[buffer1Len]; buffer1 = new byte[buffer1Len];
stream.Read(buffer1, 0, buffer1Len); readLen = stream.Read(buffer1, 0, buffer1Len);
if (readLen < buffer1Len)
{
return null;
}
// FIN // FIN
fin = (buffer1[0] & 0x80) == 0x80 fin = (buffer1[0] & 0x80) == 0x80
@ -224,7 +229,13 @@ namespace WebSocketSharp.Frame
if (buffer2Len > 0) if (buffer2Len > 0)
{ {
buffer2 = new byte[buffer2Len]; buffer2 = new byte[buffer2Len];
stream.Read(buffer2, 0, buffer2Len); readLen = stream.Read(buffer2, 0, buffer2Len);
if (readLen < buffer2Len)
{
return null;
}
extPayloadLen = buffer2; extPayloadLen = buffer2;
switch (buffer2Len) switch (buffer2Len)
{ {
@ -245,17 +256,32 @@ namespace WebSocketSharp.Frame
if (masked == Mask.MASK) if (masked == Mask.MASK)
{ {
maskingKey = new byte[maskingKeyLen]; maskingKey = new byte[maskingKeyLen];
stream.Read(maskingKey, 0, maskingKeyLen); readLen = stream.Read(maskingKey, 0, maskingKeyLen);
if (readLen < maskingKeyLen)
{
return null;
}
} }
// Payload Data // Payload Data
if (buffer3Len <= (ulong)_readBufferLen) if (buffer3Len <= (ulong)_readBufferLen)
{ {
buffer3 = new byte[buffer3Len]; buffer3 = new byte[buffer3Len];
stream.Read(buffer3, 0, (int)buffer3Len); readLen = stream.Read(buffer3, 0, (int)buffer3Len);
if (readLen < (int)buffer3Len)
{
return null;
}
} }
else else
{ {
buffer3 = stream.ReadBytes(buffer3Len, _readBufferLen); buffer3 = stream.ReadBytes(buffer3Len, _readBufferLen);
if ((ulong)buffer3.LongLength < buffer3Len)
{
return null;
}
} }
if (masked == Mask.MASK) if (masked == Mask.MASK)

View File

@ -64,10 +64,10 @@ namespace WebSocketSharp.Server
_server.AddService(this); _server.AddService(this);
}; };
_socket.OnClose += (sender, e) => // _socket.OnClose += (sender, e) =>
{ // {
_server.RemoveService(this); // _server.RemoveService(this);
}; // };
} }
#endregion #endregion

View File

@ -752,6 +752,10 @@ namespace WebSocketSharp
{ {
close(CloseStatusCode.TOO_BIG, ex.Message); close(CloseStatusCode.TOO_BIG, ex.Message);
} }
catch (Exception ex)
{
close(CloseStatusCode.ABNORMAL, ex.Message);
}
} }
private void messageLoop() private void messageLoop()
@ -762,39 +766,16 @@ namespace WebSocketSharp
} }
} }
private void startMessageThread() private void pong(PayloadData data)
{ {
if (_isClient) var frame = createFrame(Fin.FINAL, Opcode.PONG, data);
{ send(frame);
_msgThread = new Thread(new ThreadStart(messageLoop));
_msgThread.IsBackground = true;
_msgThread.Start();
} }
else
{
_autoEvent = new AutoResetEvent(false);
Action act = () =>
{
if (_readyState == WsState.OPEN)
{
message();
}
};
AsyncCallback callback = (ar) =>
{
act.EndInvoke(ar);
if (_readyState == WsState.OPEN) private void pong(string data)
{ {
act.BeginInvoke(callback, null); var payloadData = new PayloadData(data);
} pong(payloadData);
else
{
_autoEvent.Set();
}
};
act.BeginInvoke(callback, null);
}
} }
private MessageEventArgs receive() private MessageEventArgs receive()
@ -806,7 +787,15 @@ namespace WebSocketSharp
Opcode opcode; Opcode opcode;
PayloadData payloadData; PayloadData payloadData;
Action act = () =>
{
var msg = "WebSocket data frame can not be read from network stream.";
close(CloseStatusCode.ABNORMAL, msg);
};
frame = _wsStream.ReadFrame(); frame = _wsStream.ReadFrame();
if (frame.IsNullDo(act)) return null;
if ((frame.Fin == Fin.FINAL && frame.Opcode == Opcode.CONT) || if ((frame.Fin == Fin.FINAL && frame.Opcode == Opcode.CONT) ||
(frame.Fin == Fin.MORE && frame.Opcode == Opcode.CONT)) (frame.Fin == Fin.MORE && frame.Opcode == Opcode.CONT))
{ {
@ -825,6 +814,7 @@ namespace WebSocketSharp
while (true) while (true)
{ {
frame = _wsStream.ReadFrame(); frame = _wsStream.ReadFrame();
if (frame.IsNullDo(act)) return null;
if (frame.Fin == Fin.MORE) if (frame.Fin == Fin.MORE)
{ {
@ -856,8 +846,10 @@ namespace WebSocketSharp
} }
else if (frame.Opcode == Opcode.PING) else if (frame.Opcode == Opcode.PING)
{// FINAL & PING {// FINAL & PING
#if DEBUG
Console.WriteLine("WS: Info@receive: Return Pong.");
#endif
pong(frame.PayloadData); pong(frame.PayloadData);
OnMessage.Emit(this, new MessageEventArgs(frame.Opcode, frame.PayloadData));
} }
else if (frame.Opcode == Opcode.PONG) else if (frame.Opcode == Opcode.PONG)
{// FINAL & PONG {// FINAL & PONG
@ -889,8 +881,11 @@ namespace WebSocketSharp
close(payloadData); close(payloadData);
break; break;
case Opcode.PING: case Opcode.PING:
#if DEBUG
Console.WriteLine("WS: Info@receive: Return Pong.");
#endif
pong(payloadData); pong(payloadData);
goto default; break;
default: default:
eventArgs = new MessageEventArgs(opcode, payloadData); eventArgs = new MessageEventArgs(opcode, payloadData);
break; break;
@ -902,18 +897,6 @@ namespace WebSocketSharp
return eventArgs; return eventArgs;
} }
private void pong(PayloadData data)
{
var frame = createFrame(Fin.FINAL, Opcode.PONG, data);
send(frame);
}
private void pong(string data)
{
var payloadData = new PayloadData(data);
pong(payloadData);
}
private string[] receiveOpeningHandshake() private string[] receiveOpeningHandshake()
{ {
var readData = new List<byte>(); var readData = new List<byte>();
@ -1096,10 +1079,60 @@ namespace WebSocketSharp
_wsStream.Write(buffer, 0, buffer.Length); _wsStream.Write(buffer, 0, buffer.Length);
} }
private void startMessageThread()
{
if (_isClient)
{
_msgThread = new Thread(new ThreadStart(messageLoop));
_msgThread.IsBackground = true;
_msgThread.Start();
}
else
{
_autoEvent = new AutoResetEvent(false);
Action act = () =>
{
if (_readyState == WsState.OPEN)
{
message();
}
};
AsyncCallback callback = (ar) =>
{
act.EndInvoke(ar);
if (_readyState == WsState.OPEN)
{
act.BeginInvoke(callback, null);
}
else
{
_autoEvent.Set();
}
};
act.BeginInvoke(callback, null);
}
}
#endregion #endregion
#region Public Methods #region Public Methods
public void Close()
{
Close(CloseStatusCode.NORMAL);
}
public void Close(CloseStatusCode code)
{
Close(code, String.Empty);
}
public void Close(CloseStatusCode code, string reason)
{
close(code, reason);
}
public void Connect() public void Connect()
{ {
if (_readyState == WsState.OPEN) if (_readyState == WsState.OPEN)
@ -1128,21 +1161,6 @@ namespace WebSocketSharp
} }
} }
public void Close()
{
Close(CloseStatusCode.NORMAL);
}
public void Close(CloseStatusCode code)
{
Close(code, String.Empty);
}
public void Close(CloseStatusCode code, string reason)
{
close(code, reason);
}
public void Dispose() public void Dispose()
{ {
Close(CloseStatusCode.AWAY); Close(CloseStatusCode.AWAY);

Binary file not shown.