Example #1
0
        // Process the given tcpStream until either
        // - ProcessStatus.Error OR
        // - ProcessStatus.NeedMoreData OR
        // - ProcessStatus.Completed
        //
        // ProcessStatus.Continue is hidden as this method will simply
        // loop internally, asking the current HttpMessage to continue processing
        //
        // see HttpMessage.Process() for return values from this method as they
        // are the same
        private HttpMessage.ProcessStatus HandleTcpStreamGenerator(TcpStreamGenerator tcpStreamGenerator)
        {
            var tcpStream   = tcpStreamGenerator.tcpStream;
            var monitorType = tcpStreamGeneratorToMonitorType[tcpStreamGenerator];

            if (IsDebugEnabled)
            {
                log.DebugFormat("monitorType: {0}", monitorType);
            }

            HttpMessage theMessage = null;

            // retrieve the pending message or create and assign a new one if there
            // is no pending message
            if (monitorType == MonitorTypes.Client)
            {
                if (pendingRequest == null)
                {
                    if (IsDebugEnabled)
                    {
                        log.Debug("No pendingRequest, creating a new one");
                    }
                    pendingRequest = new HttpRequest();
                }

                theMessage = pendingRequest;
            }
            else if (monitorType == MonitorTypes.Server)
            {
                if (pendingStatus == null)
                {
                    if (IsDebugEnabled)
                    {
                        log.Debug("no pendingStatus, creating a new one");
                    }
                    pendingStatus = new HttpStatus();
                }

                theMessage = pendingStatus;
            }

            BinaryReader br = new BinaryReader(tcpStream);

            // default to NeedMoreData since that would be our state if
            // we didn't get into the while() loop due to running out of data
            HttpMessage.ProcessStatus status = HttpMessage.ProcessStatus.NeedMoreData;

            // outer loop runs while we have bytes to process
            //
            // NOTE: We can process until we run out of data because we re-use
            // the same message for the given TcpStream
            while (br.BaseStream.Position < br.BaseStream.Length)
            {
                // if we haven't identified the monitor type yet, attempt to do so now
                if (monitorType == HttpSessionWatcher.MonitorTypes.Unknown)
                {
                    // attempt to process as a request
                    // NOTE: Must assign pendingRequest BEFORE calling ProcessBinaryReader()
                    // which may pass the object if processing completes
                    pendingRequest = new HttpRequest();
                    status         = ProcessBinaryReader(pendingRequest, MonitorTypes.Client, br);
                    if (status == HttpMessage.ProcessStatus.Error)
                    {
                        pendingRequest = null;

                        // attempt to process as a status
                        // NOTE: Must assign pendingStatus BEFORE calling ProcessBinaryReader()
                        // which may pass the object if processing completes
                        pendingStatus = new HttpStatus();
                        status        = ProcessBinaryReader(pendingStatus, MonitorTypes.Server, br);
                        if (status == HttpMessage.ProcessStatus.Error)
                        {
                            pendingStatus = null;
                            return(status);
                        }
                        else   // success
                        {
                            theMessage  = pendingStatus;
                            monitorType = HttpSessionWatcher.MonitorTypes.Server;

                            // assign the monitor type
                            SetTypeForTcpStreamGenerator(tcpStreamGenerator, monitorType);
                        }
                    }
                    else   // success
                    {
                        theMessage  = pendingRequest;
                        monitorType = HttpSessionWatcher.MonitorTypes.Client;

                        // assign the monitor type
                        SetTypeForTcpStreamGenerator(tcpStreamGenerator, monitorType);
                    }
                }
                else   // otherwise just process the data like normal
                {
                    status = ProcessBinaryReader(theMessage, monitorType, br);
                }

                // stop processing if we need more data
                // or if we are complete since we are done with this message and
                // only by re-entering this function do we create a new one
                if ((status == HttpMessage.ProcessStatus.NeedMoreData)
                    ||
                    (status == HttpMessage.ProcessStatus.Complete))
                {
                    break;
                }
            }

            return(status);
        }
Example #2
0
        private HttpMessage.ProcessStatus ProcessBinaryReader(HttpMessage theMessage,
                                                              MonitorTypes monitorType,
                                                              BinaryReader br)
        {
            HttpMessage.ProcessStatus status;

            status = theMessage.Process(br);

            if (IsDebugEnabled)
            {
                log.DebugFormat("status == {0}", status);
            }

            if (status == HttpMessage.ProcessStatus.Error)
            {
                log.Debug("ProcessStatus.Error");
            }
            else if (status == HttpMessage.ProcessStatus.Complete)
            {
                // send a completed notification to the appropriate handler
                if (monitorType == MonitorTypes.Client)
                {
                    if (OnHttpRequestFound != null)
                    {
                        if (IsDebugEnabled)
                        {
                            log.Debug("Calling OnHttpRequestFound() delegates");
                        }

                        try
                        {
                            OnHttpRequestFound(new HttpSessionWatcherRequestEventArgs(this, pendingRequest));
                        } catch (System.Exception)
                        {
                            // drop all exceptions thrown from handlers, its not our issue
                        }
                    }

                    // put this request into requests waiting for status queue
                    requestsWaitingForStatus.Enqueue(pendingRequest);

                    // clear out the pendingRequest since we finished with it
                    pendingRequest = null;
                }
                else if (monitorType == MonitorTypes.Server)
                {
                    // do we have any pending requests? if so we should
                    // dequeue one of them and assign it to the pendingStatus
                    // so the user can match the status with the request
                    if (requestsWaitingForStatus.Count != 0)
                    {
                        pendingStatus.Request = requestsWaitingForStatus.Dequeue();
                    }

                    if (OnHttpStatusFound != null)
                    {
                        if (IsDebugEnabled)
                        {
                            log.Debug("Calling OnHttpStatusFound() delegates");
                        }

                        try
                        {
                            OnHttpStatusFound(new HttpSessionWatcherStatusEventArgs(this, pendingStatus));
                        } catch (System.Exception)
                        {
                            // drop all exceptions thrown from handlers, its not our issue
                        }
                    }

                    // clear out the pendingStatus since we finished with it
                    pendingStatus = null;
                }

                // return completion
                status = HttpMessage.ProcessStatus.Complete;
            }
            else if (status == HttpMessage.ProcessStatus.NeedMoreData)
            {
                // need more data, return with our current position
            }

            return(status);
        }
Example #3
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="sessionWatcher">
 /// A <see cref="HttpSessionWatcher"/>
 /// </param>
 /// <param name="status">
 /// A <see cref="HttpStatus"/>
 /// </param>
 public HttpSessionWatcherStatusEventArgs(HttpSessionWatcher sessionWatcher,
                                          HttpStatus status)
 {
     this.sessionWatcher = sessionWatcher;
     this.status         = status;
 }