Exemple #1
0
        public HttpRangeHeader GetRange()
        {
            string rangeString = GetHeader("Range");

            if (String.IsNullOrEmpty(rangeString))
            {
                return(null);
            }

            HttpRangeHeader rangeHeader;

            if (HttpRangeHeader.TryParse(rangeString, out rangeHeader))
            {
                return(rangeHeader);
            }

            return(null);
        }
Exemple #2
0
        public static bool TryParse(string rangeString, out HttpRangeHeader rangeHeader)
        {
            rangeHeader = null;

            if (String.IsNullOrEmpty(rangeString))
            {
                return(false);
            }

            int equalIndex = rangeString.IndexOf('=');
            int dashIndex  = rangeString.IndexOf('-');

            // The equal should be before the dash.
            if (dashIndex <= equalIndex)
            {
                return(false);
            }

            // There should be something else after the equal.
            if (equalIndex + 1 >= rangeString.Length)
            {
                return(false);
            }

            string firstBytePosString = rangeString.Substring(equalIndex + 1, dashIndex - equalIndex - 1);

            string lastBytePosString = String.Empty;

            if (dashIndex + 1 <= rangeString.Length)
            {
                lastBytePosString = rangeString.Substring(dashIndex + 1);
            }

            long last;

            if (!String.IsNullOrEmpty(lastBytePosString))
            {
                if (!Int64.TryParse(lastBytePosString, out last))
                {
                    // Invalid header, stop parsing.
                    return(false);
                }
            }
            else
            {
                last = Int64.MaxValue;
            }

            long first = 0;

            if (!String.IsNullOrEmpty(firstBytePosString))
            {
                if (!Int64.TryParse(firstBytePosString, out first))
                {
                    // Invalid header, stop parsing.
                    return(false);
                }
            }
            else
            {
                last *= -1;
            }

            rangeHeader = new HttpRangeHeader(first, last);
            return(true);
        }
