示例#1
0
        public async Task WriteRequestAsync(MiddlemanRequest request, CancellationToken ct)
        {
            var writeStream = GetWriteStream();

            var ms = new MemoryStream(0);
            var sw = new StreamWriter(ms, HeaderEncoding) { NewLine = "\r\n" };

            sw.WriteLine("{0} {1} HTTP/1.{2}", request.Method, request.RequestUri, request.ProtocolVersion.Minor);

            for (var i = 0; i < request.Headers.Count; i++)
            {
                var key = request.Headers.GetKey(i);
                var val = request.Headers.Get(i);
                sw.WriteLine("{0}: {1}", key, val);
            }

            sw.WriteLine();
            sw.Flush();

            var reqHeaderBytes = ms.GetBuffer();
            var reqHeaders = HeaderEncoding.GetString(reqHeaderBytes.Where(x => x != 0).ToArray());

            await writeStream.WriteAsync(reqHeaderBytes, 0, (int)ms.Length, ct).ConfigureAwait(false);

            var reqBody = "";

            if (request.RequestBody != null)
            {
                var rms = new MemoryStream();

                await request.RequestBody.CopyToAsync(rms).ConfigureAwait(false);
                rms.Position = 0;
                var bytes = rms.ToArray();
                reqBody += HeaderEncoding.GetString(bytes.Where(x => x != 0).ToArray(), 0, (int)rms.Length);
                rms.Position = 0;

                await rms.CopyToAsync(writeStream).ConfigureAwait(false);
            }

            Log.Info("FORWARDED REQUEST: " + Environment.NewLine + (reqHeaders + reqBody).Trim() + Environment.NewLine);

            await writeStream.FlushAsync(ct).ConfigureAwait(false);
        }
示例#2
0
        public async Task<MiddlemanResponse> GetResponseAsync(MiddlemanContext context, MiddlemanRequest request)
        {

            if (request.Headers.AllKeys.Any(h => h.Equals("VsDebuggerCausalityData", StringComparison.InvariantCultureIgnoreCase)))
            {
                request.Headers.Remove("VsDebuggerCausalityData");
            }

            //if (request.Headers.AllKeys.Any(h => h.Equals("SOAPAction", StringComparison.InvariantCultureIgnoreCase)))
            //{
            //    request.Headers.Remove("SOAPAction");
            //}

            if (request.Headers.AllKeys.Any(
                h => h.Equals("Accept-Encoding", StringComparison.InvariantCultureIgnoreCase) && request.Headers[h].Contains("/")))
            {
                string[] parts = request.Headers["Accept-Encoding"].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Where(s => !s.Contains("/")).ToArray();

                Log.Debug("Fixed bad [Accept-Encoding] header");

                if (parts.Length > 0)
                {
                    request.Headers["Accept-Encoding"] = string.Join(",", parts);
                }
                else
                {
                    request.Headers.Remove("Accept-Encoding");
                }
            }

            if (RewriteHost)
            {
                request.Headers["Host"] = _backendUri.Host +
                                          (_backendUri.IsDefaultPort ? string.Empty : ":" + _backendUri.Port);
            }

            if (AddForwardedForHeader)
            {
                SetForwardedForHeader(context, request);
            }

            if (RemoveExpectHeader &&
                request.Headers.AllKeys.Any(
                    h => h.Equals(HttpRequestHeader.Expect.ToString(), StringComparison.InvariantCultureIgnoreCase)))
            {
                request.Headers.Remove(HttpRequestHeader.Expect);
            }

            //if (request.Headers.AllKeys.Any(h => h.Equals(HttpRequestHeader.Range.ToString(), StringComparison.InvariantCultureIgnoreCase))) 
            //    request.Headers.Remove(HttpRequestHeader.Range);

            //if (request.Headers.AllKeys.Any(h => h.Replace("-","").Equals(HttpRequestHeader.IfRange.ToString(), StringComparison.InvariantCultureIgnoreCase)))
            //    request.Headers.Remove(HttpRequestHeader.IfRange);

            //if (request.Headers.AllKeys.Any(h => h.Replace("-", "").Equals(HttpRequestHeader.IfModifiedSince.ToString(), StringComparison.InvariantCultureIgnoreCase)))
            //    request.Headers.Remove(HttpRequestHeader.IfModifiedSince);

            //if (request.Headers.AllKeys.Any(h => h.Replace("-", "").Equals(HttpRequestHeader.IfMatch.ToString(), StringComparison.InvariantCultureIgnoreCase)))
            //    request.Headers.Remove(HttpRequestHeader.IfMatch);

            //if (request.Headers.AllKeys.Any(h => h.Replace("-", "").Equals(HttpRequestHeader.IfNoneMatch.ToString(), StringComparison.InvariantCultureIgnoreCase)))
            //    request.Headers.Remove(HttpRequestHeader.IfNoneMatch);

            var sw = Stopwatch.StartNew();

            IPAddress ip;

            if (_backendUri.HostNameType == UriHostNameType.IPv4)
            {
                ip = IPAddress.Parse(_backendUri.Host);
            }
            else
            {
                var ipAddresses = await Dns.GetHostAddressesAsync(_backendUri.Host);
                ip = ipAddresses.FirstOrDefault(o => !o.ToString().Contains(":"));
            }

            var backendEp = new IPEndPoint(ip, _backendUri.Port);

            Log.Debug("{0}: Resolved upstream server to {1} in {2}ms, opening connection",
                context.InboundConnection.RemoteEndPoint, backendEp, sw.Elapsed.TotalMilliseconds);

            if (_backendUri.Scheme != "https")
                await context.OpenOutboundConnectionAsync(backendEp);
            else
                await context.OpenSecureOutboundConnectionAsync(backendEp, _backendUri.Host);

            Log.Debug("{0}: Outbound connection established, sending request",
                context.InboundConnection.RemoteEndPoint);
            sw.Restart();
            await context.OutboundConnection.WriteRequestAsync(request);
            Log.Debug("{0}: Handler sent request in {1}ms", context.InboundConnection.RemoteEndPoint,
                sw.Elapsed.TotalMilliseconds);

            var response = await context.OutboundConnection.ReadResponseAsync();

            return response;
        }
示例#3
0
        private void SetForwardedForHeader(MiddlemanContext context, MiddlemanRequest request)
        {
            var remoteAddress = context.InboundConnection.RemoteEndPoint.Address.ToString();
            var currentForwardedFor = request.Headers["X-Forwarded-For"];

            request.Headers["X-Forwarded-For"] = string.IsNullOrEmpty(currentForwardedFor)
                ? remoteAddress
                : currentForwardedFor + ", " + remoteAddress;
        }
示例#4
0
 public Task WriteRequestAsync(MiddlemanRequest request)
 {
     return WriteRequestAsync(request, CancellationToken.None);
 }