Example #1
0
 private static void AddResponseHeaders(HttpWebResponse response, HttpResponseInfo responseInfo)
 {
     foreach (string key in response.Headers.Keys)
     {
         string headerValue = response.Headers[key].Trim();
         //these headers can occur multiple times in the response
         //as per the RFC if the value is split by a comma should be
         //considered multiple message header fields however there are cases when the
         //header can contain a comma for example Date: Sun, December 23
         if (String.Compare(key, "WWW-Authenticate", true) == 0 ||
             String.Compare(key, "Proxy-Authenticate", true) == 0)
         {
             if (headerValue.StartsWith("Basic", StringComparison.OrdinalIgnoreCase) ||
                 headerValue.StartsWith("NTLM", StringComparison.OrdinalIgnoreCase) ||
                 headerValue.StartsWith("Negotiate", StringComparison.OrdinalIgnoreCase))
             {
                 //get the values
                 string[] values = headerValue.Split(',');
                 foreach (string value in values)
                 {
                     responseInfo.Headers.Add(key, value);
                 }
             }
             else
             {
                 responseInfo.Headers.Add(key, headerValue);
             }
         }
         else if (String.Compare(key, "Set-Cookie", true) == 0)
         {
             AddCookies(responseInfo, headerValue);
         }
         else
         {
             responseInfo.Headers.Add(key, headerValue);
         }
     }
 }
Example #2
0
        private void SendConnect(string host, int port)
        {
            string connectRequest = String.Format(Resources.ConnectRequest, host, port);

            byte[] connectBytes = Constants.DefaultEncoding.GetBytes(connectRequest);
            _connection.Stream.Write(connectBytes, 0, connectBytes.Length);
            //read the response

            ByteArrayBuilder builder = new ByteArrayBuilder();

            byte[] buffer    = new byte[MAX_BUFFER_SIZE];
            int    bytesRead = _connection.Stream.Read(buffer, 0, MAX_BUFFER_SIZE);

            if (bytesRead > 0)
            {
                builder.AddChunkReference(buffer, bytesRead);
            }

            if (builder.Length == 0)
            {
                throw new Exception("No response to connect");
            }
            else
            {
                HttpResponseInfo respInfo = new HttpResponseInfo();
                respInfo.ProcessResponse(builder.ToArray());
                if (respInfo.Status != 200)
                {
                    throw new Exception("Connect response didn't get 200 status");
                }
                else
                {
                    //secure the connection
                    _connection.SecureStream(host);
                }
            }
        }
 /// <summary>
 /// Override to do something with the response before returning it to the client
 /// </summary>
 /// <param name="responseInfo"></param>
 /// <returns></returns>
 protected virtual HttpResponseInfo OnBeforeResponseToClient(HttpResponseInfo responseInfo)
 {
     return(responseInfo);
 }
        /// <summary>
        /// Writes a response to the client stream
        /// </summary>
        /// <param name="responseInfo"></param>
        protected virtual void ReturnResponse(HttpResponseInfo responseInfo)
        {
            HttpServerConsole.Instance.WriteLine(LogMessageType.Information,
                                                 "Sending response: {0} for request: {1}", responseInfo.StatusLine, _requestInfo.RequestLine);


            if (_currDataStoreRequestInfo != null)
            {
                _currDataStoreRequestInfo.ResponseStatus = responseInfo.Status.ToString();
                _currDataStoreRequestInfo.ResponseTime   = DateTime.Now;
            }

            //process response headers
            if (responseInfo.Status == 401)
            {
                //we need to send the proxy support header/ or overwrite the existing proxy support header
                responseInfo.Headers["Proxy-Support"] = "Session-Based-Authentication";
            }

            //if connection is close disconnect, or if the client sent us a connection close message
            if (String.Compare(responseInfo.Headers[CONNECTION_HEADER], "close", true) == 0 ||
                String.Compare(_requestInfo.Headers[CONNECTION_HEADER], "close", true) == 0)
            {
                _isClose = true;
            }

            byte[] responseHead = HandleResponseByteChunk(responseInfo.ResponseHead);

            if (!TryWriteToStream(responseHead))
            {
                return;
            }
            ;

            // Return the substitute response body
            if (responseInfo.ResponseBody.IsChunked)
            {
                byte[] chunk;
                byte[] chunkBuf;
                while ((chunk = responseInfo.ResponseBody.ReadChunk()) != null)
                {
                    //write the chunk size line
                    chunkBuf = Constants.DefaultEncoding.GetBytes(String.Format("{0:x}\r\n", chunk.Length));
                    chunkBuf = HandleResponseByteChunk(chunkBuf);
                    if (!TryWriteToStream(chunkBuf))
                    {
                        return;
                    }
                    //write the chunk
                    chunk = HandleResponseByteChunk(chunk);
                    if (!TryWriteToStream(chunk))
                    {
                        return;
                    }
                    chunkBuf = Constants.DefaultEncoding.GetBytes("\r\n");
                    chunkBuf = HandleResponseByteChunk(chunkBuf);
                    if (!TryWriteToStream(chunkBuf))
                    {
                        return;
                    }
                }
                //write a last chunk with the value 0
                // write the last chunk size
                chunkBuf = Constants.DefaultEncoding.GetBytes("0\r\n\r\n");
                chunkBuf = HandleResponseByteChunk(chunkBuf);
                if (!TryWriteToStream(chunkBuf))
                {
                    return;
                }
            }
            else
            {
                byte[] buffer = responseInfo.ResponseBody.ToArray();
                if (buffer != null)
                {
                    buffer = HandleResponseByteChunk(buffer);
                    if (!TryWriteToStream(buffer))
                    {
                        return;
                    }
                }
            }


            //cleanup the request info
            _requestBuilder = new ByteArrayBuilder();

            if (_currDataStoreRequestInfo != null)
            {
                TrafficDataStore.SaveResponse(_currDataStoreRequestInfo.Id, _currentRequestResponseBytes);
            }

            _currDataStoreRequestInfo    = null;
            _currentRequestResponseBytes = null;

            //close the connection if the request had a connection close header
            if (_isClose)
            {
                ClientStreamWrapper.Close();
            }
            else
            {
                _isBusy = false;
                ClientStreamWrapper.BeginRead(Buffer, 0, Buffer.Length, new AsyncCallback(OnRead), ClientStreamWrapper);
            }
        }
