Beispiel #1
0
        /// <summary>
        /// Respuesta 200
        /// Se debe de llamar ANTES de empezar a escribir en el stream de respuesta
        /// Se enviarán todos los headers incluidos en ResponseHeaders
        /// </summary>
        public void WriteOkResponse()
        {
            string type = "text/html";

            if (ResponseHeaders.ContainsKey("Content-Type"))
            {
                type = ResponseHeaders["Content-Type"];
                ResponseHeaders.Remove("Content-Type");
            }

            if (ResponseHeaders.ContainsKey("Connection"))
            {
                ResponseHeaders.Remove("Connection");
            }

            var headersList = ResponseHeaders.ToList();

            if (RequestHeaders.ContainsKey("Host"))
            {
                foreach (var cookie in Cookies)
                {
                    headersList.Add(new KeyValuePair <string, string>("Set-Cookie", cookie.Key + "=" + cookie.Value + "; domain=." + RequestHeaders["Host"]));
                }
            }

            Processor.WriteSuccess(type, headersList);
        }
 public virtual string GetRequestHeaderValue(string header)
 {
     if (!RequestHeaders.ContainsKey(header))
     {
         return(null);
     }
     return(((WebHeaderCollection)RequestHeaders)[header]);
 }
Beispiel #3
0
        /// <summary>
        /// True if header exists
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool HeaderExists(string name)
        {
            if (RequestHeaders.ContainsKey(name) ||
                NonUniqueRequestHeaders.ContainsKey(name))
            {
                return(true);
            }

            return(false);
        }
Beispiel #4
0
        private void ParseRequest_(byte[] request_bytes)
        {
            string request_str = Encoding.UTF8.GetString(request_bytes);

            int current_index = 0;
            int scan_index    = request_str.IndexOf(' ');

            this.Method   = request_str.Substring(current_index, scan_index);
            current_index = scan_index + 1;

            scan_index      = request_str.IndexOf(' ', current_index);
            this.RequestUri = request_str.Substring(current_index, scan_index - current_index);
            Uri uri = new Uri(this.RequestUri);

            this.Scheme      = uri.Scheme;
            this.Path        = uri.LocalPath;
            this.PathBase    = "";
            this.QueryString = uri.Query;
            current_index    = scan_index + 1;

            scan_index       = request_str.IndexOf('\r', current_index);
            this.HttpVersion = request_str.Substring(current_index, scan_index - current_index);
            current_index    = scan_index + 2;

            string header_line;
            int    header_scan_index = 0;

            while (current_index != request_str.Length && request_str[current_index] != '\r')
            {
                scan_index  = request_str.IndexOf('\r', current_index);
                header_line = request_str.Substring(current_index, scan_index - current_index);
                if (header_line.IndexOf("Connection") == 0 && header_line.IndexOf("keep-alive") != -1)
                {
                    _keepAlive = true;
                }
                header_scan_index = header_line.IndexOf(':');
                this.RequestHeaders.Add(header_line.Substring(0, header_scan_index), header_line.Substring(header_scan_index + 2, header_line.Length - header_scan_index - 2));
                current_index = scan_index + 2;
            }
            if (current_index < request_str.Length)
            {
                current_index += 2;
                string body_str   = request_str.Substring(current_index, request_str.Length - current_index);
                byte[] body_bytes = Encoding.UTF8.GetBytes(body_str);
                this.RequestBody.Write(body_bytes, 0, body_bytes.Length);
                this.RequestBody.Flush();
                this.RequestBody.Position = 0;
                if (!RequestHeaders.ContainsKey("Content-Length"))
                {
                    RequestHeaders.Add("Content-Length", body_bytes.Length.ToString());
                }
            }
            _responseStarted = true;
        }
Beispiel #5
0
        public void SetRequestHeader(string headerName, string headerValue)
        {
            if (RequestHeaders.ContainsKey(headerName))
            {
                RequestHeaders[headerName][0] = headerValue;
                return;
            }
            RequestHeaders.Add(headerName, new string[]
			{
				headerValue
			});
        }
Beispiel #6
0
        /// <summary>
        ///  removes all headers with given name
        /// </summary>
        /// <param name="headerName"></param>
        /// <returns>True if header was removed
        /// False if no header exists with given name</returns>
        public bool RemoveHeader(string headerName)
        {
            if (RequestHeaders.ContainsKey(headerName))
            {
                RequestHeaders.Remove(headerName);
                return(true);
            }
            else if (NonUniqueRequestHeaders.ContainsKey(headerName))
            {
                NonUniqueRequestHeaders.Remove(headerName);
                return(true);
            }

            return(false);
        }
Beispiel #7
0
        /// <summary>
        /// Returns all headers with given name if exists
        /// Returns null if does'nt exist
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public List <HttpHeader> GetHeaders(string name)
        {
            if (RequestHeaders.ContainsKey(name))
            {
                return(new List <HttpHeader>()
                {
                    RequestHeaders[name]
                });
            }
            else if (NonUniqueRequestHeaders.ContainsKey(name))
            {
                return(new List <HttpHeader>(NonUniqueRequestHeaders[name]));
            }

            return(null);
        }
 public void SetRequestHeaders(IEnumerable <KeyValuePair <string, string> > requestHeaders)
 {
     if (requestHeaders != null)
     {
         foreach (var header in requestHeaders)
         {
             if (RequestHeaders.ContainsKey(header.Key))
             {
                 RequestHeaders[header.Key] = header.Value;
             }
             else
             {
                 RequestHeaders.Add(header.Key, header.Value);
             }
         }
     }
 }
