public void PUT_Verb()
        {
            // arrange
            var verb = "PUT";

            // act
            var result = KnownHttpVerb.Parse(verb);

            // assert
            Assert.AreEqual(verb, result.Name);
            Assert.IsFalse(result.ConnectRequest);
            Assert.IsFalse(result.ContentBodyNotAllowed);
            Assert.IsFalse(result.ExpectNoContentResponse);
            Assert.IsTrue(result.RequireContentBody);
        }
示例#2
0
        protected HttpWebResponse(SerializationInfo serializationInfo, StreamingContext streamingContext)
            : base(serializationInfo, streamingContext)
        {
            m_HttpResponseHeaders = (WebHeaderCollection)serializationInfo.GetValue("m_HttpResponseHeaders", typeof(WebHeaderCollection));
            m_Uri = (Uri)serializationInfo.GetValue("m_Uri", typeof(Uri));
#if !FEATURE_PAL
            m_Certificate = (X509Certificate)serializationInfo.GetValue("m_Certificate", typeof(X509Certificate));
#endif // !FEATURE_PAL
            Version version = (Version)serializationInfo.GetValue("m_Version", typeof(Version));
            m_IsVersionHttp11   = version.Equals(HttpVersion.Version11);
            m_StatusCode        = (HttpStatusCode)serializationInfo.GetInt32("m_StatusCode");
            m_ContentLength     = serializationInfo.GetInt64("m_ContentLength");
            m_Verb              = KnownHttpVerb.Parse(serializationInfo.GetString("m_Verb"));
            m_StatusDescription = serializationInfo.GetString("m_StatusDescription");
            m_MediaType         = serializationInfo.GetString("m_MediaType");
        }
示例#3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="HttpWebResponseSocks" /> class.
        /// </summary>
        /// <param name="responseUri">The response URI.</param>
        /// <param name="verb">The verb.</param>
        /// <param name="statusCode">The status code.</param>
        /// <param name="responseHeaders">The response headers.</param>
        /// <param name="responseStream">The response stream.</param>
        /// <exception cref="InvalidOperationException"></exception>
        internal HttpWebResponseSocks(Uri responseUri, KnownHttpVerb verb, HttpStatusCode statusCode, WebHeaderCollection responseHeaders, Stream responseStream)
        {
            StatusCode       = statusCode;
            Headers          = responseHeaders;
            ResponseUri      = responseUri;
            _socksConnection = null;
            _verb            = verb;

            // Build stream object for WebResponse
            string contentEncodingKey;
            DecompressionMethods compressionMethod;

            if (!Headers.ContainsHeaderKey(HttpResponseHeader.ContentEncoding.ToString(), out contentEncodingKey) ||
                !Enum.TryParse(Headers[contentEncodingKey], true, out compressionMethod))
            {
                _responseStream = responseStream;
                return;
            }

            // If content encoding is
            var contentEncoding = Headers[contentEncodingKey].Trim().ToLowerInvariant();

            switch (compressionMethod)
            {
            case DecompressionMethods.GZip:
                _responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                Headers[HttpRequestHeader.ContentLength] = "-1";
                break;

            case DecompressionMethods.Deflate:
                _responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
                Headers[HttpRequestHeader.ContentLength] = "-1";
                break;

            default:
                throw new InvalidOperationException($"Unknown encoding type '{contentEncoding}'");
            }
        }