Example #5
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="response">The result of an HttpClient send operation</param>
 /// <param name="result">The Http response, null if an error occurred</param>
 public HttpClientRequestCompleteEventArgs(HttpResponseInfo response)
 {
     _result       = HttpClientResult.Success;
     _httpResponse = response;
 }
Example #6
0
        /// <summary>
        /// Sends the request to the site
        /// </summary>
        /// <param name="requestInfo"></param>
        /// <returns></returns>
        public override HttpResponseInfo SendRequest(HttpRequestInfo requestInfo)
        {
            HttpWebRequest webRequest = WebRequest.Create(requestInfo.FullUrl) as HttpWebRequest;

            if (ShouldHandleCookies)
            {
                webRequest.CookieContainer = _cookieJar;
            }

            ProcessRequestDelay(requestInfo);

            webRequest.Timeout = _timeout;

            //attempt to reserve a connection group name for the current object
            //this will make the web request keep alive work properly
            webRequest.ConnectionGroupName = GetHashCode().ToString();

            SetNetworkSettings(webRequest);

            CopyHeaders(requestInfo, webRequest);

            //request Method (GET, POST, etc..)
            webRequest.Method = requestInfo.Method;

            string version = requestInfo.HttpVersion.Replace("HTTP/", "");

            if (!version.Equals("1.0") && !version.Equals("1.1"))
            {
                version = "1.1";
            }
            webRequest.ProtocolVersion   = Version.Parse(version);
            webRequest.AllowAutoRedirect = false;

            //add POST data, if any

            byte[] postData = requestInfo.ContentData;
            if (postData != null && postData.Length > 0)
            {
                try
                {
                    webRequest.ContentLength = postData.Length;
                    Stream requestStream = webRequest.GetRequestStream();
                    requestStream.Write(postData, 0, postData.Length);
                    requestStream.Close();
                }
                catch (ProtocolViolationException ex)                //ignore malformed request such as AppScan requests
                {
                    SdkSettings.Instance.Logger.Log(TraceLevel.Verbose, "WebRequestClient: Got a malformed request: {0}", ex.Message);
                }
            }

            HttpWebResponse response = null;

            //pass the request to the target server

            try
            {
                response = webRequest.GetResponse() as HttpWebResponse;
            }
            catch (WebException webException)
            {
                response = webException.Response as HttpWebResponse;

                if (response == null)
                {
                    throw webException;
                }
            }

            HttpResponseInfo responseInfo = null;

            //read response
            if (response != null)
            {
                string responseLine = String.Format("HTTP/{0} {1} {2}\r\n", response.ProtocolVersion, (int)response.StatusCode, response.StatusDescription);

                responseInfo = new HttpResponseInfo(responseLine);

                AddResponseHeaders(response, responseInfo);

                //add response body
                string transferEncoding = response.Headers["Transfer-Encoding"];
                responseInfo.ResponseBody.IsChunked = transferEncoding != null && String.Compare("chunked", transferEncoding, true) == 0;

                Stream responseStream = response.GetResponseStream();
                int    read;
                byte[] buffer = new byte[MAX_BUFFER_SIZE];

                while ((read = responseStream.Read(buffer, 0, MAX_BUFFER_SIZE)) > 0)
                {
                    responseInfo.ResponseBody.AddChunkReference(buffer, read);
                }

                response.Close();
            }

            return(responseInfo);
        }
