Пример #1
0
        HttpRequestMessage CreateHttpRequestMessage(RelayedHttpListenerContext context)
        {
            var requestMessage = new HttpRequestMessage();

            if (context.Request.HasEntityBody)
            {
                requestMessage.Content = new StreamContent(context.Request.InputStream);
                string contentType = context.Request.Headers[HttpRequestHeader.ContentType];
                if (!string.IsNullOrEmpty(contentType))
                {
                    requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
                }
            }

            string relativePath = context.Request.Url.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);

            relativePath = relativePath.Replace(this.hybridConnectionSubpath, string.Empty, StringComparison.OrdinalIgnoreCase);
            requestMessage.RequestUri = new Uri(relativePath, UriKind.RelativeOrAbsolute);
            requestMessage.Method     = new HttpMethod(context.Request.HttpMethod);

            foreach (var headerName in context.Request.Headers.AllKeys)
            {
                if (string.Equals(headerName, "Host", StringComparison.OrdinalIgnoreCase) ||
                    string.Equals(headerName, "Content-Type", StringComparison.OrdinalIgnoreCase))
                {
                    // Don't flow these headers here
                    continue;
                }

                requestMessage.Headers.Add(headerName, context.Request.Headers[headerName]);
            }

            return(requestMessage);
        }
Пример #2
0
        private void RequestHandler(RelayedHttpListenerContext context)
        {
            try
            {
                this.logger?.LogMessage(LogLevel.Verbose, $"Request: {context.Request.HttpMethod} {context.Request.Url.AbsolutePath}");
                PluginMethod method = this.FindMethod(context.Request.Url.AbsolutePath, context.Request.HttpMethod);
                if (method == null)
                {
                    string message = $"Method not found. Uri = {context.Request.Url.AbsoluteUri}, Method = {context.Request.HttpMethod}";

                    this.logger?.LogMessage(LogLevel.Warning, message);

                    context.Response.StatusCode        = HttpStatusCode.NotFound;
                    context.Response.StatusDescription = message;
                    return;
                }

                try
                {
                    this.logger?.LogMessage(LogLevel.Verbose, $"Execute: {method}");
                    method.Invoke(context);
                }
                catch (Exception e)
                {
                    context.Response.StatusCode = HttpStatusCode.InternalServerError;
                    this.logger?.LogException(e);
                }
            }
            finally
            {
                context.Response.Close();
            }
        }
Пример #3
0
        private void RequestHandler(RelayedHttpListenerContext context)
        {
            var streamReader = new StreamReader(context.Request.InputStream);
            // reading the body
            var requestContent = streamReader.ReadToEnd();


            var message = JsonConvert.DeserializeObject <RemoteDebuggerMessage>(requestContent);

            CurrentResponseCache.AddOrUpdate(message.PluginExecutionId, context.Response, (guid, response) => context.Response);

            if (message.MessageType == RemoteDebuggerMessageType.Context)
            {
                var remoteContext = message.GetContext <RemoteDebugExecutionContext>();
                OnContextReceived(remoteContext);

                MessageSendCache.TryAdd(remoteContext.Id, new RemoteDebuggerMessage(RemoteDebuggerMessageType.Context, remoteContext, remoteContext.Id));
            }

            if (message.MessageType == RemoteDebuggerMessageType.Response)
            {
                MessageReceiveCache.TryAdd(message.PluginExecutionId, message);

                RemoteDebuggerMessage response;
                while (!MessageSendCache.TryRemove(message.PluginExecutionId, out response))
                {
                    // Waiting for the response to come
                    Thread.Sleep(50);
                }

                //Console.WriteLine("{0}", response);

                SendMessage(response);
            }
        }
