예제 #1
0
        public override bool TryParseValue([NotNullWhen(true)] string?value, object?storeValue, ref int index, [NotNullWhen(true)] out object?parsedValue)
        {
            parsedValue = null;

            // Some headers support empty/null values. This one doesn't.
            if (string.IsNullOrEmpty(value) || (index == value.Length))
            {
                return(false);
            }

            ReadOnlySpan <char> dateString = value;

            if (index > 0)
            {
                dateString = value.AsSpan(index);
            }

            DateTimeOffset date;

            if (!HttpDateParser.TryParse(dateString, out date))
            {
                return(false);
            }

            index       = value.Length;
            parsedValue = date;
            return(true);
        }
예제 #2
0
        // Add the given parameter to the list. Remove if date is null.
        private void SetDate(string parameter, DateTimeOffset?date)
        {
            NameValueHeaderValue?dateParameter = NameValueHeaderValue.Find(_parameters, parameter);

            if (date == null)
            {
                // Remove parameter.
                if (dateParameter != null)
                {
                    _parameters !.Remove(dateParameter);
                }
            }
            else
            {
                // Must always be quoted.
                string dateString = "\"" + HttpDateParser.DateToString(date.Value) + "\"";
                if (dateParameter != null)
                {
                    dateParameter.Value = dateString;
                }
                else
                {
                    Parameters.Add(new NameValueHeaderValue(parameter, dateString));
                }
            }
        }
예제 #3
0
        private void SetDate(string parameter, DateTimeOffset?date)
        {
            NameValueHeaderValue valueHeaderValue = NameValueHeaderValue.Find(this._parameters, parameter);

            if (!date.HasValue)
            {
                if (valueHeaderValue == null)
                {
                    return;
                }
                this._parameters.Remove(valueHeaderValue);
            }
            else
            {
                string str = "\"" + HttpDateParser.DateToString(date.Value) + "\"";
                if (valueHeaderValue != null)
                {
                    valueHeaderValue.Value = str;
                }
                else
                {
                    this.Parameters.Add(new NameValueHeaderValue(parameter, str));
                }
            }
        }
예제 #4
0
        public override bool TryParseValue(string value, object storeValue, ref int index, out object parsedValue)
        {
            parsedValue = null;

            // Some headers support empty/null values. This one doesn't.
            if (string.IsNullOrEmpty(value) || (index == value.Length))
            {
                return(false);
            }

            string dateString = value;

            if (index > 0)
            {
                dateString = value.Substring(index);
            }

            DateTimeOffset date;

            if (!HttpDateParser.TryStringToDate(dateString, out date))
            {
                return(false);
            }

            index       = value.Length;
            parsedValue = date;
            return(true);
        }
예제 #5
0
        public static void DateToString_UseRfcSampleTimestamp_FormattedAccordingToRfc1123()
        {
            // We don't need extensive tests, since we let DateTimeOffset do the formatting. This test is just
            // to validate that we use the correct parameters when calling into DateTimeOffset.ToString().
            DateTimeOffset dateTime = new DateTimeOffset(1994, 11, 6, 8, 49, 37, TimeSpan.Zero);

            Assert.Equal("Sun, 06 Nov 1994 08:49:37 GMT", HttpDateParser.DateToString(dateTime));
        }
예제 #6
0
 public override string ToString()
 {
     if (_entityTag == null)
     {
         return(HttpDateParser.DateToString(_date.Value));
     }
     return(_entityTag.ToString());
 }
예제 #7
0
 public override string ToString()
 {
     if (_delta.HasValue)
     {
         return(((int)_delta.Value.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo));
     }
     return(HttpDateParser.DateToString(_date.Value));
 }