Example #7
0
        /// <summary>
        /// Sends the request to the site
        /// </summary>
        /// <param name="requestInfo"></param>
        /// <returns></returns>
        public override HttpResponseInfo SendRequest(HttpRequestInfo requestInfo)
        {
            PrepareConnection(requestInfo);

            HttpClientRequest request = new HttpClientRequest(_connection);

            //check if the request requires credentials
            HttpAuthenticationInfo authInfo;

            if (HttpAuthenticationManager.Instance.RequiresCredentials(requestInfo, out authInfo))
            {
                requestInfo.Headers.Add(HttpAuthenticationManager.Instance.GetBasicAuthHeader(authInfo));
            }

            //delay the request
            ProcessRequestDelay(requestInfo);

            request.SendRequest(requestInfo, requestInfo.IsSecure);

            bool success = request.RequestCompleteEvent.WaitOne(_timeout);

            if (!success || request.Response == null)
            {
                throw new Exception(Resources.RequestTimeout);
            }
            string rawResponse    = Constants.DefaultEncoding.GetString(request.Response);
            string responseStatus = HttpResponseInfo.GetResponseStatus(rawResponse);
            bool   isPlatformAuth = String.Compare(responseStatus, "401") == 0;
            bool   isProxyAuth    = String.Compare(responseStatus, "407") == 0;

            if (isPlatformAuth || isProxyAuth)
            {
                //check the headers
                HttpResponseInfo  respInfo    = new HttpResponseInfo(rawResponse);
                List <HTTPHeader> authHeaders = new List <HTTPHeader>();
                if (isPlatformAuth)
                {
                    authHeaders = respInfo.Headers.GetHeaders("WWW-Authenticate");
                }
                else if (isProxyAuth)
                {
                    authHeaders = respInfo.Headers.GetHeaders("Proxy-Authenticate");
                }

                bool usesBasic = false;

                for (int i = authHeaders.Count - 1; i > -1; i--) //go backwards the basic header is usually last
                {
                    HTTPHeader header = authHeaders[i];
                    if (header.Value.IndexOf("Basic", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        usesBasic = true;
                        break;
                    }
                }

                if (usesBasic)
                {
                    //try to get the credentials from the user
                    authInfo = HttpAuthenticationManager.Instance.GetCredentials(requestInfo, isProxyAuth);
                    if (authInfo != null)
                    {
                        //add the basic auth header
                        requestInfo.Headers.Add(HttpAuthenticationManager.Instance.GetBasicAuthHeader(authInfo));
                        //create a new request
                        PrepareConnection(requestInfo);
                        request = new HttpClientRequest(_connection);
                        //proceed with new request
                        request.SendRequest(requestInfo, requestInfo.IsSecure);
                        success = request.RequestCompleteEvent.WaitOne(_timeout);

                        if (!success)
                        {
                            throw new Exception(Resources.RequestTimeout);
                        }
                    }
                }
            }

            if (request.Response != null)
            {
                return(new HttpResponseInfo(request.Response));
            }

            return(null);
        }