Пример #4
0
        static void ProcessEventGridEvents(RelayedHttpListenerContext context)
        {
            var content = new StreamReader(context.Request.InputStream).ReadToEnd();

            EventGridEvent[] eventGridEvents = JsonConvert.DeserializeObject <EventGridEvent[]>(content);

            foreach (EventGridEvent eventGridEvent in eventGridEvents)
            {
                Console.WriteLine($"Received event {eventGridEvent.Id} with type:{eventGridEvent.EventType}");
                JObject dataObject = eventGridEvent.Data as JObject;

                if (string.Equals(eventGridEvent.EventType, StorageBlobCreatedEvent, StringComparison.OrdinalIgnoreCase))
                {
                    // Deserialize the data portion of the event into StorageBlobCreatedEventData
                    var eventData = dataObject.ToObject <StorageBlobCreatedEventData>();
                    Console.WriteLine($"Got BlobCreated event data, blob URI {eventData.Url}");
                }
                else if (string.Equals(eventGridEvent.EventType, CustomTopicEvent, StringComparison.OrdinalIgnoreCase))
                {
                    // Deserialize the data portion of the event into ContosoItemReceivedEventData
                    var eventData = dataObject.ToObject <ContosoItemReceivedEventData>();
                    Console.WriteLine($"Got ContosoItemReceived event data, item SKU {eventData.ItemSku}");
                }
                else
                {
                    // This can be extended to any event type that Event Grid supports.
                    Console.WriteLine($"Event with type {eventGridEvent.EventType} received, use proper type to deserialize data object");
                }
            }
        }
 public RequestContext(RelayedHttpListenerContext innerContext, Uri baseUri)
 {
     _cts                = new CancellationTokenSource();
     _innerContext       = innerContext;
     _response           = new Response(_innerContext.Response, baseUri);
     _request            = new Request(_innerContext.Request, baseUri);
     IsUpgradableRequest = false;
 }
Пример #6
0
        void SendErrorResponse(Exception e, RelayedHttpListenerContext context)
        {
            context.Response.StatusCode = HttpStatusCode.InternalServerError;

#if DEBUG || INCLUDE_ERROR_DETAILS
            context.Response.StatusDescription = $"Internal Server Error: {e.GetType().FullName}: {e.Message}";
#endif
            context.Response.Close();
        }
Пример #7
0
        void LogRequest(DateTime startTimeUtc, RelayedHttpListenerContext context)
        {
            DateTime      stopTimeUtc = DateTime.UtcNow;
            StringBuilder buffer      = new StringBuilder();

            buffer.Append($"{startTimeUtc.ToString("s", CultureInfo.InvariantCulture)}, ");
            buffer.Append($"\"{context.Request.HttpMethod} {context.Request.Url.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped)}\", ");
            buffer.Append($"{(int)context.Response.StatusCode}, ");
            buffer.Append($"{(int)stopTimeUtc.Subtract(startTimeUtc).TotalMilliseconds}");
            Console.WriteLine(buffer);
        }
Пример #8
0
        /// <summary>
        /// Invoke the method using reflection.
        /// </summary>
        /// <param name="context">The listener context</param>
        internal void Invoke(RelayedHttpListenerContext context)
        {
            var result = this.MethodInfo.Invoke(this.Plugin, this.PrepareArguments(context.Request.Url.Query));

            if (result != null)
            {
                using (var sw = new StreamWriter(context.Response.OutputStream))
                {
                    sw.WriteLine(result.ToString());
                }
            }
        }
Пример #9
0
        private static void HandleReceivedRequest(RelayedHttpListenerContext context, ILogger logger)
        {
            using (var requestStreamReader = new StreamReader(context.Request.InputStream))
            {
                var rawEvents = requestStreamReader.ReadToEnd();

                logger.LogInformation("New request was received - {rawEvents}", rawEvents);
                StoreReceivedEvents(rawEvents, logger);
            }

            // The context MUST be closed here
            context.Response.Close();
        }
Пример #10
0
        public static void ProcessRelayedHttpRequest(RelayedHttpListenerContext context)
        {
            // Do something with context.Request.Url, HttpMethod, Headers, InputStream...
            context.Response.StatusCode        = HttpStatusCode.OK;
            context.Response.StatusDescription = "OK";
            using (var sw = new StreamWriter(context.Response.OutputStream))
            {
                sw.WriteLine("Current date and time for me is: " + DateTime.Now.ToString());
            }

            // The context MUST be closed here
            context.Response.Close();
        }