示例#4
0
        internal HttpWebResponse(Uri responseUri, KnownHttpVerb verb, CoreResponseData coreData, string mediaType, bool usesProxySemantics, DecompressionMethods decompressionMethod)
        {
            m_Uri                = responseUri;
            m_Verb               = verb;
            m_MediaType          = mediaType;
            m_UsesProxySemantics = usesProxySemantics;

            m_ConnectStream       = coreData.m_ConnectStream;
            m_HttpResponseHeaders = coreData.m_ResponseHeaders;
            m_ContentLength       = coreData.m_ContentLength;
            m_StatusCode          = coreData.m_StatusCode;
            m_StatusDescription   = coreData.m_StatusDescription;
            m_IsVersionHttp11     = coreData.m_IsVersionHttp11;


            //if the returned contentlength is zero, preemptively invoke calldone on the stream.
            //this will wake up any pending reads.
            if (m_ContentLength == 0 && m_ConnectStream is ConnectStream)
            {
                ((ConnectStream)m_ConnectStream).CallDone();
            }

            // handle Content-Location header, by combining it with the orginal request.
            string contentLocation = m_HttpResponseHeaders[HttpKnownHeaderNames.ContentLocation];

            if (contentLocation != null)
            {
                try
                {
                    m_Uri = new Uri(m_Uri, contentLocation);
                }
                catch (UriFormatException e)
                {
                    GlobalLog.Assert("Exception on response Uri parsing.", e.ToString());
                }
            }
            // decompress responses by hooking up a final response Stream - only if user required it
            if (decompressionMethod != DecompressionMethods.None)
            {
                string contentEncoding = m_HttpResponseHeaders[HttpKnownHeaderNames.ContentEncoding];
                if (contentEncoding != null)
                {
                    if (((decompressionMethod & DecompressionMethods.GZip) != 0) && contentEncoding.IndexOf(HttpWebRequest.GZipHeader) != -1)
                    {
                        m_ConnectStream = new GZipWrapperStream(m_ConnectStream, CompressionMode.Decompress);
                        m_ContentLength = -1; // unknown on compressed streams

                        // Setting a response header after parsing will ruin the Common Header optimization.
                        // This seems like a corner case.  ContentEncoding could be added as a common header, with a special
                        // property allowing it to be nulled.
                        m_HttpResponseHeaders[HttpKnownHeaderNames.ContentEncoding] = null;
                    }
                    else if (((decompressionMethod & DecompressionMethods.Deflate) != 0) && contentEncoding.IndexOf(HttpWebRequest.DeflateHeader) != -1)
                    {
                        m_ConnectStream = new DeflateWrapperStream(m_ConnectStream, CompressionMode.Decompress);
                        m_ContentLength = -1; // unknown on compressed streams

                        // Setting a response header after parsing will ruin the Common Header optimization.
                        // This seems like a corner case.  ContentEncoding could be added as a common header, with a special
                        // property allowing it to be nulled.
                        m_HttpResponseHeaders[HttpKnownHeaderNames.ContentEncoding] = null;
                    }
                }
            }
        }
示例#5
0
    /// <summary>
    /// Equalses the specified verb.
    /// </summary>
    /// <param name="verb">The verb.</param>
    /// <returns></returns>
    public bool Equals(KnownHttpVerb verb) {
      if (this != verb)
        return String.Compare(Name, verb.Name, StringComparison.OrdinalIgnoreCase) == 0;

      return true;
    }
