Skip to content

Corrupted message from IE11, Edge when the content is larger than 1MB and sent multiple times #15

@Peter-Optiway

Description

@Peter-Optiway

I'm using your WebSocketListener the following way:

class Program
{
    static void Main(string[] args)
    {
        CancellationTokenSource cancellation = new CancellationTokenSource();
            
        var task = Task.Run(() => RunServer(cancellation.Token));
        Console.WriteLine("Press any key to stop");
        Console.ReadKey(true);
        cancellation.Cancel();
        task.Wait();
        Console.ReadKey(true);
    }

    static async Task RunServer(CancellationToken cancellationToken)
    {
        try
        {
            var options = new WebSocketListenerOptions();
            options.Logger = new WebSocketLogger();
            options.Standards.RegisterRfc6455();
            var server = new WebSocketListener(new IPEndPoint(IPAddress.Any, 1234), options);
            await server.StartAsync();
            while (!cancellationToken.IsCancellationRequested)
            {
                var client = await server.AcceptWebSocketAsync(cancellationToken);
                Console.WriteLine("Client connected");
                while (client.IsConnected)
                {
                    var content = await client.ReadStringAsync(cancellationToken);
                    if (content == null)
                    {
                        //client disconnected
                        continue;
                    }
                    Console.WriteLine("Message received");
                    //validate content!
                    if (!Regex.IsMatch(content, @"^([0-9a-zA-Z+])*$"))
                    {
                        await client.WriteStringAsync("Content was invalid", cancellationToken);
                        Console.WriteLine("Content was invalid!");
                    }
                    else
                    {
                        await client.WriteStringAsync("Content was valid", cancellationToken);
                    }
                }
                Console.WriteLine("Client disconnected");
            }
            await server.StopAsync();
        }
        catch(Exception ex)
        {
            Console.WriteLine("Error occurred, " + ex.ToString());
        }
        finally
        {
            Console.WriteLine("Exited event loop");
        }
    }
}

class WebSocketLogger : vtortola.WebSockets.ILogger
{

    public bool IsDebugEnabled
    {
        get
        {
            return true;
        }
    }

    public bool IsWarningEnabled
    {
        get
        {
            return true;
        }
    }

    public bool IsErrorEnabled
    {
        get
        {
            return true;
        }
    }

    public void Debug(string message, Exception error = null)
    {
        Console.WriteLine(DateTime.Now.ToString("G") + " Debug " + message);
        if (error != null)
            Console.WriteLine(error.ToString());
    }

    public void Warning(string message, Exception error = null)
    {
        Console.WriteLine(DateTime.Now.ToString("G") + " Warn " + message);
        if (error != null)
            Console.WriteLine(error.ToString());
    }

    public void Error(string message, Exception error = null)
    {
        Console.WriteLine(DateTime.Now.ToString("G") + " Error " + message);
        if (error != null)
            Console.WriteLine(error.ToString());
    }
}

Then i have the following page

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Websocket tester!</title>
    <script src="assets/js/jquery.slim.min.js"></script>
    <script src="assets/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="assets/css/bootstrap.min.css" />
    <link rel="stylesheet" href="assets/css/bootstrap-theme.min.css" />
  </head>
  <body>
    <div class="container">
      <div class="row">
        <div class="col-sm-12">
          <form id="openForm" class="form-horizontal">
            <div class="form-group">
              <label for="dataFile" class="col-sm-2 control-label">Data to spam:</label>
              <div class="col-sm-10">
                <input type="file" class="control-label" id="dataFile" />
              </div>
            </div>
              <div class="form-group">
                <label for="count" class="col-sm-2 control-label">count:</label>
                <div class="col-sm-10">
                  <input type="text" class="control-label" id="count" />
                </div>
              </div>
            <div>
              <div class="col-sm-offset-2 col-sm-10">
                <button id="send" type="submit" class="btn btn-default">Send</button>
              </div>
            </div>
          </form>
        </div>
      </div>
    </div>
    <script src="assets/js/index.js"></script>
  </body>
</html>

and the following javascript file:

var openFormElement = $('#openForm');
var dataFileElement = $('#dataFile').get(0);
var countElement = $('#count');
var sendButton = $('#send');

var socket;

sendButton.click(function(e) {
  if (dataFileElement.files.length === 1) {
    var dataReader = new FileReader();
    dataReader.onload = function(dataEvent) {
      var data = dataEvent.target.result;
      //now we have the data to spam send!
      if (socket) {
        socket.close();
      }
      socket = new WebSocket("ws://localhost:1234/");
      socket.onopen = function(event) {
        console.log('connected');
        //Now we can spam!
        var count = parseInt(countElement.val());
        for (var i = 0; i < count; i++) {
          console.log('sending data');
          socket.send(data);
        }
      };
      socket.onmessage = function(event) {
        console.log('onmessage', event);
      };
      socket.onclose = function(event) {
        console.log('closed', event);
      };
      socket.onerror = function(event) {
        console.log('error', event);
      };
    };
    dataReader.readAsText(dataFileElement.files[0]);
  }
  e.stopPropagation();
  return false;
});

If i in IE or Edge:
Select the Random1MB.txt and enter 10 in the count and press send it works.
But if i use Random1.5MB.txt instead it crashes after 6 messages and the following is logged by the WebSocketListener. (Also the content is corrupted.)

2018-01-22 13:17:37 Debug (BAB87) An error occurred while async awaiting header.
vtortola.WebSockets.WebSocketException: Frame header is malformed.
   at vtortola.WebSockets.Rfc6455.WebSocketConnectionRfc6455.<ParseHeaderAsync>d__44.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at vtortola.WebSockets.Rfc6455.WebSocketConnectionRfc6455.<AwaitHeaderAsync>d__36.MoveNext()
2018-01-22 13:17:37 Debug (BAB87) [FRAME->] ConnectionClose, len: 2, key: 0, flags: FIN
Error occurred, vtortola.WebSockets.WebSocketException: Frame header is malformed.
   at vtortola.WebSockets.Rfc6455.WebSocketConnectionRfc6455.<ParseHeaderAsync>d__44.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at vtortola.WebSockets.Rfc6455.WebSocketConnectionRfc6455.<AwaitHeaderAsync>d__36.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at vtortola.WebSockets.Rfc6455.WebSocketConnectionRfc6455.<AwaitHeaderAsync>d__36.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at vtortola.WebSockets.Rfc6455.WebSocketRfc6455.<ReadMessageAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at vtortola.WebSockets.WebSocketStringExtensions.<ReadStringAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at WebSocketServerTest.Program.<RunServer>d__1.MoveNext() in ...\WebSocketServerTest\Program.cs:line 43

Do you have any idea what is wrong, or what i could do about it? (I'm using IE11 and Edge, but it seems to work correctly in Chrome)

Example.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions