SignalR / SignalR

Incredibly simple real-time web for .NET
http://signalr.net
Other
9.21k stars 2.28k forks source link

Error in groups serialization (Javascript client) #1217

Closed davidfowl closed 11 years ago

davidfowl commented 11 years ago

Found this in the jabbr.net logs. It seems for some reason groups are being sent as a json object instead of an array in some cases.

Exception information: 
    Exception type: JsonSerializationException 
    Exception message: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.String[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path '#Chat.OctopusDeploy', line 1, position 23.
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Microsoft.AspNet.SignalR.Json.JsonNetSerializer.Parse(String json, Type targetType)
   at Microsoft.AspNet.SignalR.Json.JsonSerializerExtensions.Parse[T](IJsonSerializer serializer, String json)
   at Microsoft.AspNet.SignalR.Transports.TransportDisconnectBase.get_Groups()
   at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequestAsync(HostContext context)
   at Microsoft.AspNet.SignalR.Owin.CallHandler.Invoke(IDictionary`2 environment)
   at Microsoft.AspNet.SignalR.Owin.Handlers.HubDispatcherHandler.Invoke(IDictionary`2 environment)
   at Microsoft.Owin.Host.SystemWeb.OwinCallContext.Execute()
   at Microsoft.Owin.Host.SystemWeb.OwinHttpHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object extraData)

Request information: 
    Request URL: http://jabbr.net/signalr?transport=serverSentEvents&connectionId=28a3d727-a9a6-481d-b371-d23c80099bf8&connectionData=[]&messageId=P:,2|QA,0|QB,50&groups={"#Chat.OctopusDeploy":true}&tid=0 
    Request path: /signalr 
    User host address: 107.20.97.189 
    User:  
    Is authenticated: False 
    Authentication Type:  
    Thread account name: NT AUTHORITY\NETWORK SERVICE 

Thread information: 
    Thread ID: 11 
    Thread account name: NT AUTHORITY\NETWORK SERVICE 
    Is impersonating: False 
    Stack trace:    at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Microsoft.AspNet.SignalR.Json.JsonNetSerializer.Parse(String json, Type targetType)
   at Microsoft.AspNet.SignalR.Json.JsonSerializerExtensions.Parse[T](IJsonSerializer serializer, String json)
   at Microsoft.AspNet.SignalR.Transports.TransportDisconnectBase.get_Groups()
   at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequestAsync(HostContext context)
   at Microsoft.AspNet.SignalR.Owin.CallHandler.Invoke(IDictionary`2 environment)
   at Microsoft.AspNet.SignalR.Owin.Handlers.HubDispatcherHandler.Invoke(IDictionary`2 environment)
   at Microsoft.Owin.Host.SystemWeb.OwinCallContext.Execute()
   at Microsoft.Owin.Host.SystemWeb.OwinHttpHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object extraData)
NTaylorMullen commented 11 years ago

Is there any additional info in the logs? I'm unable to repro this and after spending a significant amount of time in the JS source I feel as though this was the result of someone messing around with their client.

The &groups=val addition to the query string is ALWAYS an array via @halter73 addition of the getGroups method:

       getGroups: function (connection) {
            var groups = [];
            if (connection.groups) {
                $.each(connection.groups, function (group, _) {
                    // Add keys from connection.groups without the # prefix
                    groups.push(group.substr(1));
                });
            }
            return groups;
        }

This is called prior to appending the data to the query string.

In addition to this the messageId field in the request is funky. After clarifying its format with @halter73 it should not be possible for there to be a colon in the message id. Which is why i'm leaning towards this being a false alarm.

For now I'll assign this to @Xiaohongt for reproduction when time permits.

davidfowl commented 11 years ago

There's nothing else there. It could be a browser specific thing but it does happen. I'm sure it's not somebody messing with the client.

davidfowl commented 11 years ago

Seems like it's this nodejs client https://github.com/smoak/njabbr/blob/master/lib/transports/common.js#L174