示例#6
0
        /// <summary>
        /// Creates a request to the specified URI.
        /// </summary>
        /// <param name="uri">The URI to send request to.</param>
        /// <param name="type">Request type.</param>
        /// <param name="requestData">Request data.</param>
        /// <param name="settings">Request settings.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException">Only http://xxxx and https://xxxx URI are supported!</exception>
        public static IWebRequestResult Create(
            Uri uri,
            KnownHttpVerb type = KnownHttpVerb.Get,
            Dictionary <string, string> requestData = null,
            WebRequestSettings settings             = null
            )
        {
            if (!uri.Scheme.Equals("http") && !uri.Scheme.Equals("https"))
            {
                throw new NotImplementedException("Only http://xxxx and https://xxxx URI are supported!");
            }

            var requestDataString = string.Empty;

            if (requestData != null && requestData.Any())
            {
                // Aggregate all the parameters in a query string
                requestDataString = string.Join("&", requestData.Select(varSet => $"{HttpUtility.UrlPathEncode(varSet.Key)}={HttpUtility.UrlEncode(varSet.Value)}"));
            }

            // Append data in GET/HEAD format
            switch (type)
            {
            case KnownHttpVerb.Get:
            case KnownHttpVerb.Head:
                var ub = new UriBuilder(uri);
                ub.Query = (string.IsNullOrWhiteSpace(ub.Query))
                        ? requestDataString
                        : $"{ub.Query}&{requestDataString}";
                uri = ub.Uri;
                break;
            }

            // Create web request (request type is based on proxy type)
            var requestResult = (settings?.Proxy is WebProxySocks)
                ? HttpWebRequestSocksResult.Create(uri)
                : HttpWebRequestResult.Create(uri);

            // Set request proxy
            requestResult.Request.Proxy = settings?.Proxy;

            // Set HTTP request type (POST, GET etc)
            requestResult.Request.Method = type.ToString().ToUpperInvariant();

            // Override headers if needed
            if (settings?.Headers != null)
            {
                requestResult.AddHeaders(settings.Headers);
            }

            // Set request encoding
            var requestEncoding = settings?.Encoding ?? Encoding.UTF8;

            if (settings?.Headers.ContainsKey(HttpRequestHeader.AcceptCharset) ?? false && string.IsNullOrWhiteSpace(settings?.Headers[HttpRequestHeader.AcceptCharset]))
            {
                requestResult.Request.Headers[HttpRequestHeader.AcceptCharset] = requestEncoding.WebName;
            }

            // Forcibly set a ContentType header on POST/PUT/DELETE request
            switch (type)
            {
            case KnownHttpVerb.Post:
            case KnownHttpVerb.Put:
                // Set content type if it is empty
                if (string.IsNullOrWhiteSpace(requestResult.Request.ContentType))
                {
                    requestResult.Request.ContentType = "application/x-www-form-urlencoded";
                }

                // Send request BODY if needed
                var postDataBytes = requestEncoding.GetBytes(requestDataString);
                requestResult.Request.ContentLength = postDataBytes.Length;
                using (var stream = requestResult.Request.GetRequestStream())
                {
                    stream.Write(postDataBytes, 0, postDataBytes.Length);
                    stream.Close();
                }
                break;

            default:
                if (string.IsNullOrWhiteSpace(requestResult.Request.ContentType))
                {
                    requestResult.Request.ContentType = $"text/html; charset={requestEncoding.WebName}";
                }
                break;
            }

            return(requestResult);
        }
示例#7
0
    /// <summary>
    /// Parses the specified name.
    /// </summary>
    /// <param name="name">The name.</param>
    /// <returns></returns>
    public static KnownHttpVerb Parse(string name) {
      KnownHttpVerb verb;

      if (!NamedHeaders.TryGetValue(name, out verb))
        verb = new KnownHttpVerb(name, false, false, false, false);

      return verb;
    }
