private static IHttpSocketAdapter GetSocketConnectionToHost(string applicationPath, string requestId, string rpcMethod, bool isHttps, string hostUrl) { // The host should send an initial response immediately after // the connection is established. If it fails to do so multiple times, // stop trying. Each timeout is delaying a response to the browser. // // This will only reset when the server process is restarted. if (_filterRequestTimeouts >= FilterRequestTimeoutLimit) { return(null); } if (FindAndSignalHostConnection(applicationPath)) { return(new DelayConnectingHttpSocketAdapter(async delegate() { Uri connectionString; if (GetHostConnectionString(applicationPath, out connectionString)) { IHttpSocketAdapter httpSocket = await HttpSocketAdapter.OpenHttpSocketAsync("GET", new Uri(connectionString, rpcMethod)); AddRequestHeaders(httpSocket, requestId, isHttps, hostUrl); return httpSocket; } return null; })); } return(null); }
private async Task <IHttpSocketAdapter> CreateSocketConnectionAsync() { IHttpSocketAdapter socket = await _connectFunction.Invoke(); if (socket == null) { // Failed to create the connection, so instead we create this null // object to handle future requests with no-ops. socket = new FailedConnectionHttpSocketAdapter(); } else { if (_responseHandler != null) { socket.SetResponseHandler(_responseHandler); } foreach (KeyValuePair <string, string> header in _headers) { socket.AddRequestHeader(header.Key, header.Value); } } return(socket); }
internal ScriptInjectionFilterStream(IHttpSocketAdapter injectScriptSocket, IScriptInjectionFilterContext context) { _context = context; _outputStream = _context.ResponseBody; _injectScriptSocket = injectScriptSocket; _injectScriptSocket.SetResponseHandler(CreateResponseHandler(_outputStream)); }
private void CloseInjectScriptSocketAndBecomePassthrough() { if (_injectScriptSocket != null) { _injectScriptSocket.Dispose(); _injectScriptSocket = null; } _filterState = FilterState.Passthrough; }
private async Task ExecuteWithFilter(IHttpSocketAdapter injectScriptSocket, string requestId, HttpContext httpContext) { ScriptInjectionFilterContext filterContext = new ScriptInjectionFilterContext(httpContext); int currentPort = -1; PreprocessRequestHeader(httpContext, ref currentPort); RequestHeaders requestHeader = new RequestHeaders(httpContext.Request.Headers); if (currentPort == -1) { BrowserLinkMiddleWareUtil.RemoveETagAndTimeStamp(requestHeader); } using (ScriptInjectionFilterStream filter = new ScriptInjectionFilterStream(injectScriptSocket, filterContext)) { httpContext.Response.Body = filter; httpContext.Response.OnStarting(delegate() { if (ContentTypeUtil.IsSupportedContentTypes(httpContext.Response.ContentType)) { httpContext.Response.ContentLength = null; } ResponseHeaders responseHeader = new ResponseHeaders(httpContext.Response.Headers); BrowserLinkMiddleWareUtil.AddToETag(responseHeader, currentPort); return(StaticTaskResult.True); }); IHttpSendFileFeature originalSendFile = httpContext.Features.Get <IHttpSendFileFeature>(); httpContext.Features.Set <IHttpSendFileFeature>(new SendFilesWrapper(originalSendFile, httpContext.Response)); using (AddPageExecutionListenerFeatureTo(httpContext, requestId)) { await _next(httpContext); await filter.WaitForFilterComplete(); if (filter.ScriptInjectionTimedOut) { _filterRequestTimeouts++; } else { _filterRequestTimeouts = 0; } } } }
private static void AddRequestHeaders(IHttpSocketAdapter httpSocket, string requestId, bool isHttps, string hostUrl) { httpSocket.AddRequestHeader(BrowserLinkConstants.RequestIdHeaderName, requestId); if (isHttps) { httpSocket.AddRequestHeader(BrowserLinkConstants.RequestScheme, "https"); } else { httpSocket.AddRequestHeader(BrowserLinkConstants.RequestScheme, "http"); } httpSocket.AddRequestHeader(BrowserLinkConstants.RequestHostUrl, hostUrl); }
async Task IHttpSocketAdapter.CompleteRequest() { // If a connection hasn't been created yet, no data has been sent. // If there's no response listener, no data will be received. // If both of those are true, it's a safe bet that the connection is unnecessary. if (_connectedSocketTask == null && _responseHandler == null) { return; } else { IHttpSocketAdapter socket = await GetConnectedSocketAsync(); await socket.CompleteRequest(); } }
private PageExecutionListenerFeature AddPageExecutionListenerFeatureTo(HttpContext context, string requestId) { RequestHeaders requestHeader = new RequestHeaders(context.Request.Headers); string hostUrl = BrowserLinkMiddleWareUtil.GetRequestUrl(requestHeader); IHttpSocketAdapter mappingDataSocket = GetSocketConnectionToHost(_applicationPath, requestId, "sendMappingData", context.Request.IsHttps, hostUrl); if (mappingDataSocket != null) { PageExecutionListenerFeature listener = new PageExecutionListenerFeature(mappingDataSocket); context.Features.Set(listener); return(listener); } return(null); }
/// <summary> /// This method is called to process the response. /// </summary> internal Task Invoke(HttpContext context) { string requestId = Guid.NewGuid().ToString("N"); RequestHeaders requestHeader = new RequestHeaders(context.Request.Headers); string hostUrl = BrowserLinkMiddleWareUtil.GetRequestUrl(requestHeader); IHttpSocketAdapter injectScriptSocket = GetSocketConnectionToHost(_applicationPath, requestId, "injectScriptLink", context.Request.IsHttps, hostUrl); if (injectScriptSocket != null) { return(ExecuteWithFilter(injectScriptSocket, requestId, context)); } else { if (requestHeader.IfNoneMatch != null && BrowserLinkMiddleWareUtil.GetRequestPort(requestHeader).Count != 0) { BrowserLinkMiddleWareUtil.RemoveETagAndTimeStamp(requestHeader); } return(ExecuteWithoutFilter(context)); } }
async Task <string> IHttpSocketAdapter.GetResponseHeader(string headerName) { IHttpSocketAdapter socket = await GetConnectedSocketAsync(); return(await socket.GetResponseHeader(headerName)); }
async Task IHttpSocketAdapter.WriteToRequestAsync(byte[] buffer, int offset, int count) { IHttpSocketAdapter socket = await GetConnectedSocketAsync(); await socket.WriteToRequestAsync(buffer, offset, count); }
async Task IHttpSocketAdapter.WaitForResponseComplete() { IHttpSocketAdapter socket = await GetConnectedSocketAsync(); await socket.WaitForResponseComplete(); }
internal PageExecutionListenerFeature(IHttpSocketAdapter mappingDataSocket) { _mappingDataWriter = new MappingDataWriter(mappingDataSocket); }
/// <remarks> /// This function is the pump that pushes data from the buffers into an /// HTTP connection. It asynchronously waits on data, then asynchronously /// waits while the data is sent, then waits on more data, etc. /// </remarks> private static async void SendDataFromBuffersAsync(RevolvingBuffers <byte> buffer, IHttpSocketAdapter adapter) { while (true) { ArraySegment <byte> bufferToSend = await buffer.GetBufferedDataAsync(); if (bufferToSend.Count == 0) { break; } await adapter.WriteToRequestAsync(bufferToSend.Array, bufferToSend.Offset, bufferToSend.Count); } await adapter.CompleteRequest(); adapter.Dispose(); }
async Task <int> IHttpSocketAdapter.GetResponseStatusCode() { IHttpSocketAdapter socket = await GetConnectedSocketAsync(); return(await socket.GetResponseStatusCode()); }
internal MappingDataWriter(IHttpSocketAdapter mappingDataSocket) { _binaryWriter = new BinaryWriter(new HttpAdapterRequestStream(mappingDataSocket)); }
internal HttpAdapterRequestStream(IHttpSocketAdapter adapter) { SendDataFromBuffersAsync(_buffers, adapter); }