Exemple #3
0
        private void SendResponse(HeyHttpResponse response)
        {
            try
            {
                // Set default content.
                response.ContentStream = CreateDefaultResponseStream();

                // Do authentication.
                HeyHttpAuthentication.AddAuthenticateHeaderIfNeeded(request, response);

                // Custom headers.
                if (request.QueryStringHasTrueValue("custom"))
                {
                    response.Headers.Add("X-Header: Value1");
                    response.Headers.Add("X-Header: Value2");
                    response.Headers.Add("X-Header: Value3");
                }

                // Show the 'Save As' dialog.
                string filename;
                if (request.QueryStringHas("filename", out filename))
                {
                    response.Headers.Add(String.Format("Content-Disposition: Attachment; filename={0}", filename));
                }

                // 201 Created for AtomPub.
                if (request.QueryStringHasTrueValue("create"))
                {
                    response.Status = "201 Created";
                    response.Headers.Add("Location: http://heyhttp.org/Data/first-post.atom");
                    response.Headers.Add("Content-Location: http://heyhttp.org/Data/first-post.atom");
                    response.Headers.Add("ETag: \"e180ee84f0671b1\"");
                }

                // 301 Moved Permanently.
                string redirect;
                if (request.QueryStringHas("redirect", out redirect))
                {
                    response.Status = "301 Moved Permanently";

                    response.Headers.Add("Location: " + redirect);

                    // Do not send any data back.
                    request.Path = "";
                }

                // 503 Service Unavailable, retry after N seconds.
                if (request.QueryStringHasTrueValue("retry"))
                {
                    if (!retryReceivedBefore)
                    {
                        response.Status = "503 Service Unavailable";
                        response.Headers.Add("Retry-After: 5");
                        response.ContentStream = GetStringStream(String.Empty);
                    }
                    retryReceivedBefore = !retryReceivedBefore;
                }

                // Set cache headers.
                if (request.QueryStringHasTrueValue("cache"))
                {
                    response.Headers.Add("Cache-Control: max-age=3600"); // One hour (60 minutes * 60 seconds)

                    //additionalHeaders.Add("Expires: " + DateTime.UtcNow.AddHours(24).ToString("R"));
                }
                else if (request.QueryStringHasTrueValue("nocache"))
                {
                    response.Headers.Add("Cache-Control: no-cache"); // HTTP 1.1
                }

                // Set cookie header.
                if (request.QueryStringHasTrueValue("setcookie"))
                {
                    response.Headers.Add("Set-Cookie: sessionTestCookie=X");
                    response.Headers.Add("Set-Cookie: persistentTestCookie=Y; expires=Wednesday, 09-Nov-2020 23:12:40 GMT");
                    response.Headers.Add("Set-Cookie: httpOnlyTestCookie=X; expires=Wednesday, 09-Nov-2020 23:12:40 GMT; HttpOnly");
                    response.Headers.Add("Set-Cookie: subdomainTestCookie=ghi; expires=Wednesday, 09-Nov-2020 23:12:40 GMT; domain=foo.heyhttp.org");
                    response.Headers.Add("Set-Cookie: slashEndingCookie=b; expires=Wednesday, 09-Nov-2020 23:12:40 GMT; domain=heyhttp.org; path=/foo/");
                    response.Headers.Add("Set-Cookie: nonSlashEndingCookie=a; expires=Wednesday, 09-Nov-2020 23:12:40 GMT; domain=heyhttp.org; path=/foo");
                }

                // Return an specific HTTP status.
                int requestedStatus;
                if (request.QueryStringHas("status", out requestedStatus))
                {
                    response.Status = String.Format("{0} Foo Foo Bar", requestedStatus);
                }

                // Set arbitrary header.
                string headerName;
                string headerValue;
                if (request.QueryStringHas("name", out headerName) && request.QueryStringHas("value", out headerValue))
                {
                    response.Headers.Add(String.Format("{0}: {1}", headerName, headerValue));
                }

                // Introduce a long delay.
                int delay;
                if (request.QueryStringHas("delay", out delay))
                {
                    Thread.Sleep(delay);
                }

                // Get trace content stream.
                if (request.QueryStringHasTrueValue("trace"))
                {
                    response.ContentStream = GetTraceStream();

                    // Do not send any data back.
                    request.Path = "";
                }


                // Get file.
                if (!String.IsNullOrEmpty(request.Path) &&
                    !String.IsNullOrEmpty(response.Status) &&
                    request.Path != "/" &&
                    !response.Status.StartsWith("404"))
                {
                    try
                    {
                        response.ContentStream = GetFileStream();
                    }
                    catch (FileNotFoundException ex)
                    {
                        response.Status        = "404 Not Found";
                        response.ContentStream = GetStringStream(ex.Message);
                    }
                    catch (DirectoryNotFoundException ex)
                    {
                        response.Status        = "404 Not Found";
                        response.ContentStream = GetStringStream(ex.Message);
                    }
                }

                // Create a response of the length given.
                long sizeInBytes;
                if (request.QueryStringHas("length", out sizeInBytes))
                {
                    response.ContentStream = CreateBigStream(sizeInBytes);
                }

                // This check must be done after the response coontent has been selected.
                string eTag;
                bool   useETag = request.QueryStringHas("etag", out eTag);
                if (useETag)
                {
                    //// 304 Not Modified with ETag.
                    //if (request.GetHeader("If-None-Match") == eTag)
                    //{
                    //    response.Status = "304 Not Modified";
                    //    response.ContentStream = GetStringStream(String.Empty);
                    //}
                    //else
                    //{
                    //}

                    // This 'if' is to manually change the flow when debugging.
                    if (DateTime.Now.Second == -1)
                    {
                        eTag                   = String.Empty;
                        response.Status        = "404 NOT FOUND";
                        response.ContentStream = GetStringStream("Oops!");
                    }
                    else
                    {
                        response.Headers.Add(String.Format("ETag: \"{0}\"", eTag));
                        response.Headers.Add("Accept-Ranges: bytes");
                    }
                }

                bool useLastModified = request.QueryStringHasTrueValue("lastModified");
                if (useLastModified)
                {
                    response.Headers.Add("Last-Modified: Thu, 21 Aug 2014 21:34:57 GMT");
                    response.Headers.Add("Accept-Ranges: bytes");
                }

                HttpRangeHeader rangeHeader = request.GetRange();
                if (rangeHeader != null && (useETag || useLastModified))
                {
                    response.Status = "206 Partial Content";
                    response.Headers.Add(rangeHeader.GetContentRange(response.ContentStream.Length));
                    response.FirstPosition = rangeHeader.FirstPosition;
                    response.LastPosition  = rangeHeader.LastPosition;
                }

                ForkSendResponse(response);
            }
            finally
            {
                // 'finally' block is executed even if a 'try' or 'catch' block contains a 'return'.
                if (response.ContentStream != null)
                {
                    response.ContentStream.Dispose();
                }
            }
        }