Пример #11
0
        static void LogHttpRequest(RelayedHttpListenerContext context, TraceSource traceSource)
        {
            string requestBody = new StreamReader(context.Request.InputStream).ReadToEnd();
            string output      = $"Request:  {context.Request.HttpMethod} {context.Request.Url} ";

            if (traceSource.Switch.ShouldTrace(TraceEventType.Verbose) && !string.IsNullOrEmpty(requestBody))
            {
                output += Environment.NewLine + requestBody + Environment.NewLine;
            }

            output += $"({requestBody.Length} bytes, {context.TrackingContext.TrackingId})";
            traceSource.TraceInformation(output);
        }
Пример #12
0
        /// <summary>
        /// Handles the HTTP request received over the hybrid connection.
        /// </summary>
        /// <param name="context">Relayed request context.</param>
        /// <returns>Task tracking operation.</returns>
        private async Task HandleProxyRequestAsync(RelayedHttpListenerContext context)
        {
            RelayRequest relayRequest = new RelayRequest
            {
                Headers              = context.Request.Headers,
                HttpMethod           = new HttpMethod(context.Request.HttpMethod),
                InputStream          = context.Request.InputStream,
                RequestPathAndQuery  = context.Request.Url.AbsoluteUri.Substring(this.relayUrl.Length),
                RequestStartDateTime = DateTimeOffset.Now,
            };

            try
            {
                RelayResponse relayResponse = await this.relayManager.HandleRelayRequestAsync(relayRequest).ConfigureAwait(false);

                context.Response.StatusCode        = relayResponse.HttpStatusCode;
                context.Response.StatusDescription = relayResponse.StatusDescription;

                // Copy over outgoing headers.
                foreach (string headerName in relayResponse.Headers.Keys)
                {
                    // Not copying over the Transfer-Encoding header as the communication between server and Relay, and Relay and client are
                    // different connections.
                    if (headerName.Equals("Transfer-Encoding", StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    context.Response.Headers[headerName] = relayResponse.Headers[headerName];
                }

                if (relayResponse.OutputStream != null)
                {
                    await relayResponse.OutputStream.CopyToAsync(context.Response.OutputStream).ConfigureAwait(false);
                }

                await context.Response.CloseAsync().ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                context.Response.StatusCode        = HttpStatusCode.InternalServerError;
                context.Response.StatusDescription = "Exception occurred at Server";

                byte[] errorMessage = Encoding.UTF8.GetBytes(ex.Message);
                await context.Response.OutputStream.WriteAsync(errorMessage, 0, errorMessage.Length).ConfigureAwait(false);
            }
        }
Пример #13
0
        async Task <bool> TestAcceptHandler(RelayedHttpListenerContext listenerContext)
        {
            string   delayString = listenerContext.Request.Headers[TestAcceptHandlerDelayHeader];
            TimeSpan delay;

            if (!string.IsNullOrEmpty(delayString) && TimeSpan.TryParse(delayString, out delay))
            {
                await Task.Delay(delay);
            }

            string statusCodeString = listenerContext.Request.Headers[TestAcceptHandlerStatusCodeHeader];
            int    statusCode;

            if (!string.IsNullOrEmpty(statusCodeString) && int.TryParse(statusCodeString, out statusCode))
            {
                listenerContext.Response.StatusCode = (HttpStatusCode)statusCode;
            }

            string statusDescription = listenerContext.Request.Headers[TestAcceptHandlerStatusDescriptionHeader];

            if (!string.IsNullOrEmpty(statusDescription))
            {
                listenerContext.Response.StatusDescription = statusDescription;
            }

            string responseHeaders = listenerContext.Request.Headers[TestAcceptHandlerSetResponseHeader];

            if (!string.IsNullOrEmpty(responseHeaders))
            {
                foreach (var headerAndValue in responseHeaders.Split(','))
                {
                    string[] headerNameAndValue = headerAndValue.Split(':');
                    listenerContext.Response.Headers[headerNameAndValue[0]] = headerNameAndValue[1].Trim();
                }
            }

            bool result;

            if (!bool.TryParse(listenerContext.Request.Headers[TestAcceptHandlerResultHeader], out result))
            {
                result = true;
            }

            TestUtility.Log($"Test AcceptHandler: {listenerContext.Request.Url} {(int)listenerContext.Response.StatusCode}: {listenerContext.Response.StatusDescription} returning {result}");
            return(result);
        }
        private async Task SendResponseAsync(RelayedHttpListenerContext context, HttpResponseMessage responseMessage)
        {
            context.Response.StatusCode        = responseMessage.StatusCode;
            context.Response.StatusDescription = responseMessage.ReasonPhrase;
            foreach (var header in responseMessage.Headers)
            {
                if (string.Equals(header.Key, "Transfer-Encoding"))
                {
                    continue;
                }

                context.Response.Headers.Add(header.Key, string.Join(",", header.Value));
            }

            var responseStream = await responseMessage.Content.ReadAsStreamAsync();

            await responseStream.CopyToAsync(context.Response.OutputStream);
        }
        private HttpRequestMessage CreateHttpRequestMessage(RelayedHttpListenerContext context)
        {
            var requestMessage = new HttpRequestMessage();

            if (context.Request.HasEntityBody)
            {
                requestMessage.Content = new StreamContent(context.Request.InputStream);
                // Experiment to see if I can capture the return message instead of having the bot responding directly (so far it doesn't work).
                //var contentStream = new MemoryStream();
                //var writer = new StreamWriter(contentStream);
                //var newActivity = requestMessage.Content.ReadAsStringAsync().Result.Replace("https://directline.botframework.com/", "https://localhost:44372/");
                //writer.Write(newActivity);
                //writer.Flush();
                //contentStream.Position = 0;
                //requestMessage.Content = new StreamContent(contentStream);
                var contentType = context.Request.Headers[HttpRequestHeader.ContentType];
                if (!string.IsNullOrEmpty(contentType))
                {
                    requestMessage.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
                }
            }

            var relativePath = context.Request.Url.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);

            relativePath = relativePath.Replace(_hybridConnectionSubPath, string.Empty, StringComparison.OrdinalIgnoreCase);
            requestMessage.RequestUri = new Uri(relativePath, UriKind.RelativeOrAbsolute);
            requestMessage.Method     = new HttpMethod(context.Request.HttpMethod);

            foreach (var headerName in context.Request.Headers.AllKeys)
            {
                if (string.Equals(headerName, "Host", StringComparison.OrdinalIgnoreCase) ||
                    string.Equals(headerName, "Content-Type", StringComparison.OrdinalIgnoreCase))
                {
                    // Don't flow these headers here
                    continue;
                }

                requestMessage.Headers.Add(headerName, context.Request.Headers[headerName]);
            }

            LogRequestActivity(requestMessage);

            return(requestMessage);
        }
        /// <summary>
        /// Pre-check before accept.
        /// </summary>
        /// <param name="context"></param>
        /// <returns>Successful acceptance or not</returns>
        private Task <bool> OnAcceptAsync(RelayedHttpListenerContext context)
        {
            var id = context.Request.Headers["x-Id"];

            if (!string.IsNullOrEmpty(id) && Reference.TryParse(id, out var streamId))
            {
                if (_connectionMap.TryGetValue(streamId, out var connection))
                {
                    // We correlate context and relay stream by finding
                    // the stream id in the stream's tracking id
                    if (context.ToString().ToLower().Contains(id.ToLower()))
                    {
                        return(Task.FromResult(true));
                    }
                }
            }
            ProxyEventSource.Log.ConnectionRejected(context, null);
            return(Task.FromResult(false));
        }
Пример #17
0
        async void RequestHandler(RelayedHttpListenerContext context)
        {
            DateTime startTimeUtc = DateTime.UtcNow;

            try
            {
                HttpRequestMessage  requestMessage  = CreateHttpRequestMessage(context);
                HttpResponseMessage responseMessage = await this.httpClient.SendAsync(requestMessage);
                await SendResponseAsync(context, responseMessage);

                await context.Response.CloseAsync();
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error: {e.GetType().Name}: {e.Message}");
                SendErrorResponse(e, context);
            }
            finally
            {
                LogRequest(startTimeUtc, context);
            }
        }
Пример #18
0
        void LogRequest(DateTime startTimeUtc, RelayedHttpListenerContext context)
        {
            DateTime stopTimeUtc = DateTime.UtcNow;

            _libHoney.SendNow(new Dictionary <string, object> ()
            {
                ["name"]         = "HybridConnectionReverseProxy",
                ["service_name"] = "HybridConnectionReverseProxy",
                ["duration_ms"]  = (int)stopTimeUtc.Subtract(startTimeUtc).TotalMilliseconds,
                ["method"]       = context.Request.HttpMethod,
                ["status_code"]  = $"{(int)context.Response.StatusCode}",
                ["azFunction"]   = "GetTemps",
                ["endpoint"]     = $"\"{context.Request.Url.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped)}\"",
            });
            StringBuilder buffer = new StringBuilder();

            buffer.Append($"{startTimeUtc.ToString("s", CultureInfo.InvariantCulture)}, ");
            buffer.Append($"\"{context.Request.HttpMethod} {context.Request.Url.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped)}\", ");
            buffer.Append($"{(int)context.Response.StatusCode}, ");
            buffer.Append($"{(int)stopTimeUtc.Subtract(startTimeUtc).TotalMilliseconds}");
            Console.WriteLine(buffer);
        }
Пример #19
0
        static async void SomebodyCalled(RelayedHttpListenerContext context)
        {
            //StreamReader sr = new StreamReader(context.Request.InputStream);
            Request req = await JsonSerializer
                          .DeserializeAsync <Request>(
                utf8Json : context.Request.InputStream,
                options : new JsonSerializerOptions {
                PropertyNameCaseInsensitive = true
            });

            Console.WriteLine($"Somebody called, with the following command: {req.Command}\tFilePath is : {req.FilePath}");
            context.Response.Close();
            return;

            var           files      = Directory.GetFiles(req.FilePath);
            List <object> resultList = new List <object>();

            foreach (string file in files)
            {
                resultList.Add(new { file = file });
            }

            var resultObject = resultList.ToArray();

            var json = JsonSerializer
                       .Serialize(value: resultObject, options: new JsonSerializerOptions {
                WriteIndented = true
            });

            context.Response.Headers.Add("content-type", "application/json");
            using (var sw = new StreamWriter(context.Response.OutputStream))
            {
                await sw.WriteLineAsync(json);
            }

            context.Response.Close();
        }
        private async void ListenerRequestHandler(RelayedHttpListenerContext context)
        {
            var startTimeUtc = DateTime.UtcNow;

            try
            {
                Console.WriteLine("Calling {0}...", _targetServiceAddress);
                var requestMessage  = CreateHttpRequestMessage(context);
                var responseMessage = await _httpClient.SendAsync(requestMessage);
                await SendResponseAsync(context, responseMessage);

                await context.Response.CloseAsync();
            }

            catch (Exception ex)
            {
                LogException(ex);
                SendErrorResponse(ex, context);
            }
            finally
            {
                LogRequest(startTimeUtc);
            }
        }
 private void SendErrorResponse(Exception ex, RelayedHttpListenerContext context)
 {
     context.Response.StatusCode        = HttpStatusCode.InternalServerError;
     context.Response.StatusDescription = $"Internal Server Error: {ex.GetType().FullName}: {ex.Message}";
     context.Response.Close();
 }
        async Task QueryString(EndpointTestType endpointTestType)
        {
            HybridConnectionListener listener = this.GetHybridConnectionListener(endpointTestType);

            try
            {
                RelayConnectionStringBuilder connectionString = GetConnectionStringBuilder(endpointTestType);
                Uri endpointUri = connectionString.Endpoint;

                TestUtility.Log("Calling HybridConnectionListener.Open");
                await listener.OpenAsync(TimeSpan.FromSeconds(30));

                var queryStringTests = new[]
                {
                    new { Original = "?foo=bar", Output = "?foo=bar" },
                    new { Original = "?sb-hc-id=1", Output = "" },
                    new { Original = "?sb-hc-id=1&custom=value", Output = "?custom=value" },
                    new { Original = "?custom=value&sb-hc-id=1", Output = "?custom=value" },
                    new { Original = "?sb-hc-undefined=true", Output = "" },
                    new { Original = "? Key =  Value With Space ", Output = "?+Key+=++Value+With+Space" }, // HttpUtility.ParseQueryString.ToString() in the cloud service changes this
                    new { Original = "?key='value'", Output = "?key=%27value%27" },                        // HttpUtility.ParseQueryString.ToString() in the cloud service changes this
                    new { Original = "?key=\"value\"", Output = "?key=%22value%22" },                      // HttpUtility.ParseQueryString.ToString() in the cloud service changes this
                    new { Original = "?key=<value>", Output = "?key=%3cvalue%3e" },
#if PENDING_SERVICE_UPDATE
                    new { Original = "?foo=bar&", Output = "?foo=bar&" },
                    new { Original = "?&foo=bar", Output = "?foo=bar" }, // HttpUtility.ParseQueryString.ToString() in the cloud service changes this
                    new { Original = "?sb-hc-undefined", Output = "?sb-hc-undefined" },
                    new { Original = "?CustomValue", Output = "?CustomValue" },
                    new { Original = "?custom-Value", Output = "?custom-Value" },
                    new { Original = "?custom&value", Output = "?custom&value" },
                    new { Original = "?&custom&value&", Output = "?&custom&value&" },
                    new { Original = "?&&value&&", Output = "?&&value&&" },
                    new { Original = "?+", Output = "?+" },
                    new { Original = "?%20", Output = "?+" },                                        // HttpUtility.ParseQueryString.ToString() in the cloud service changes this
                    new { Original = "? Not a key value pair ", Output = "?+Not+a+key+value+pair" }, // HttpUtility.ParseQueryString.ToString() in the cloud service changes this
                    new { Original = "?&+&", Output = "?&+&" },
                    new { Original = "?%2f%3a%3d%26", Output = "?%2f%3a%3d%26" },
#endif
                };

                RelayedHttpListenerContext actualRequestContext = null;
                listener.RequestHandler = async(context) =>
                {
                    TestUtility.Log($"RequestHandler {context.Request.HttpMethod} {context.Request.Url}");
                    actualRequestContext = context;
                    await context.Response.CloseAsync();
                };

                foreach (var queryStringTest in queryStringTests)
                {
                    string originalQueryString = queryStringTest.Original;
                    string expectedQueryString = queryStringTest.Output;
                    actualRequestContext = null;

                    TestUtility.Log($"Testing Query String '{originalQueryString}'");
                    Uri hybridHttpUri = new UriBuilder("https://", endpointUri.Host, endpointUri.Port, connectionString.EntityPath, originalQueryString).Uri;
                    using (var client = new HttpClient {
                        BaseAddress = hybridHttpUri
                    })
                    {
                        client.DefaultRequestHeaders.ExpectContinue = false;

                        var getRequest = new HttpRequestMessage();
                        getRequest.Method = HttpMethod.Get;
                        await AddAuthorizationHeader(connectionString, getRequest, hybridHttpUri);

                        LogRequestLine(getRequest, client);
                        using (HttpResponseMessage response = await client.SendAsync(getRequest))
                        {
                            LogResponseLine(response);
                            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                            Assert.Equal(expectedQueryString, actualRequestContext.Request.Url.Query);
                        }
                    }
                }

                await listener.CloseAsync(TimeSpan.FromSeconds(10));
            }
            finally
            {
                await SafeCloseAsync(listener);
            }
        }
 Task <bool> WebSocketAcceptHandler(RelayedHttpListenerContext arg)
 {
     return(Task <bool> .FromResult(true));
 }