示例#8
0
        //private bool IncrementRequestCount(ApplicationInstance instance)
        //{
        //    LbIncrementRequestCountRequest request = new LbIncrementRequestCountRequest(Settings.Credentials);
        //    request.ApplicationId = instance.ApplicationId;
        //    request.InstanceId = instance.Id;
        //    EndPoints.LoadBalancerWebService.IncrementRequestCount(request);
        //    return true;
        //}

        //private void DecrementRequestCount(ApplicationInstance instance)
        //{
        //    LbDecrementRequestCountRequest request = new LbDecrementRequestCountRequest(Settings.Credentials);
        //    request.ApplicationId = instance.ApplicationId;
        //    request.InstanceId = instance.Id;
        //    EndPoints.LoadBalancerWebService.DecrementRequestCount(request);
        //}

        /// <summary>
        /// Sends the request to server
        /// Implemented using Managed Fusion URL Rewriter
        /// Reference: http://www.managedfusion.com/products/url-rewriter/
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private WebResponse SendRequestToTarget(HttpContext context, Uri requestUrl, ReverseProxyContext rpContext, out bool incremented)
        {
            incremented = false;
            // get the request
            WebRequest request = WebRequest.CreateDefault(requestUrl);

            if (request == null)
            {
                throw new HttpException((int)HttpStatusCode.BadRequest, "The requested url, <" + requestUrl + ">, could not be found.");
            }

            // 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;

                // 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;
                        }

                        List <string> 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 Proxy Standard Protocol Headers
            // http://en.wikipedia.org/wiki/X-Forwarded-For
            request.Headers.Add("X-Forwarded-For", context.Request.UserHostAddress);
            // Add Server Variables
            // 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, "Monoscape.LoadBalancerController");

            request.Headers.Add("Via", currentVia);

            //
            // ContentLength is set to -1 if their is no data to send
            if ((request.ContentLength >= 0) && (!knownVerb.ContentBodyNotAllowed))
            {
                int bufferSize = 64 * 1024;
                using (Stream requestStream = request.GetRequestStream(), bufferStream = new BufferedStream(context.Request.InputStream, 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 e)
                    {
                        Log.Error(typeof(ProxyHandler), "", e);
                    }
                }
            }

            WebResponse response;

            try
            {
                // Increment application instance request count
                //incremented = IncrementRequestCount(rpContext.ApplicationInstance);
                if (addReqResult != null)
                {
                    int requestId = rpContext.AddReqCaller.EndInvoke(addReqResult);
                    // Remove request from load balancer request queue
                    ASyncRemoveRequestFromQueue caller = new ASyncRemoveRequestFromQueue(RemoveRequestFromQueue);
                    caller.BeginInvoke(requestId, null, null);
                }
                // Send request to the proxy target
                response = request.GetResponse();
            }
            catch (WebException e)
            {
                Log.Error(typeof(ProxyHandler), "Error received from " + request.RequestUri + ": " + e.Message, e);
                response = e.Response;
            }

            if (response == null)
            {
                Log.Error(typeof(ProxyHandler), "The requested url " + requestUrl + " could not be found.");
                throw new HttpException((int)HttpStatusCode.NotFound, "The requested url could not be found.");
            }

            Log.Info(typeof(ProxyHandler), response.GetType().ToString());
            if (response is HttpWebResponse)
            {
                HttpWebResponse httpResponse = response as HttpWebResponse;
                Log.Info(typeof(ProxyHandler), "Received '" + ((int)httpResponse.StatusCode) + " " + httpResponse.StatusDescription + "'");
            }
            return(response);
        }
示例#9
0
 public bool Equals(KnownHttpVerb verb)
 {
     return this==verb || string.Compare(Name, verb.Name, StringComparison.OrdinalIgnoreCase)==0;
 }
示例#10
0
 public static KnownHttpVerb Parse(string name)
 {
     KnownHttpVerb knownHttpVerb = NamedHeaders[name] as KnownHttpVerb;
     if (knownHttpVerb==null) {
         // unknown verb, default behaviour
         knownHttpVerb = new KnownHttpVerb(name, false, false, false, false);
     }
     return knownHttpVerb;
 }
示例#11
0
 //
 // InitializeKnownVerbs - Does basic init for this object,
 //  such as creating defaultings and filling them
 //
 static KnownHttpVerb()
 {
     NamedHeaders = new ListDictionary(CaseInsensitiveAscii.StaticInstance);
     Get = new KnownHttpVerb("GET", false, true, false, false);
     Connect = new KnownHttpVerb("CONNECT", false, true, true, false);
     Head = new KnownHttpVerb("HEAD", false, true, false, true);
     Put = new KnownHttpVerb("PUT", true, false, false, false);
     Post = new KnownHttpVerb("POST", true, false, false, false);
     MkCol = new KnownHttpVerb("MKCOL",false,false,false,false);
     NamedHeaders[Get.Name] = Get;
     NamedHeaders[Connect.Name] = Connect;
     NamedHeaders[Head.Name] = Head;
     NamedHeaders[Put.Name] = Put;
     NamedHeaders[Post.Name] = Post;
     NamedHeaders[MkCol.Name] = MkCol;
 }