Ejemplo n.º 1
0
 public StompConnection(Socket socket)
 {
     _socket    = socket;
     _processor = new StompFrameProcessor();
     _requestProcessingStatus = RequestProcessingStatus.RequestPending;
     _currentHeaders          = new Dictionary <string, string>();
 }
Ejemplo n.º 2
0
        private async Task InitializeResponseAsync()
        {
            //fire on start.
            //call reponse starting call back.
            var startingTask = FireOnStarting();

            await startingTask;

            _requestProcessStatus = RequestProcessingStatus.ResponseStarted;
        }
Ejemplo n.º 3
0
        private void ProduceStart(bool appCompleted)
        {
            if (HasResponseStarted)
            {
                return;
            }

            _requestProcessingStatus = RequestProcessingStatus.ResponseStarted;

            var statusBytes = ReasonPhrases.ToStatusBytes(StatusCode, ReasonPhrase);

            CreateResponseHeader(statusBytes, appCompleted);
        }
Ejemplo n.º 4
0
        private void ParseRequest(ReadOnlySequence <byte> buffer, out SequencePosition consumed, out SequencePosition examined)
        {
            consumed = buffer.Start;
            examined = buffer.End;

            switch (_requestProcessingStatus)
            {
            case RequestProcessingStatus.RequestPending:
                if (buffer.IsEmpty)
                {
                    break;
                }

                _requestProcessingStatus = RequestProcessingStatus.ParsingCommand;
                goto case RequestProcessingStatus.ParsingCommand;

            case RequestProcessingStatus.ParsingCommand:
                if (_processor.ProcessCommandLine(new StompRequestHandler(this), buffer, out consumed, out examined))
                {
                    buffer = buffer.Slice(consumed, buffer.End);
                    _requestProcessingStatus = RequestProcessingStatus.ParsingHeaders;
                    goto case RequestProcessingStatus.ParsingHeaders;
                }

                break;

            case RequestProcessingStatus.ParsingHeaders:
                if (_processor.ProcessHeaders(new StompRequestHandler(this), buffer, out consumed, out examined))
                {
                    _requestProcessingStatus = RequestProcessingStatus.ParsingBody;
                    goto case RequestProcessingStatus.ParsingBody;
                }

                break;

            case RequestProcessingStatus.ParsingBody:
                if (_processor.ProcessBody(new StompRequestHandler(this), buffer, out consumed, out examined))
                {
                    _requestProcessingStatus = RequestProcessingStatus.RequestPending;
                }
                break;
            }
        }
Ejemplo n.º 5
0
        public void Reset()
        {
            FrameRequestHeaders?.Reset();
            FrameResponseHeaders?.Reset();

            _onStarting  = null;
            _onCompleted = null;

            _requestProcessingStatus = RequestProcessingStatus.RequestPending;
            _keepAlive            = false;
            _autoChunk            = false;
            _applicationException = null;

            ResetFeatureCollection();

            Scheme       = null;
            Method       = null;
            PathBase     = null;
            Path         = null;
            QueryString  = null;
            _httpVersion = HttpVersionType.Unset;
            StatusCode   = 200;
            ReasonPhrase = null;

            RemoteIpAddress = RemoteEndPoint?.Address;
            RemotePort      = RemoteEndPoint?.Port ?? 0;

            LocalIpAddress      = LocalEndPoint?.Address;
            LocalPort           = LocalEndPoint?.Port ?? 0;
            ConnectionIdFeature = ConnectionId;

            PrepareRequest?.Invoke(this);

            _manuallySetRequestAbortToken = null;
            _abortedCts = null;
        }
Ejemplo n.º 6
0
        protected RequestLineStatus TakeStartLine(SocketInput input)
        {
            var scan     = input.ConsumingStart();
            var consumed = scan;

            try
            {
                // We may hit this when the client has stopped sending data but
                // the connection hasn't closed yet, and therefore Frame.Stop()
                // hasn't been called yet.
                if (scan.Peek() == -1)
                {
                    return(RequestLineStatus.Empty);
                }

                _requestProcessingStatus = RequestProcessingStatus.RequestStarted;

                string method;
                var    begin = scan;
                if (!begin.GetKnownMethod(out method))
                {
                    if (scan.Seek(ref _vectorSpaces) == -1)
                    {
                        return(RequestLineStatus.MethodIncomplete);
                    }

                    method = begin.GetAsciiString(scan);

                    if (method == null)
                    {
                        RejectRequest("Missing method.");
                    }

                    // Note: We're not in the fast path any more (GetKnownMethod should have handled any HTTP Method we're aware of)
                    // So we can be a tiny bit slower and more careful here.
                    for (int i = 0; i < method.Length; i++)
                    {
                        if (!IsValidTokenChar(method[i]))
                        {
                            RejectRequest("Invalid method.");
                        }
                    }
                }
                else
                {
                    scan.Skip(method.Length);
                }

                scan.Take();
                begin = scan;
                var needDecode = false;
                var chFound    = scan.Seek(ref _vectorSpaces, ref _vectorQuestionMarks, ref _vectorPercentages);
                if (chFound == -1)
                {
                    return(RequestLineStatus.TargetIncomplete);
                }
                else if (chFound == '%')
                {
                    needDecode = true;
                    chFound    = scan.Seek(ref _vectorSpaces, ref _vectorQuestionMarks);
                    if (chFound == -1)
                    {
                        return(RequestLineStatus.TargetIncomplete);
                    }
                }

                var pathBegin = begin;
                var pathEnd   = scan;

                var queryString = "";
                if (chFound == '?')
                {
                    begin = scan;
                    if (scan.Seek(ref _vectorSpaces) == -1)
                    {
                        return(RequestLineStatus.TargetIncomplete);
                    }
                    queryString = begin.GetAsciiString(scan);
                }

                var queryEnd = scan;

                if (pathBegin.Peek() == ' ')
                {
                    RejectRequest("Missing request target.");
                }

                scan.Take();
                begin = scan;
                if (scan.Seek(ref _vectorCRs) == -1)
                {
                    return(RequestLineStatus.VersionIncomplete);
                }

                string httpVersion;
                if (!begin.GetKnownVersion(out httpVersion))
                {
                    // A slower fallback is necessary since the iterator's PeekLong() method
                    // used in GetKnownVersion() only examines two memory blocks at most.
                    // Although unlikely, it is possible that the 8 bytes forming the version
                    // could be spread out on more than two blocks, if the connection
                    // happens to be unusually slow.
                    httpVersion = begin.GetAsciiString(scan);

                    if (httpVersion == null)
                    {
                        RejectRequest("Missing HTTP version.");
                    }
                    else if (httpVersion != "HTTP/1.0" && httpVersion != "HTTP/1.1")
                    {
                        RejectRequest("Unrecognized HTTP version.");
                    }
                }

                scan.Take();
                var next = scan.Take();
                if (next == -1)
                {
                    return(RequestLineStatus.Incomplete);
                }
                else if (next != '\n')
                {
                    RejectRequest("Missing LF in request line.");
                }

                // URIs are always encoded/escaped to ASCII https://tools.ietf.org/html/rfc3986#page-11
                // Multibyte Internationalized Resource Identifiers (IRIs) are first converted to utf8;
                // then encoded/escaped to ASCII  https://www.ietf.org/rfc/rfc3987.txt "Mapping of IRIs to URIs"
                string requestUrlPath;
                string rawTarget;
                if (needDecode)
                {
                    // Read raw target before mutating memory.
                    rawTarget = pathBegin.GetAsciiString(queryEnd);

                    // URI was encoded, unescape and then parse as utf8
                    pathEnd        = UrlPathDecoder.Unescape(pathBegin, pathEnd);
                    requestUrlPath = pathBegin.GetUtf8String(pathEnd);
                }
                else
                {
                    // URI wasn't encoded, parse as ASCII
                    requestUrlPath = pathBegin.GetAsciiString(pathEnd);

                    if (queryString.Length == 0)
                    {
                        // No need to allocate an extra string if the path didn't need
                        // decoding and there's no query string following it.
                        rawTarget = requestUrlPath;
                    }
                    else
                    {
                        rawTarget = pathBegin.GetAsciiString(queryEnd);
                    }
                }

                var normalizedTarget = PathNormalizer.RemoveDotSegments(requestUrlPath);

                consumed    = scan;
                Method      = method;
                QueryString = queryString;
                RawTarget   = rawTarget;
                HttpVersion = httpVersion;

                bool caseMatches;
                if (RequestUrlStartsWithPathBase(normalizedTarget, out caseMatches))
                {
                    PathBase = caseMatches ? _pathBase : normalizedTarget.Substring(0, _pathBase.Length);
                    Path     = normalizedTarget.Substring(_pathBase.Length);
                }
                else if (rawTarget[0] == '/') // check rawTarget since normalizedTarget can be "" or "/" after dot segment removal
                {
                    Path = normalizedTarget;
                }
                else
                {
                    Path        = string.Empty;
                    PathBase    = string.Empty;
                    QueryString = string.Empty;
                }

                return(RequestLineStatus.Done);
            }
            finally
            {
                input.ConsumingComplete(consumed, scan);
            }
        }