/// <summary> /// Sends a webservice to the miniserver /// </summary> /// <param name="request">The Request that should be sent</param> /// <returns>The Response the miniserver returns</returns> public async override Task <WebserviceResponse> SendWebservice(WebserviceRequest request) { WebserviceRequest encRequest = await GetEncryptedRequest(request); Uri url = new UriBuilder() { Scheme = "http", Host = IP, Port = Port, Path = encRequest.Command, Query = encRequest.Queries.ToString() }.Uri; CancellationTokenSource?.Dispose(); CancellationTokenSource = new CancellationTokenSource(request.Timeout); HttpResponseMessage httpResponse = await HttpClient?.GetAsync(url.OriginalString, CancellationTokenSource.Token); byte[] responseContent = await httpResponse?.Content.ReadAsByteArrayAsync(); CancellationTokenSource?.Dispose(); if (httpResponse.IsSuccessStatusCode && request.Encryption == EncryptionType.RequestAndResponse) //decypt response if needed { responseContent = Encoding.UTF8.GetBytes(Cryptography.AesDecrypt(Encoding.UTF8.GetString(responseContent), Session)); } WebserviceResponse response = new WebserviceResponse(null, responseContent, (int)httpResponse.StatusCode); encRequest.TryValidateResponse(response); return(response); }
/// <summary> /// Waits until a matching WebserviceResponse is received /// </summary> /// <returns>The received WebserviceResponse</returns> public WebserviceResponse WaitForResponse() { if (!ResponseReceived.WaitOne(Timeout)) { Response = null; } return(Response); }
/// <summary> /// Validates the given WebserviceResponse /// </summary> /// <param name="response">The WebserviceResponse to validate</param> /// <returns>Whether the validation succeeded or not</returns> public virtual bool TryValidateResponse(WebserviceResponse response) { if (response != null) { Response = response; ResponseReceived.Set(); return(true); } else { return(false); } }
/// <summary> /// Handles the assignment of the responses to the right requests. /// </summary> /// <param name="response">The response that should be handled</param> /// <returns>Whether or not the reponse could be assigned to a request</returns> private bool HandleWebserviceResponse(WebserviceResponse response) { foreach (WebserviceRequest request in Enumerable.Reverse(Requests)) { if (request.TryValidateResponse(response)) { lock (Requests) { Requests.Remove(request); } return(true); } } return(false); }
/// <summary> /// The listener starts to wait for messsages from the miniserver /// </summary> private void BeginListening() { if (Listener != null) { TokenSource.Cancel(); Listener = null; } Listener = Task.Run(async() => { while (WebSocket.State == WebSocketState.Open) { WebserviceResponse response = await ReceiveWebsocketMessage(1024, TokenSource.Token); if (!HandleWebserviceResponse(response) && !ParseEventTable(response.Content, response.Header.Type)) { OnReceiveMessge?.BeginInvoke(WebSocket, new MessageReceivedEventArgs(response), null, null); } await Task.Delay(10); } }, TokenSource.Token); }
/// <summary> /// Sends a webservice to the miniserver and waits until its receives an answer /// </summary> /// <param name="request">The Request that should be sent</param> /// <returns>The Response the miniserver returns</returns> public async override Task <WebserviceResponse> SendWebservice(WebserviceRequest request) { switch (request?.Encryption) { case EncryptionType.Request: request.Command = Uri.EscapeDataString(Cryptography.AesEncrypt($"salt/{Session.Salt}/{request.Command}", Session)); request.Command = $"jdev/sys/enc/{request.Command}"; request.Encryption = EncryptionType.None; return(await SendWebservice(request)); case EncryptionType.RequestAndResponse: string command = Uri.EscapeDataString(Cryptography.AesEncrypt($"salt/{Session.Salt}/{request.Command}", Session)); command = $"jdev/sys/fenc/{command}"; WebserviceRequest encryptedRequest = new WebserviceRequest(command, EncryptionType.None); WebserviceResponse encrypedResponse = await SendWebservice(encryptedRequest); if (encrypedResponse == null) { request.TryValidateResponse(new WebserviceResponse(null, null, (int?)WebSocket?.CloseStatus)); } else { request.TryValidateResponse(new WebserviceResponse(encrypedResponse.Header, Encoding.UTF8.GetBytes(Cryptography.AesDecrypt(encrypedResponse.GetAsStringContent(), Session)), (int?)WebSocket?.CloseStatus)); } return(request.WaitForResponse()); default: case EncryptionType.None: if (WebSocket == null || WebSocket.State != WebSocketState.Open) { return(null); } lock (Requests) { Requests.Add(request); } byte[] input = Encoding.UTF8.GetBytes(request.Command); await WebSocket.SendAsync(new ArraySegment <byte>(input, 0, input.Length), WebSocketMessageType.Text, true, CancellationToken.None); return(request.WaitForResponse()); } }
/// <summary> /// Throws a new WebserviceException /// </summary> /// <param name="message">The error message</param> /// <param name="response">the response that caused the error</param> public WebserviceException(string message, WebserviceResponse response) : base(message) { Response = response; }
/// <summary> /// Initialises the eventArgs /// </summary> /// <param name="response">The received Message</param> public MessageReceivedEventArgs(WebserviceResponse response) { Response = response; }