示例#1
0
        /// <summary>
        /// Triggered before the response is sent back to the client
        /// </summary>
        /// <param name="responseInfo"></param>
        /// <returns></returns>
        protected override HttpResponseInfo OnBeforeResponseToClient(HttpResponseInfo responseInfo)
        {
            if (_responseReplacements != null && _responseReplacements.Count > 0)
            {
                string response    = responseInfo.ToString();
                bool   wasReplaced = false;

                foreach (string key in _responseReplacements.Keys)
                {
                    if (Utils.IsMatch(response, key))
                    {
                        response = Utils.ReplaceGroups(response, key, _responseReplacements[key]);
                        HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Response replacement applied for pattern: '{0}'", key);
                        wasReplaced = true;
                    }
                }

                if (wasReplaced)
                {
                    //remove chunked encoding
                    response     = Regex.Replace(response, "Transfer-Encoding:\\s?chunked\\r\\n", "", RegexOptions.IgnoreCase);
                    responseInfo = new HttpResponseInfo(response);
                }
            }

            if (!_isNonEssential)
            {
                //update tracked paterns from the response
                PatternTracker.Instance.UpdatePatternValues(responseInfo);
            }


            if (CurrDataStoreRequestInfo != null)
            {
                //trap the response (this will only occur if the trap is enabled)
                if (HttpTrap.Instance.TrapResponses)
                {
                    TrafficDataStore.SaveResponse(CurrDataStoreRequestInfo.Id, responseInfo.ToArray());

                    if (HttpTrap.Instance.TrapResponse(CurrDataStoreRequestInfo, responseInfo))
                    {
                        responseInfo = new HttpResponseInfo(TrafficDataStore.LoadResponseData(CurrDataStoreRequestInfo.Id));

                        if (responseInfo.ResponseBody != null && responseInfo.ResponseBody.IsChunked == false)
                        {
                            responseInfo.Headers["Content-Length"] = responseInfo.ResponseBody.Length.ToString();
                        }
                    }
                }

                if (_trackRequestContext)
                {
                    //replace the request with its request id
                    //store information about where the request was found in previous traffic responses stored in the
                    //current traffic file
                    TrackRequestContext(_requestInfo);
                }
            }
            return(responseInfo);
        }
        /// <summary>
        /// Writes a CRWAE message to the client when response is not available from server
        /// </summary>
        /// <param name="statusCode">HTTP status code for the response</param>
        /// <param name="reason">Brief explanation of error</param>
        /// <param name="serviceCode">ID of the CRAWE message</param>
        /// <param name="args">Message args</param>
        protected virtual void ReturnHttpErrorResponse(HttpStatusCode statusCode, string reason, ServiceCode serviceCode, params object [] args)
        {
            byte[] messageBytes = HttpErrorResponse.GenerateHttpErrorResponse(statusCode, reason, serviceCode, args);
            if (!TryWriteToStream(messageBytes))
            {
                return;
            }

            //add the response if we are adding requests to the data source
            if (_currDataStoreRequestInfo != null)
            {
                _currDataStoreRequestInfo.ResponseStatus = statusCode.ToString();
                _currDataStoreRequestInfo.ResponseTime   = DateTime.Now;
                TrafficDataStore.SaveResponse(_currDataStoreRequestInfo.Id, messageBytes);
                _currDataStoreRequestInfo = null;
            }
            ClientStreamWrapper.Close();
        }
        /// <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);
            }
        }