/// <summary> /// Starts the azure relay engine. /// </summary> public static void StartTunnelRelayEngine() { try { TunnelRelayEngine.InitializePlugins(); ServiceHost = new WebServiceHost(typeof(WCFContract)); ServiceHost.AddServiceEndpoint( typeof(WCFContract), new WebHttpRelayBinding( EndToEndWebHttpSecurityMode.Transport, RelayClientAuthenticationType.None), ApplicationData.Instance.ProxyBaseUrl) .EndpointBehaviors.Add( new TransportClientEndpointBehavior( TokenProvider.CreateSharedAccessSignatureTokenProvider( ApplicationData.Instance.ServiceBusKeyName, ApplicationData.Instance.ServiceBusSharedKey))); ServiceHost.Open(); // Ignore all HTTPs cert errors. We wanna do this after the call to Azure is made so that if Azure call presents wrong cert we bail out. ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((sender, cert, chain, errs) => true); } catch (Exception ex) { Logger.LogError(CallInfo.Site(), ex, "Failed to start Service host"); throw; } }
private async Task <Message> DeleteRequest() { return(await TunnelRelayEngine.GetResponse(WebOperationContext.Current)); }
private async Task <Message> PutRequest(Stream pStream) { return(await TunnelRelayEngine.GetResponse(WebOperationContext.Current, pStream)); }
/// <summary> /// Gets the required response from underlying service. /// </summary> /// <param name="operationContext">Current operation context.</param> /// <param name="stream">The stream to get body of incoming request..</param> /// <returns>Response from underlying service.</returns> internal static async Task <Message> GetResponse(WebOperationContext operationContext, Stream stream = null) { // Buffer the request contents into memory. MemoryStream memoryStream = null; if (stream != null) { memoryStream = new MemoryStream(); await stream.CopyToAsync(memoryStream); } var activeRequestContext = new RequestContext { IncomingRequestStream = memoryStream, IncomingWebRequest = operationContext.IncomingRequest, }; activeRequestContext.UIRequestDescription = new RequestDetails { Method = activeRequestContext.IncomingWebRequest.Method, Url = activeRequestContext.IncomingWebRequest.UriTemplateMatch.RequestUri.PathAndQuery.Replace(activeRequestContext.IncomingWebRequest.UriTemplateMatch.RequestUri.Segments[1], string.Empty), RequestHeaders = new List <HeaderDetails>(activeRequestContext.IncomingRequestHeaders.GetUIHeaderMap()), Timestamp = DateTime.Now.ToString("O"), RequestReceiveTime = DateTime.Now, RequestData = activeRequestContext.IncomingRequestStream != null ? await activeRequestContext.IncomingRequestStream.ReadToEndAsync() : string.Empty, ResponseData = string.Empty, ResponseHeaders = new List <HeaderDetails>(), StatusCode = "Active", Duration = "Active", }; try { // Fire event for request received. TunnelRelayEngine.RequestReceived?.Invoke(ApplicationData.Instance.ProxyBaseUrl, new RequestEventArgs { Request = activeRequestContext.UIRequestDescription, }); // Get new Request. HttpRequestMessage requestMessage = TunnelRelayEngine.GetInternalRequest(ref activeRequestContext); // Execute the request + call plugins. DateTime hostedServiceRequestStartTime = DateTime.Now; HttpResponseMessage response = await TunnelRelayEngine.ExecuteInternalRequestAsync(requestMessage); activeRequestContext.UIRequestDescription.Duration = (DateTime.Now - hostedServiceRequestStartTime).TotalMilliseconds + "ms"; // Copy data from response and populate UI elements. Stream readableStream = null; if (response.Content != null) { readableStream = await response.Content.ReadAsStreamAsync(); activeRequestContext.UIRequestDescription.ResponseData = await new StreamReader(readableStream).ReadToEndAsync(); readableStream.Seek(0, SeekOrigin.Begin); } else { activeRequestContext.UIRequestDescription.ResponseData = string.Empty; } response.Headers.GetUIHeaderMap().ForEach(header => activeRequestContext.UIRequestDescription.ResponseHeaders.Add(header)); activeRequestContext.UIRequestDescription.StatusCode = response.StatusCode.ToString(); // Get the Serializable response to be sent back over the wire. This response needs to be serializable by WCF standards. Message responseMessage = TunnelRelayEngine.GetOutgoingResponse(operationContext, response, readableStream); return(responseMessage); } catch (Exception ex) { activeRequestContext.UIRequestDescription.StatusCode = "Exception!!"; activeRequestContext.UIRequestDescription.ExceptionHit = true; activeRequestContext.UIRequestDescription.ResponseData = JsonConvert.SerializeObject(ex, Formatting.Indented); activeRequestContext.UIRequestDescription.Duration = (DateTime.Now - activeRequestContext.UIRequestDescription.RequestReceiveTime).TotalMilliseconds.ToString() + "ms"; Message exceptionMessage = WebOperationContext.Current.CreateTextResponse(ex.ToString()); WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.InternalServerError; return(exceptionMessage); } finally { TunnelRelayEngine.RequestUpdated?.Invoke(ApplicationData.Instance.ProxyBaseUrl, new RequestEventArgs { Request = activeRequestContext.UIRequestDescription, }); } }