예제 #8
0
        private static bool TryReadDate(string input, ref int current, out DateTimeOffset?date)
        {
            date = null;

            // Make sure we have at least one whitespace between <text> and <date> (if we have <date>)
            int whitespaceLength = HttpRuleParser.GetWhitespaceLength(input, current);

            current = current + whitespaceLength;

            // Read <date> in '<code> <agent> <text> ["<date>"]'
            if ((current < input.Length) && (input[current] == '"'))
            {
                if (whitespaceLength == 0)
                {
                    return(false); // we have characters after <text> but they were not separated by a whitespace
                }

                current++; // skip opening '"'

                // Find the closing '"'
                int dateStartIndex = current;
                while (current < input.Length)
                {
                    if (input[current] == '"')
                    {
                        break;
                    }
                    current++;
                }

                if ((current == input.Length) || (current == dateStartIndex))
                {
                    return(false); // we couldn't find the closing '"' or we have an empty quoted string.
                }

                DateTimeOffset temp;
                if (!HttpDateParser.TryParse(input.AsSpan(dateStartIndex, current - dateStartIndex), out temp))
                {
                    return(false);
                }

                date = temp;

                current++; // skip closing '"'
                current = current + HttpRuleParser.GetWhitespaceLength(input, current);
            }

            return(true);
        }
예제 #9
0
        private DateTimeOffset?GetDate(string parameter)
        {
            NameValueHeaderValue valueHeaderValue = NameValueHeaderValue.Find(this._parameters, parameter);

            if (valueHeaderValue != null)
            {
                ReadOnlySpan <char> input = (ReadOnlySpan <char>)valueHeaderValue.Value;
                if (ContentDispositionHeaderValue.IsQuoted(input))
                {
                    input = input.Slice(1, input.Length - 2);
                }
                DateTimeOffset result;
                if (HttpDateParser.TryStringToDate(input, out result))
                {
                    return(new DateTimeOffset?(result));
                }
            }
            return(new DateTimeOffset?());
        }
예제 #10
0
        // Gets a parameter of the given name and attempts to extract a date.
        // Returns null if the parameter is not present or the format is incorrect.
        private DateTimeOffset?GetDate(string parameter)
        {
            NameValueHeaderValue?dateParameter = NameValueHeaderValue.Find(_parameters, parameter);
            DateTimeOffset       date;

            if (dateParameter != null)
            {
                ReadOnlySpan <char> dateString = dateParameter.Value;
                // Should have quotes, remove them.
                if (IsQuoted(dateString))
                {
                    dateString = dateString.Slice(1, dateString.Length - 2);
                }
                if (HttpDateParser.TryParse(dateString, out date))
                {
                    return(date);
                }
            }
            return(null);
        }
예제 #11
0
        public override string ToString()
        {
            StringBuilder sb = StringBuilderCache.Acquire();

            // Warning codes are always 3 digits according to RFC2616
            sb.Append(NumberFormatInfo.InvariantInfo, $"{_code:000}");

            sb.Append(' ');
            sb.Append(_agent);
            sb.Append(' ');
            sb.Append(_text);

            if (_date.HasValue)
            {
                sb.Append(" \"");
                sb.Append(HttpDateParser.DateToString(_date.Value));
                sb.Append('\"');
            }

            return(StringBuilderCache.GetStringAndRelease(sb));
        }
