public static async Task<string> CreateWebServerAsync(string remoteUrl, string baseAddress, string name, ICoreServices services, IConsole console, CancellationToken ct = default(CancellationToken)) { Uri remoteUri = new Uri(remoteUrl); UriBuilder localUri = new UriBuilder(remoteUri); WebServer server; if(!Servers.TryGetValue(remoteUri.Port, out server)) { server = new WebServer(remoteUri.Host, remoteUri.Port, baseAddress, name, services, console); await server.InitializeAsync(ct); Servers.TryAdd(remoteUri.Port, server); } server.DoWorkAsync(ct).DoNotWait(); localUri.Host = server.LocalHost; localUri.Port = server.LocalPort; return localUri.Uri.ToString(); }
public async Task GetResponseAsync(HttpListenerContext context, string localBaseUrl, string remoteBaseUrl, CancellationToken ct) { string postUri = null; if (context.Request.IsWebSocketRequest) { UriBuilder ub = new UriBuilder(PostUri) { Scheme = "wss" }; postUri = ub.Uri.ToString(); } else { postUri = PostUri.ToString(); } HttpWebRequest request = (HttpWebRequest)WebRequest.Create(postUri); request.Method = context.Request.HttpMethod; request.ServerCertificateValidationCallback += ValidateCertificate; if (!context.Request.IsWebSocketRequest) { SetRequestHeaders(request, context.Request.Headers, localBaseUrl, remoteBaseUrl); } // Add RTVS headers var remoteUri = GetRemoteUri(context.Request.Url, remoteBaseUrl); request.Headers.Add(CustomHttpHeaders.RTVSRequestedURL, remoteUri.ToString()); if (context.Request.InputStream.CanSeek && context.Request.InputStream.Length > 0) { using (Stream reqStream = await request.GetRequestStreamAsync()) { await context.Request.InputStream.CopyAndFlushAsync(reqStream, null, ct); } } HttpWebResponse response = null; try { response = (HttpWebResponse)await request.GetResponseAsync(); if (response != null) { if (context.Request.IsWebSocketRequest && response.StatusCode == HttpStatusCode.SwitchingProtocols) { Stream respStream = response.GetResponseStream(); string subProtocol = response.Headers[Constants.Headers.SecWebSocketProtocol]; var remoteWebSocket = CommonWebSocket.CreateClientWebSocket(respStream, subProtocol, TimeSpan.FromMinutes(10), receiveBufferSize: 65335, useZeroMask: true); var websocketContext = await context.AcceptWebSocketAsync(subProtocol, receiveBufferSize : 65335, keepAliveInterval : TimeSpan.FromMinutes(10)); await WebSocketHelper.SendReceiveAsync(websocketContext.WebSocket, remoteWebSocket, ct); } else { context.Response.StatusCode = (int)response.StatusCode; SetResponseHeaders(response, context.Response, localBaseUrl, remoteBaseUrl); using (Stream respStream = response.GetResponseStream()) using (Stream outStream = context.Response.OutputStream) { await respStream.CopyAndFlushAsync(outStream, null, ct); } response.Close(); } } } catch (WebException wex) when(wex.Status == WebExceptionStatus.ProtocolError) { response = wex.Response as HttpWebResponse; } catch (OperationCanceledException) { WebServer.Stop(remoteUri.Port); } catch (Exception ex) when(!ex.IsCriticalException()) { _log?.WriteLine(LogVerbosity.Normal, MessageCategory.Error, Resources.Error_RemoteWebServerException.FormatInvariant(ex.Message)); _console?.WriteErrorLine(Resources.Error_RemoteWebServerException.FormatInvariant(ex.Message)); WebServer.Stop(remoteUri.Port); } finally { response?.Close(); } }