/// <summary> /// Sends the request to server. /// </summary> /// <param name="context">The context.</param> /// <returns></returns> private WebResponse SendRequestToTarget(HttpContext context) { // get the request var request = WebRequest.CreateDefault(RequestUrl); if (request == null) { throw new HttpException((int)HttpStatusCode.BadRequest, String.Format("The requested url, <{0}>, could not be found.", RequestUrl)); } // keep the same HTTP request method request.Method = context.Request.HttpMethod; var knownVerb = KnownHttpVerb.Parse(request.Method); // depending on the type of this request specific values for an HTTP request if (request is HttpWebRequest) { var httpRequest = request as HttpWebRequest; httpRequest.AllowAutoRedirect = false; httpRequest.ServicePoint.Expect100Continue = false; httpRequest.Host = ResponseUrl.Host; // add all the headers from the other proxied session to this request foreach (string name in context.Request.Headers.AllKeys) { // add the headers that are restricted in their supported manor switch (name) { case "User-Agent": httpRequest.UserAgent = context.Request.UserAgent; break; case "Connection": string connection = context.Request.Headers[name]; if (connection.IndexOf("Keep-Alive", StringComparison.OrdinalIgnoreCase) > 0) { httpRequest.KeepAlive = true; } var list = new List <string>(); foreach (string conn in connection.Split(',')) { string c = conn.Trim(); if (!c.Equals("Keep-Alive", StringComparison.OrdinalIgnoreCase) && !c.Equals("Close", StringComparison.OrdinalIgnoreCase)) { list.Add(c); } } if (list.Count > 0) { httpRequest.Connection = String.Join(", ", list.ToArray()); } break; case "Transfer-Encoding": httpRequest.SendChunked = true; httpRequest.TransferEncoding = context.Request.Headers[name]; break; case "Expect": httpRequest.ServicePoint.Expect100Continue = true; break; case "If-Modified-Since": DateTime ifModifiedSince; if (DateTime.TryParse(context.Request.Headers[name], out ifModifiedSince)) { httpRequest.IfModifiedSince = ifModifiedSince; } break; case "Content-Length": httpRequest.ContentLength = context.Request.ContentLength; break; case "Content-Type": httpRequest.ContentType = context.Request.ContentType; break; case "Accept": httpRequest.Accept = String.Join(", ", context.Request.AcceptTypes); break; case "Referer": httpRequest.Referer = context.Request.UrlReferrer.OriginalString; break; } // add to header if not restricted if (!WebHeaderCollection.IsRestricted(name, false)) { // it is nessisary to get the values for headers that are allowed to specifiy // multiple values in an instance (i.e. Cookie) string[] values = context.Request.Headers.GetValues(name); foreach (string value in values) { request.Headers.Add(name, value); } } } } // add the vanity url to the header if (Manager.Configuration.Rewriter.AllowVanityHeader) { request.Headers.Add("X-Reverse-Proxied-By", Manager.RewriterUserAgent); request.Headers.Add("X-ManagedFusion-Rewriter-Version", Manager.RewriterVersion.ToString(2)); } /* * Add Proxy Standard Protocol Headers */ // http://en.wikipedia.org/wiki/X-Forwarded-For request.Headers.Add("X-Forwarded-For", context.Request.UserHostAddress); // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.45 string currentServerName = context.Request.ServerVariables["SERVER_NAME"]; string currentServerPort = context.Request.ServerVariables["SERVER_PORT"]; string currentServerProtocol = context.Request.ServerVariables["SERVER_PROTOCOL"]; if (currentServerProtocol.IndexOf("/") >= 0) { currentServerProtocol = currentServerProtocol.Substring(currentServerProtocol.IndexOf("/") + 1); } string currentVia = String.Format("{0} {1}:{2} ({3})", currentServerProtocol, currentServerName, currentServerPort, Manager.RewriterNameAndVersion); request.Headers.Add("Via", currentVia); /* * End - Add Proxy Standard Protocol Headers */ request.Headers.Add("Host", context.Request.Headers.Get("host")); OnRequestToTarget(context, request); // ContentLength is set to -1 if their is no data to send if (request.ContentLength >= 0 && !knownVerb.ContentBodyNotAllowed) { int bufferSize = Manager.Configuration.Rewriter.Proxy.RequestSize; using (Stream requestStream = request.GetRequestStream(), bufferStream = new BufferedStream(context.Request.InputStream, Manager.Configuration.Rewriter.Proxy.BufferSize)) { byte[] buffer = new byte[bufferSize]; try { while (true) { // make sure that the stream can be read from if (!bufferStream.CanRead) { break; } int bytesReturned = bufferStream.Read(buffer, 0, bufferSize); // if not bytes were returned the end of the stream has been reached // and the loop should exit if (bytesReturned == 0) { break; } // write bytes to the response requestStream.Write(buffer, 0, bytesReturned); } } catch (Exception exc) { Manager.Log("Error on request: " + exc.Message, "Proxy"); } } } // get the response WebResponse response; try { response = request.GetResponse(); } catch (WebException exc) { Manager.Log(String.Format("Error received from {0}: {1}", request.RequestUri, exc.Message), "Proxy"); response = exc.Response; } if (response == null) { Manager.Log("No response was received, returning a '400 Bad Request' to the client.", "Proxy"); throw new HttpException((int)HttpStatusCode.BadRequest, String.Format("The requested url, <{0}>, could not be found.", RequestUrl)); } Manager.Log(response.GetType().ToString(), "Proxy"); if (response is HttpWebResponse) { var httpResponse = response as HttpWebResponse; Manager.Log(String.Format("Received '{0} {1}'", ((int)httpResponse.StatusCode), httpResponse.StatusDescription), "Proxy"); } return(response); }
/// <summary> /// Sends the request to server. /// </summary> /// <param name="context">The context.</param> /// <returns></returns> private async Task <HttpRequestMessage> GetRequestFromClient(HttpContext context) { var request = new HttpRequestMessage(new HttpMethod(context.Request.HttpMethod), RequestUrl); var content = new StreamContent(context.Request.InputStream, Manager.Configuration.Rewriter.Proxy.BufferSize); var knownVerb = KnownHttpVerb.Parse(request.Method.Method); foreach (var name in context.Request.Headers.AllKeys) { var values = context.Request.Headers.GetValues(name); request.Headers.TryAddWithoutValidation(name, values); } // send url encoded form if we have one if (context.Request.Form.Count > 0) { var formValues = new List <KeyValuePair <string, string> >(); foreach (var key in context.Request.Form.AllKeys) { var strings = context.Request.Form.GetValues(key); if (strings == null || strings.Length != 1) { continue; } formValues.Add(new KeyValuePair <string, string>(key, strings[0])); } request.Content = new FormUrlEncodedContent(formValues); } // add the vanity url to the header if (Manager.Configuration.Rewriter.AllowVanityHeader) { request.Headers.Add("X-Reverse-Proxied-By", Manager.RewriterUserAgent); request.Headers.Add("X-ManagedFusion-Rewriter-Version", Manager.RewriterVersion.ToString(2)); } /* * Add Proxy Standard Protocol Headers */ // http://en.wikipedia.org/wiki/X-Forwarded-For request.Headers.Add("X-Forwarded-For", context.Request.UserHostAddress); // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.45 string currentServerName = context.Request.ServerVariables["SERVER_NAME"]; string currentServerPort = context.Request.ServerVariables["SERVER_PORT"]; string currentServerProtocol = context.Request.ServerVariables["SERVER_PROTOCOL"]; if (currentServerProtocol.IndexOf("/") >= 0) { currentServerProtocol = currentServerProtocol.Substring(currentServerProtocol.IndexOf("/") + 1); } string currentVia = String.Format("{0} {1}:{2} ({3})", currentServerProtocol, currentServerName, currentServerPort, Manager.RewriterNameAndVersion); request.Headers.Add("Via", currentVia); /* * End - Add Proxy Standard Protocol Headers */ await OnRequestToTarget(context, request); return(request); }
/// <summary> /// Sends the request to server. /// </summary> /// <param name="context">The context.</param> /// <returns></returns> private async Task <HttpRequestMessage> GetRequestFromClient(HttpContext context) { var request = new HttpRequestMessage(new HttpMethod(context.Request.HttpMethod), RequestUrl); var content = new StreamContent(context.Request.InputStream, Manager.Configuration.Rewriter.Proxy.BufferSize); var knownVerb = KnownHttpVerb.Parse(request.Method.Method); foreach (var name in context.Request.Headers.AllKeys) { HttpHeaders headers = request.Headers; if (name.StartsWith("content", StringComparison.OrdinalIgnoreCase) || String.Equals("Allow", name, StringComparison.OrdinalIgnoreCase) || String.Equals("Expires", name, StringComparison.OrdinalIgnoreCase) || String.Equals("Last-Modified", name, StringComparison.OrdinalIgnoreCase)) { headers = content.Headers; } headers.Add(name, context.Request.Headers.GetValues(name)); } // add the vanity url to the header if (Manager.Configuration.Rewriter.AllowVanityHeader) { request.Headers.Add("X-Reverse-Proxied-By", Manager.RewriterUserAgent); request.Headers.Add("X-ManagedFusion-Rewriter-Version", Manager.RewriterVersion.ToString(2)); } /* * Add Proxy Standard Protocol Headers */ // http://en.wikipedia.org/wiki/X-Forwarded-For request.Headers.Add("X-Forwarded-For", context.Request.UserHostAddress); // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.45 string currentServerName = context.Request.ServerVariables["SERVER_NAME"]; string currentServerPort = context.Request.ServerVariables["SERVER_PORT"]; string currentServerProtocol = context.Request.ServerVariables["SERVER_PROTOCOL"]; if (currentServerProtocol.IndexOf("/") >= 0) { currentServerProtocol = currentServerProtocol.Substring(currentServerProtocol.IndexOf("/") + 1); } string currentVia = String.Format("{0} {1}:{2} ({3})", currentServerProtocol, currentServerName, currentServerPort, Manager.RewriterNameAndVersion); request.Headers.Add("Via", currentVia); /* * End - Add Proxy Standard Protocol Headers */ await OnRequestToTarget(context, request); // ContentLength is set to -1 if their is no data to send if (!knownVerb.ContentBodyNotAllowed) { request.Content = content; } return(request); }