예제 #12
0
 public static void TryParse_UseInvalidDateTimeString(string invalid)
 {
     Assert.False(HttpDateParser.TryParse(invalid, out var result));
     Assert.Equal(default, result);
예제 #13
0
        internal static int GetRangeConditionLength(string input, int startIndex, out object parsedValue)
        {
            Debug.Assert(startIndex >= 0);

            parsedValue = null;

            // Make sure we have at least 2 characters
            if (string.IsNullOrEmpty(input) || (startIndex + 1 >= input.Length))
            {
                return(0);
            }

            int current = startIndex;

            // Caller must remove leading whitespace.
            DateTimeOffset       date      = DateTimeOffset.MinValue;
            EntityTagHeaderValue entityTag = null;

            // Entity tags are quoted strings optionally preceded by "W/". By looking at the first two character we
            // can determine whether the string is en entity tag or a date.
            char firstChar  = input[current];
            char secondChar = input[current + 1];

            if ((firstChar == '\"') || (((firstChar == 'w') || (firstChar == 'W')) && (secondChar == '/')))
            {
                // trailing whitespace is removed by GetEntityTagLength()
                int entityTagLength = EntityTagHeaderValue.GetEntityTagLength(input, current, out entityTag);

                if (entityTagLength == 0)
                {
                    return(0);
                }

                current = current + entityTagLength;

                // RangeConditionHeaderValue only allows 1 value. There must be no delimiter/other chars after an
                // entity tag.
                if (current != input.Length)
                {
                    return(0);
                }
            }
            else
            {
                if (!HttpDateParser.TryStringToDate(input.AsSpan(current), out date))
                {
                    return(0);
                }

                // If we got a valid date, then the parser consumed the whole string (incl. trailing whitespace).
                current = input.Length;
            }

            RangeConditionHeaderValue result = new RangeConditionHeaderValue();

            if (entityTag == null)
            {
                result._date = date;
            }
            else
            {
                result._entityTag = entityTag;
            }

            parsedValue = result;
            return(current - startIndex);
        }
        internal static int GetRetryConditionLength(string?input, int startIndex, out object?parsedValue)
        {
            Debug.Assert(startIndex >= 0);

            parsedValue = null;

            if (string.IsNullOrEmpty(input) || (startIndex >= input.Length))
            {
                return(0);
            }

            int current = startIndex;

            // Caller must remove leading whitespace.
            DateTimeOffset date         = DateTimeOffset.MinValue;
            int            deltaSeconds = -1; // use -1 to indicate that the value was not set. 'delta' values are always >=0

            // We either have a timespan or a date/time value. Determine which one we have by looking at the first char.
            // If it is a number, we have a timespan, otherwise we assume we have a date.
            char firstChar = input[current];

            if ((firstChar >= '0') && (firstChar <= '9'))
            {
                int deltaStartIndex = current;
                int deltaLength     = HttpRuleParser.GetNumberLength(input, current, false);

                // The value must be in the range 0..2^31
                if ((deltaLength == 0) || (deltaLength > HttpRuleParser.MaxInt32Digits))
                {
                    return(0);
                }

                current = current + deltaLength;
                current = current + HttpRuleParser.GetWhitespaceLength(input, current);

                // RetryConditionHeaderValue only allows 1 value. There must be no delimiter/other chars after 'delta'
                if (current != input.Length)
                {
                    return(0);
                }

                if (!HeaderUtilities.TryParseInt32(input, deltaStartIndex, deltaLength, out deltaSeconds))
                {
                    return(0); // int.TryParse() may return 'false' if the value has 10 digits and is > Int32.MaxValue.
                }
            }
            else
            {
                if (!HttpDateParser.TryParse(input.AsSpan(current), out date))
                {
                    return(0);
                }

                // If we got a valid date, then the parser consumed the whole string (incl. trailing whitespace).
                current = input.Length;
            }

            RetryConditionHeaderValue result = new RetryConditionHeaderValue();

            if (deltaSeconds == -1) // we didn't change delta, so we must have found a date.
            {
                result._date = date;
            }
            else
            {
                result._delta = new TimeSpan(0, 0, deltaSeconds);
            }

            parsedValue = result;
            return(current - startIndex);
        }
예제 #15
0
        public override string ToString(object value)
        {
            Debug.Assert(value is DateTimeOffset);

            return(HttpDateParser.DateToString((DateTimeOffset)value));
        }
예제 #16
0
 public static void TryStringToDate_UseInvalidDateTimeString(string invalid)
 {
     Assert.False(HttpDateParser.TryStringToDate(",Sun, 06 Nov 1994 08:49:37 GMT", out var result));
 }
예제 #17
0
 // We don't need extensive tests, since we let DateTimeOffset do the parsing. This test is just
 // to validate that we use the correct parameters when calling into DateTimeOffset.ToString().
 public static void TryParse_UseOfValidDateTimeStringsInDifferentFormats_ParsedCorrectly(string input, DateTimeOffset expected)
 {
     Assert.True(HttpDateParser.TryParse(input, out var result));
     Assert.Equal(expected, result);
 }