예제 #1
0
        /*
         *
         *
         */
        public void addElement(String pKeyLocation, String pValueLocation, Boolean pHSTSEnabled = false)
        {
            // Key value checks
            if (!Uri.IsWellFormedUriString(pKeyLocation, UriKind.Absolute))
            {
                throw new Exception("Key Uri is not well formed");
            }

            Uri lTmpUriKey = new Uri(pKeyLocation);

            if (lTmpUriKey == null || !Regex.Match(lTmpUriKey.Scheme, @"^https?$").Success)
            {
                throw new Exception("Key Uri is not well formed");
            }

            // Value URI checks
            if (!Uri.IsWellFormedUriString(pValueLocation, UriKind.Absolute))
            {
                throw new Exception("Value Uri is not well formed");
            }

            Uri lTmpUriValue = new Uri(pValueLocation);

            if (lTmpUriValue == null || !Regex.Match(lTmpUriValue.Scheme, @"^https?$").Success)
            {
                throw new Exception("Value Uri is not well formed");
            }

            if (this.NeedsRequestBeMapped(pKeyLocation))
            {
                throw new Exception("Key was already added to the cache");
            }

            Logging.LogMessage(String.Format("RedirectCache.addElement() : \"{0}\" => \"{1}\"", pKeyLocation, pValueLocation), Logging.Level.DEBUG);

            RedirectHost lTmpHost = new RedirectHost("GET", lTmpUriValue.Scheme, lTmpUriValue.Host, lTmpUriValue.PathAndQuery);

            cCache.Add(pKeyLocation, lTmpHost);
        }
        /*
         *
         *
         */
        public void HandleClientRequest(RequestObj pRequestObj)
        {
            String lHTTPRequestString = pRequestObj.ClientStreamReader.ReadLine();

            if (String.IsNullOrEmpty(lHTTPRequestString))
            {
                throw new Exception("Client request stream corrupted.");
            }

            // Read the request headers from the client and copy them to the request settings
            // Set values : METHOD scheme://host/Path
            Logging.LogMessage(String.Format("HTTPClientRequest.HandleClientRequest() : HTTP Request string: \"{0}\"", lHTTPRequestString), Logging.Level.DEBUG, pRequestObj.Counter);
            pRequestObj.parseRequestString(lHTTPRequestString);
            this.ReadRequestHeadersFromClient(pRequestObj);

            pRequestObj.Host   = pRequestObj.ClientRequestHeaders["host"].ToString();
            pRequestObj.Scheme = "http";


            /*
             * Verify if request parameters are correct.
             */
            if (!Regex.Match(pRequestObj.Method.ToLower(), @"^\s*(get|put|post|head|delete|trace|options|connect)\s*$").Success)
            {
                throw new WebException("Client request contains an unsupproted request method");
            }


            String lRequestedURL = String.Format("{0}://{1}{2}", pRequestObj.Scheme, pRequestObj.Host, pRequestObj.Path);



            /*
             *   If HTTP request was redirected to an other URL in a previous request
             *   replace current request with the redirect location
             */
            if (RedirectCache.Instance.NeedsRequestBeMapped(lRequestedURL))
            {
                Logging.LogMessage(String.Format("HTTPClientRequest.HandleClientRequest() : REDIRECT(301/302) from \"{0}\" to \"{1}\"", lRequestedURL, RedirectCache.Instance.GetElement(lRequestedURL).URL), Logging.Level.INFO, pRequestObj.Counter);

                // DO SSL STRIPPING THINGS HERE !!!!
                // Replace the URL by the URL saved in the cache ...
                RedirectHost lTmpHost = RedirectCache.Instance.GetElement(pRequestObj.getRequestedURL());

                pRequestObj.Method = "GET";
                pRequestObj.Scheme = lTmpHost.Scheme;
                pRequestObj.Host   = lTmpHost.Host;
                pRequestObj.Path   = lTmpHost.Path;

                lTmpHost.IncCounter();
            } // if (RedirectCac...


            /*
             * If HTTP request was answered with an HSTS server response header
             * conduct an HTTPS request instead of HTTP
             */
            else if (HSTSCache.Instance.GetElement(pRequestObj.Host) != null)
            {
                Logging.LogMessage(String.Format("HTTPClientRequest.HandleClientRequest() : HSTS protocol replacement : http://{0} -> https://{0} \n", pRequestObj.Host), Logging.Level.DEBUG, pRequestObj.Counter);
                pRequestObj.Scheme = "https";
            } // if (HSTSCache...


            try
            {
                /*
                 * Forward request according to the URL defined
                 * in the command line parameter.
                 */
                if (!String.IsNullOrEmpty(Config.RedirectToURL) && pRequestObj.Method.ToLower() == "get")
                {
                    HTTPRedirect.getInstance().processRequest(pRequestObj.ClientStream, Config.RedirectToURL, pRequestObj.ClientRequestHeaders);
                }
                else
                {
                    this.DoHttpProcessing(pRequestObj);
                }
            }
            catch (WebException lEx)
            {
                /*
                 * 1. Sending server response
                 */
                var lResponse = lEx.Response as HttpWebResponse;
                if (lResponse != null && lResponse.StatusCode != HttpStatusCode.OK)
                {
                    String ErrorCode = String.Format("HTTP/{0} {1} {2}\n", lResponse.ProtocolVersion, (int)lResponse.StatusCode, lResponse.StatusDescription);
                    pRequestObj.ClientStream.Write(Encoding.ASCII.GetBytes(ErrorCode), 0, ErrorCode.Length);
                }
                else
                {
                    String ErrorCode = String.Format("HTTP/1.1 500 Internal server error\n");
                    pRequestObj.ClientStream.Write(Encoding.ASCII.GetBytes(ErrorCode), 0, ErrorCode.Length);
                } // if (lRespon...

                /*
                 * 2. Sending server response headers
                 */
                if (lEx.Response != null && lEx.Response.Headers != null && lEx.Response.Headers.Count > 0)
                {
                    foreach (String la in lEx.Response.Headers.AllKeys)
                    {
                        String lResp = String.Format("{0}: {1}\n", la, lEx.Response.Headers[la]);
                        pRequestObj.ClientStream.Write(Encoding.ASCII.GetBytes(lResp), 0, lResp.Length);
                    } // foreach (Stri...
                }     // if (lEx.Resp ...

                pRequestObj.ClientStream.Write(Encoding.ASCII.GetBytes("\n"), 0, 1);

                /*
                 * 3. Sending server response body
                 */
                try
                {
                    var resp = new StreamReader(lEx.Response.GetResponseStream()).ReadToEnd();
                    pRequestObj.ClientStream.Write(Encoding.ASCII.GetBytes(resp), 0, resp.Length);
                }
                catch (Exception lEx2)
                {
                    Logging.LogMessage(String.Format("HTTPClientRequest.DoHttpProcessing(EXCEPTION2) : {0} -> {1} \n{2}", pRequestObj.getRequestedURL(), lEx.Message, lEx.StackTrace), Logging.Level.ERROR, pRequestObj.Counter);
                }
            }
            catch (Exception lEx)
            {
                Logging.LogMessage(String.Format("HTTPClientRequest.DoHttpProcessing(EXCEPTION) : {0} -> {1} \n{2}", pRequestObj.getRequestedURL(), lEx.Message, lEx.StackTrace), Logging.Level.ERROR, pRequestObj.Counter);
            }
            finally
            {
                if (pRequestObj.ClientStreamReader != null)
                {
                    pRequestObj.ClientStreamReader.Close();
                }

                if (pRequestObj.ClientStream != null)
                {
                    pRequestObj.ClientStream.Close();
                }

                if (pRequestObj.ServerWebResponse != null)
                {
                    pRequestObj.ServerWebResponse.Close();
                }
            }
        }