Beispiel #9
0
        /// <summary>
        /// Removes given header object if it exist
        /// </summary>
        /// <param name="header">Returns true if header exists and was removed </param>
        public bool RemoveHeader(HttpHeader header)
        {
            if (RequestHeaders.ContainsKey(header.Name))
            {
                if (RequestHeaders[header.Name].Equals(header))
                {
                    RequestHeaders.Remove(header.Name);
                    return(true);
                }
            }
            else if (NonUniqueRequestHeaders.ContainsKey(header.Name))
            {
                if (NonUniqueRequestHeaders[header.Name]
                    .RemoveAll(x => x.Equals(header)) > 0)
                {
                    return(true);
                }
            }

            return(false);
        }
        private bool TryUpgradeToHttp2()
        {
            try
            {
                if (RequestHeaders.ContainsKey("HTTP2-Settings") && RequestHeaders.ContainsKey("Connection"))
                {
                    var connection = RequestHeaders["Connection"];
                    if (ContainsToken(connection, "Upgrade") && ContainsToken(connection, "HTTP2-Settings")
                        && ContainsToken(RequestHeaders["Upgrade"], "h2c"))
                    {
                        var settings = RequestHeaders["HTTP2-Settings"];
                        if (settings.Count == 1)
                        {
                            var base64 = settings[0];
                            switch (base64.Length % 4)
                            {
                                case 0: break; // do nothing
                                case 2: base64 += "=="; break;
                                case 3: base64 += "="; break;
                                default: return false;
                            }
                            // In the URL and Filename safe variant, character 62 (0x3E) is replaced with a "-" (minus sign) and character 63 (0x3F) is replaced with a "_" (underscore).
                            base64 = base64.Replace('-', '+').Replace('_', '/');

                            var payload = Convert.FromBase64String(base64);
                            ParseSettings(payload);
                            return true;
                        }
                    }
                }

                return false;
            }
            catch(Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
                return false;
            }
        }
Beispiel #11
0
        /// <summary>
        /// Adds the given header object to Request
        /// </summary>
        /// <param name="newHeader"></param>
        public void AddHeader(HttpHeader newHeader)
        {
            if (NonUniqueRequestHeaders.ContainsKey(newHeader.Name))
            {
                NonUniqueRequestHeaders[newHeader.Name].Add(newHeader);
                return;
            }

            if (RequestHeaders.ContainsKey(newHeader.Name))
            {
                var existing = RequestHeaders[newHeader.Name];
                RequestHeaders.Remove(newHeader.Name);

                NonUniqueRequestHeaders.Add(newHeader.Name,
                                            new List <HttpHeader>()
                {
                    existing, newHeader
                });
            }
            else
            {
                RequestHeaders.Add(newHeader.Name, newHeader);
            }
        }
        public async Task ProcessAllRequests()
        {
            Reset();

            while (true)
            {
                var buffer = await _input.ReadAsync();

                try
                {
                    if (buffer.IsEmpty && _input.Reading.IsCompleted)
                    {
                        // We're done with this connection
                        return;
                    }
                    Console.WriteLine($"Read: {buffer.Length} bytes");
                    Console.WriteLine(BitConverter.ToString(buffer.ToArray()));
                    Console.WriteLine(buffer.GetAsciiString());
                    var result = _parser.ParseRequest(ref buffer);
                    Console.WriteLine($"Result: {result}");
                    switch (result)
                    {
                        case HttpRequestParser.ParseResult.Incomplete:
                            if (_input.Reading.IsCompleted)
                            {
                                // Didn't get the whole request and the connection ended
                                throw new EndOfStreamException();
                            }
                            // Need more data
                            continue;
                        case HttpRequestParser.ParseResult.Complete:
                            // Done
                            break;
                        case HttpRequestParser.ParseResult.BadRequest:
                            // TODO: Don't throw here;
                            throw new Exception();
                        default:
                            break;
                    }

                }
                catch (Exception)
                {
                    StatusCode = 400;

                    await EndResponse();

                    return;
                }
                finally
                {
                    _input.Advance(buffer.Start, buffer.End);
                }

                var context = _application.CreateContext(this);

                try
                {
                    if (!_isHttp2 && RequestHeaders.ContainsKey("Upgrade") && TryUpgradeToHttp2())
                    {
                        _outputFormatter.Write(_http2SwitchBytes);
                        _isHttp2 = true;

                        /*
                         The first HTTP/2 frame sent by the server MUST be a server connection
                         preface (Section 3.5) consisting of a SETTINGS frame (Section 6.5).
                        */
                        _outputFormatter.Write(_emptySettingsFrame);


                        await _outputFormatter.FlushAsync();
                    }

                    await _application.ProcessRequestAsync(context);
                }
                catch (Exception ex)
                {
                    StatusCode = 500;

                    _application.DisposeContext(context, ex);
                }
                finally
                {
                    await EndResponse();
                }

                if (!KeepAlive)
                {
                    break;
                }

                Reset();
            }
        }