/// <summary> /// Initializes a new instance of the <see cref="ButtplugJsonMessageParser"/> class. /// </summary> /// <param name="aLogManager">Log manager</param> public ButtplugJsonMessageParser(IButtplugLogManager aLogManager = null) { _bpLogger = aLogManager.GetLogger(GetType()); _bpLogger?.Info($"Setting up {GetType().Name}"); _serializer = new JsonSerializer { MissingMemberHandling = MissingMemberHandling.Error }; IEnumerable <Type> allTypes; // Some classes in the library may not load on certain platforms due to missing symbols. // If this is the case, we should still find messages even though an exception was thrown. try { allTypes = Assembly.GetAssembly(typeof(ButtplugMessage)).GetTypes(); } catch (ReflectionTypeLoadException e) { allTypes = e.Types; } var messageClasses = allTypes.Where(t => t != null && t.IsClass && t.Namespace == "B******g.Core.Messages" && typeof(ButtplugMessage).IsAssignableFrom(t)); var enumerable = messageClasses as Type[] ?? messageClasses.ToArray(); _bpLogger?.Debug($"Message type count: {enumerable.Length}"); _messageTypes = new Dictionary <string, Type>(); enumerable.ToList().ForEach(aMessageType => { _bpLogger?.Debug($"- {aMessageType.Name}"); _messageTypes.Add(aMessageType.Name, aMessageType); }); // Load the schema for validation var assembly = Assembly.GetExecutingAssembly(); const string resourceName = "B******g.Core.b******g-schema.json"; Stream stream = null; try { stream = assembly.GetManifestResourceStream(resourceName); using (var reader = new StreamReader(stream)) { stream = null; var result = reader.ReadToEnd(); _schema = JsonSchema4.FromJsonAsync(result).GetAwaiter().GetResult(); } } catch (Exception e) { _bpLogger.LogException(e); throw e; } finally { stream?.Dispose(); } }
private void WebSocketExceptionHandler(object aObj, [NotNull] UnhandledExceptionEventArgs aEx) { _toastTimer.Enabled = true; var errorMessage = (aEx.ExceptionObject as Exception)?.Message ?? "Unknown"; if (_secure && errorMessage.Contains("Not GET request") && _ws != null && !aEx.IsTerminating) { _log.LogException(aEx.ExceptionObject as Exception, true, errorMessage); return; } if (_secure && errorMessage.Contains("The handshake failed due to an unexpected packet format")) { errorMessage += "\n\nThis usually means that the client/browser tried to connect without SSL. Make sure the client is set use the wss:// URI scheme."; } else if (_secure) { errorMessage += "\n\nIf your connection is working, you can ignore this message. Otherwise, this could mean that the client/browser has not accepted our SSL certificate. Try hitting the test button on the \"Websocket Server\" tab."; } _currentExceptionMessage = errorMessage; _log.LogException(aEx.ExceptionObject as Exception, true, errorMessage); }
public async void StartServer() { if (_isRunning) { return; } _isRunning = true; _stop = false; try { _httpListener.Start(); } catch (Exception e) { _log.LogException(e); OnException?.Invoke(this, new UnhandledExceptionEventArgs(e, true)); _isRunning = false; return; } while (!_stop) { HttpListenerContext ctx = null; try { ctx = await _httpListener.GetContextAsync(); } catch (HttpListenerException ex) { _log.LogException(ex); if (ex.ErrorCode == 995) { StopServer(); _isRunning = false; return; } } catch (ObjectDisposedException) { return; } catch (Exception e) { _log.LogException(e); OnException?.Invoke(this, new UnhandledExceptionEventArgs(e, true)); } if (ctx == null) { continue; } // got a request var response = ctx.Response; response.Headers.Add("Access-Control-Allow-Origin", "*"); response.Headers.Add(HttpResponseHeader.CacheControl, "private, no-store"); response.ContentType = "application/json; charset=utf-8"; response.StatusCode = (int)HttpStatusCode.OK; if (ctx.Request.Url.Segments.Length < 2) { response.StatusCode = (int)HttpStatusCode.NotFound; response.Close(); continue; } var methodName = ctx.Request.Url.Segments[1].Replace("/", string.Empty); string json; switch (methodName) { case "status": json = "{\"connectedDeviceName\":\"ONYX\",\"bluetoothAddress\":\"8CDE52B866B5\",\"firmwareUpdateProgres\":0,\"remoteDevice\":\"not connected\",\"devicestatus\":\"NORMAL\",\"localDevice\":\"connected\",\"previousdevice_connectionurl\":\"btspp://8CDE52B866B5:1;authenticate=false;encrypt=false;master=false\",\"readOnlyMode\":false,\"streamToDeviceEnabled\":true,\"delay\":0,\"writeOnlyMode\":false,\"currentFW\":\"91\",\"waitingforusbcable\":true,\"bluetoothOn\":true,\"previousdevice_name\":\"ONYX\",\"uienabled\":true,\"newFWVersionAvailable\":false,\"previousdevice_bluetoothaddress\":\"8CDE52B866B5\",\"statusCode\":1}"; break; case "senddata": json = "{}"; NameValueCollection data; try { var post = GetRequestPostData(ctx.Request); data = HttpUtility.ParseQueryString(post); if (!data.HasKeys()) { response.StatusCode = (int)HttpStatusCode.NotFound; response.Close(); continue; } } catch { // noop - most likely the connection has been severed half way through a read. continue; } try { var position = ushort.Parse(data["data"]); OnKiirooPlatformEvent?.Invoke(this, new KiirooPlatformEventArgs(position)); } catch (FormatException) { // Swallow format exceptions, as sometimes scripts can send "undefined". response.StatusCode = (int)HttpStatusCode.NotFound; response.Close(); continue; } break; default: response.StatusCode = (int)HttpStatusCode.NotFound; response.Close(); continue; } var messageBytes = Encoding.UTF8.GetBytes(json); response.ContentLength64 = messageBytes.Length; try { await response.OutputStream.WriteAsync(messageBytes, 0, messageBytes.Length); response.OutputStream.Close(); response.Close(); } catch { // noop - most likely the connection has been severed half way through a read. continue; } } _isRunning = false; }