Fixed receive method in WebSocket.cs

This commit is contained in:
sta 2012-09-25 15:50:57 +09:00
parent a75903c488
commit dc3a8f3836
59 changed files with 114 additions and 111 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.

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,5 @@
<Properties> <Properties>
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug_Ubuntu" /> <MonoDevelop.Ide.Workspace ActiveConfiguration="Release_Ubuntu" />
<MonoDevelop.Ide.Workbench /> <MonoDevelop.Ide.Workbench />
<MonoDevelop.Ide.DebuggingService.Breakpoints> <MonoDevelop.Ide.DebuggingService.Breakpoints>
<BreakpointStore /> <BreakpointStore />

View File

@ -643,6 +643,18 @@ namespace WebSocketSharp
pong(payloadData); pong(payloadData);
} }
private WsFrame readFrame()
{
var frame = _wsStream.ReadFrame();
if (frame == null)
{
var msg = "WebSocket data frame can not be read from network stream.";
close(CloseStatusCode.ABNORMAL, msg);
}
return frame;
}
private string[] readHandshake() private string[] readHandshake()
{ {
return _wsStream.ReadHandshake(); return _wsStream.ReadHandshake();
@ -650,63 +662,24 @@ namespace WebSocketSharp
private MessageEventArgs receive() private MessageEventArgs receive()
{ {
List<byte> dataBuffer; var frame = readFrame();
MessageEventArgs eventArgs; if (frame == null)
Fin fin; return null;
WsFrame frame;
Opcode opcode;
PayloadData payloadData;
Action act = () =>
{
var msg = "WebSocket data frame can not be read from network stream.";
close(CloseStatusCode.ABNORMAL, msg);
};
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))
{
return null; return null;
}
fin = frame.Fin;
opcode = frame.Opcode;
payloadData = frame.PayloadData;
eventArgs = null;
switch (fin)
{
case Fin.MORE:
dataBuffer = new List<byte>(payloadData.ToBytes());
while (true)
{
frame = _wsStream.ReadFrame();
if (frame.IsNullDo(act)) return null;
if (frame.Fin == Fin.MORE) if (frame.Fin == Fin.MORE)
{ {// MORE
if (frame.Opcode == Opcode.CONT) var merged = receiveFragmented(frame);
{// MORE & CONT if (merged == null)
dataBuffer.AddRange(frame.PayloadData.ToBytes());
}
else
{
#if DEBUG
Console.WriteLine("WS: Info@receive: Start closing handshake.");
#endif
close(CloseStatusCode.INCORRECT_DATA, String.Empty);
return null; return null;
return new MessageEventArgs(frame.Opcode, new PayloadData(merged));
} }
}
else if (frame.Opcode == Opcode.CONT) if (frame.Opcode == Opcode.CLOSE)
{// FINAL & CONT
dataBuffer.AddRange(frame.PayloadData.ToBytes());
break;
}
else if (frame.Opcode == Opcode.CLOSE)
{// FINAL & CLOSE {// FINAL & CLOSE
#if DEBUG #if DEBUG
Console.WriteLine("WS: Info@receive: Start closing handshake."); Console.WriteLine("WS: Info@receive: Start closing handshake.");
@ -714,60 +687,90 @@ namespace WebSocketSharp
close(frame.PayloadData); close(frame.PayloadData);
return null; return null;
} }
else if (frame.Opcode == Opcode.PING)
if (frame.Opcode == Opcode.PING)
{// FINAL & PING {// FINAL & PING
#if DEBUG #if DEBUG
Console.WriteLine("WS: Info@receive: Return Pong."); Console.WriteLine("WS: Info@receive: Return Pong.");
#endif #endif
pong(frame.PayloadData); pong(frame.PayloadData);
return null;
} }
else if (frame.Opcode == Opcode.PONG)
if (frame.Opcode == Opcode.PONG)
{// FINAL & PONG {// FINAL & PONG
_receivedPong.Set(); _receivedPong.Set();
OnMessage.Emit(this, new MessageEventArgs(frame.Opcode, frame.PayloadData));
} }
else
{// FINAL & (TEXT | BINARY) // FINAL & (TEXT | BINARY | PONG)
return new MessageEventArgs(frame.Opcode, frame.PayloadData);
}
private byte[] receiveFragmented(WsFrame firstFrame)
{
var buffer = new List<byte>(firstFrame.PayloadData.ToBytes());
while (true)
{
var frame = readFrame();
if (frame == null)
return null;
if (frame.Fin == Fin.MORE)
{
if (frame.Opcode == Opcode.CONT)
{// MORE & CONT
buffer.AddRange(frame.PayloadData.ToBytes());
continue;
}
#if DEBUG #if DEBUG
Console.WriteLine("WS: Info@receive: Start closing handshake."); Console.WriteLine("WS: Info@receiveFragmented: Start closing handshake.");
#endif #endif
close(CloseStatusCode.INCORRECT_DATA, String.Empty); close(CloseStatusCode.INCORRECT_DATA, String.Empty);
return null; return null;
} }
if (frame.Opcode == Opcode.CONT)
{// FINAL & CONT
buffer.AddRange(frame.PayloadData.ToBytes());
break;
} }
eventArgs = new MessageEventArgs(opcode, new PayloadData(dataBuffer.ToArray())); if (frame.Opcode == Opcode.CLOSE)
break; {// FINAL & CLOSE
case Fin.FINAL: #if DEBUG
switch (opcode) Console.WriteLine("WS: Info@receiveFragmented: Start closing handshake.");
{ #endif
case Opcode.TEXT: close(frame.PayloadData);
case Opcode.BINARY: return null;
goto default; }
case Opcode.PONG:
if (frame.Opcode == Opcode.PING)
{// FINAL & PING
#if DEBUG
Console.WriteLine("WS: Info@receiveFragmented: Return Pong.");
#endif
pong(frame.PayloadData);
continue;
}
if (frame.Opcode == Opcode.PONG)
{// FINAL & PONG
_receivedPong.Set(); _receivedPong.Set();
goto default; OnMessage.Emit(this, new MessageEventArgs(frame.Opcode, frame.PayloadData));
case Opcode.CLOSE: continue;
#if DEBUG
Console.WriteLine("WS: Info@receive: Start closing handshake.");
#endif
close(payloadData);
break;
case Opcode.PING:
#if DEBUG
Console.WriteLine("WS: Info@receive: Return Pong.");
#endif
pong(payloadData);
break;
default:
eventArgs = new MessageEventArgs(opcode, payloadData);
break;
} }
break; // FINAL & (TEXT | BINARY)
#if DEBUG
Console.WriteLine("WS: Info@receiveFragmented: Start closing handshake.");
#endif
close(CloseStatusCode.INCORRECT_DATA, String.Empty);
return null;
} }
return eventArgs; return buffer.ToArray();
} }
private RequestHandshake receiveOpeningHandshake() private RequestHandshake receiveOpeningHandshake()

Binary file not shown.