public static void ParseHeaders( Request request, ConsumableSegment<byte> buffer ) { request.Headers = new Dictionary<string, string>( StringComparer.CurrentCultureIgnoreCase ); var length = buffer.Length; while ( MoveToNextByteIfAble( buffer ) && buffer.Offset + 4 < length && AreHeadersFinished( buffer ) ) { var headerName = ParseValue( buffer, COLON ); var value = ParseValue( buffer, CR ).Trim(); if( headerName.Equals( "Connection" ) && value.Equals( "Keep-Alive" ) ) request.KeepAlive = true; request.Headers.Add( headerName, value ); } var host = ""; if( request.Headers.TryGetValue( "Host", out host ) ) request.BaseUri = string.Format( "{0}://{1}", request.Scheme, host ); while ( MoveToNextByteIfAble( buffer ) && ( buffer.Array[buffer.Offset] == CR || buffer.Array[buffer.Offset] == LF ) ) { } request.HeadersComplete = true; request.Parse = PassBodySegmentOn; }
public static void ParseLine( Request request, ConsumableSegment<byte> buffer ) { GetMethod( request, buffer ); GetUri( request, buffer ); GetVersion( request, buffer ); request.Parse = ParseHeaders; }
public static string ParseBaseUri( ConsumableSegment<byte> buffer ) { var length = 1; var count = 0; var start = buffer.Offset; while( MoveToNextByteIfAble( buffer ) && ( ( count += buffer.Array[ buffer.Offset ] == SLASH ? 1 : 0 ) < 3 ) ) { length++; } return Encoding.UTF8.GetString( buffer.Array, start, length ); }
public static string ParseValue( ConsumableSegment<byte> buffer, byte stopCharacter ) { var length = 1; var start = buffer.Offset; while ( MoveToNextByteIfAble( buffer ) && buffer.Array[ buffer.Offset ] != stopCharacter ) { length++; } buffer.Offset++; return Encoding.UTF8.GetString( buffer.Array, start, length ); }
public static void PopulateRequest( Request request, ConsumableSegment<byte> arraySegment ) { while( arraySegment.Count > 0 ) request.Parse( request, arraySegment ); }
public static void PassBodySegmentOn( Request request, ConsumableSegment<byte> buffer ) { if( request.HandleExtraBytes != null ) request.HandleExtraBytes( buffer, request.CanHaveBody ); buffer.Offset += buffer.Count; }
public static bool AreHeadersFinished( ConsumableSegment<byte> buffer ) { return ( buffer.Array[buffer.Offset] != CR && buffer.Array[buffer.Offset + 2] != CR ); }
public static bool MoveToNextByteIfAble( ConsumableSegment<byte> buffer ) { return buffer.Count > 0 ? ( buffer ++ ).Offset > 0 : false; }
public static void GetVersion( Request request, ConsumableSegment<byte> buffer ) { request.Scheme = ParseValue( buffer, SLASH ); request.Version = ParseValue( buffer, CR ); request.KeepAlive = request.Version.Equals( "1.1" ); }
public static void GetAbsoluteUri( Request request, ConsumableSegment<byte> buffer ) { request.BaseUri = ParseBaseUri( buffer ); var pathAndQuery = ParseValue( buffer, SPACE ); ParsePathAndQuery( request, pathAndQuery ); }
public static void GetRelativeUri( Request request, ConsumableSegment<byte> buffer ) { var pathAndQuery = ParseValue( buffer, SPACE ); ParsePathAndQuery( request, pathAndQuery ); }
public static void GetUri( Request request, ConsumableSegment<byte> buffer ) { if( buffer.Array[ buffer.Offset ] == SLASH ) GetRelativeUri( request, buffer ); else GetAbsoluteUri( request, buffer ); }
public static void GetMethod( Request request, ConsumableSegment<byte> buffer ) { request.Method = ParseValue( buffer, SPACE ); }