Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V5 Docs - parseDate #395

Merged
merged 1 commit into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ docs/*.md

# subsequent PRs will un-ignore areas that are under review until
# all docs are complete and we can drop this ignore file entirely
!docs/tough-cookie.parsedate.md
!docs/tough-cookie.formatdate.md
!docs/tough-cookie.domainmatch.md
!docs/tough-cookie.defaultpath.md
Expand Down
122 changes: 122 additions & 0 deletions api/docs/tough-cookie.parsedate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [tough-cookie](./tough-cookie.md) &gt; [parseDate](./tough-cookie.parsedate.md)

## parseDate() function

Parse a cookie date string into a [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)<!-- -->. Parses according to [RFC6265 - Section 5.1.1](https://www.rfc-editor.org/rfc/rfc6265.html#section-5.1.1)<!-- -->, not [Date.parse()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse)<!-- -->.

**Signature:**

```typescript
export declare function parseDate(cookieDate: Nullable<string>): Date | undefined;
```

## Parameters

<table><thead><tr><th>

Parameter


</th><th>

Type


</th><th>

Description


</th></tr></thead>
<tbody><tr><td>

cookieDate


</td><td>

Nullable&lt;string&gt;


</td><td>

the cookie date string


</td></tr>
</tbody></table>
**Returns:**

Date \| undefined

## Remarks

\#\#\# RFC6265 - 5.1.1. Dates
colincasey marked this conversation as resolved.
Show resolved Hide resolved

The user agent MUST use an algorithm equivalent to the following algorithm to parse a cookie-date. Note that the various boolean flags defined as a part of the algorithm (i.e., found-time, found- day-of-month, found-month, found-year) are initially "not set".

1. Using the grammar below, divide the cookie-date into date-tokens.

```
cookie-date = *delimiter date-token-list *delimiter
date-token-list = date-token *( 1*delimiter date-token )
date-token = 1*non-delimiter

delimiter = %x09 / %x20-2F / %x3B-40 / %x5B-60 / %x7B-7E
non-delimiter = %x00-08 / %x0A-1F / DIGIT / ":" / ALPHA / %x7F-FF
non-digit = %x00-2F / %x3A-FF

day-of-month = 1*2DIGIT ( non-digit *OCTET )
month = ( "jan" / "feb" / "mar" / "apr" /
"may" / "jun" / "jul" / "aug" /
"sep" / "oct" / "nov" / "dec" ) *OCTET
year = 2*4DIGIT ( non-digit *OCTET )
time = hms-time ( non-digit *OCTET )
hms-time = time-field ":" time-field ":" time-field
time-field = 1*2DIGIT
```
2. Process each date-token sequentially in the order the date-tokens appear in the cookie-date:

1. If the found-time flag is not set and the token matches the time production, set the found-time flag and set the hour- value, minute-value, and second-value to the numbers denoted by the digits in the date-token, respectively. Skip the remaining sub-steps and continue to the next date-token.

2. If the found-day-of-month flag is not set and the date-token matches the day-of-month production, set the found-day-of- month flag and set the day-of-month-value to the number denoted by the date-token. Skip the remaining sub-steps and continue to the next date-token.

3. If the found-month flag is not set and the date-token matches the month production, set the found-month flag and set the month-value to the month denoted by the date-token. Skip the remaining sub-steps and continue to the next date-token.

4. If the found-year flag is not set and the date-token matches the year production, set the found-year flag and set the year-value to the number denoted by the date-token. Skip the remaining sub-steps and continue to the next date-token.

3. If the year-value is greater than or equal to 70 and less than or equal to 99, increment the year-value by 1900.

4. If the year-value is greater than or equal to 0 and less than or equal to 69, increment the year-value by 2000.

1. NOTE: Some existing user agents interpret two-digit years differently.

5. Abort these steps and fail to parse the cookie-date if:

- at least one of the found-day-of-month, found-month, found- year, or found-time flags is not set,

- the day-of-month-value is less than 1 or greater than 31,

- the year-value is less than 1601,

- the hour-value is greater than 23,

- the minute-value is greater than 59, or

- the second-value is greater than 59.

(Note that leap seconds cannot be represented in this syntax.)

6. Let the parsed-cookie-date be the date whose day-of-month, month, year, hour, minute, and second (in UTC) are the day-of-month- value, the month-value, the year-value, the hour-value, the minute-value, and the second-value, respectively. If no such date exists, abort these steps and fail to parse the cookie-date.

7. Return the parsed-cookie-date as the result of this algorithm.

## Example


```
parseDate('Wed, 09 Jun 2021 10:18:14 GMT')
```

4 changes: 2 additions & 2 deletions api/tough-cookie.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,8 @@ export const parse: (str: string, options?: {
loose?: boolean | undefined;
} | undefined) => Cookie | undefined;

// @public (undocumented)
export function parseDate(str: Nullable<string>): Date | undefined;
// @public
export function parseDate(cookieDate: Nullable<string>): Date | undefined;

// @public
export function pathMatch(reqPath: string, cookiePath: string): boolean;
Expand Down
108 changes: 103 additions & 5 deletions lib/cookie/parseDate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,19 +123,117 @@ function parseMonth(token: string): number | undefined {
}
}

/*
* RFC6265 S5.1.1 date parser (see RFC for full grammar)
/**
* Parse a cookie date string into a {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date | Date}. Parses according to
* {@link https://www.rfc-editor.org/rfc/rfc6265.html#section-5.1.1 | RFC6265 - Section 5.1.1}, not
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse | Date.parse()}.
*
* @remarks
*
* ### RFC6265 - 5.1.1. Dates
*
* The user agent MUST use an algorithm equivalent to the following
* algorithm to parse a cookie-date. Note that the various boolean
* flags defined as a part of the algorithm (i.e., found-time, found-
* day-of-month, found-month, found-year) are initially "not set".
*
* 1. Using the grammar below, divide the cookie-date into date-tokens.
*
* ```
* cookie-date = *delimiter date-token-list *delimiter
* date-token-list = date-token *( 1*delimiter date-token )
* date-token = 1*non-delimiter
*
* delimiter = %x09 / %x20-2F / %x3B-40 / %x5B-60 / %x7B-7E
* non-delimiter = %x00-08 / %x0A-1F / DIGIT / ":" / ALPHA / %x7F-FF
* non-digit = %x00-2F / %x3A-FF
*
* day-of-month = 1*2DIGIT ( non-digit *OCTET )
* month = ( "jan" / "feb" / "mar" / "apr" /
* "may" / "jun" / "jul" / "aug" /
* "sep" / "oct" / "nov" / "dec" ) *OCTET
* year = 2*4DIGIT ( non-digit *OCTET )
* time = hms-time ( non-digit *OCTET )
* hms-time = time-field ":" time-field ":" time-field
* time-field = 1*2DIGIT
* ```
*
* 2. Process each date-token sequentially in the order the date-tokens
* appear in the cookie-date:
*
* 1. If the found-time flag is not set and the token matches the
* time production, set the found-time flag and set the hour-
* value, minute-value, and second-value to the numbers denoted
* by the digits in the date-token, respectively. Skip the
* remaining sub-steps and continue to the next date-token.
*
* 2. If the found-day-of-month flag is not set and the date-token
* matches the day-of-month production, set the found-day-of-
* month flag and set the day-of-month-value to the number
* denoted by the date-token. Skip the remaining sub-steps and
* continue to the next date-token.
*
* 3. If the found-month flag is not set and the date-token matches
* the month production, set the found-month flag and set the
* month-value to the month denoted by the date-token. Skip the
* remaining sub-steps and continue to the next date-token.
*
* 4. If the found-year flag is not set and the date-token matches
* the year production, set the found-year flag and set the
* year-value to the number denoted by the date-token. Skip the
* remaining sub-steps and continue to the next date-token.
*
* 3. If the year-value is greater than or equal to 70 and less than or
* equal to 99, increment the year-value by 1900.
*
* 4. If the year-value is greater than or equal to 0 and less than or
* equal to 69, increment the year-value by 2000.
*
* 1. NOTE: Some existing user agents interpret two-digit years differently.
*
* 5. Abort these steps and fail to parse the cookie-date if:
*
* - at least one of the found-day-of-month, found-month, found-
* year, or found-time flags is not set,
*
* - the day-of-month-value is less than 1 or greater than 31,
*
* - the year-value is less than 1601,
*
* - the hour-value is greater than 23,
*
* - the minute-value is greater than 59, or
*
* - the second-value is greater than 59.
*
* (Note that leap seconds cannot be represented in this syntax.)
*
* 6. Let the parsed-cookie-date be the date whose day-of-month, month,
* year, hour, minute, and second (in UTC) are the day-of-month-
* value, the month-value, the year-value, the hour-value, the
* minute-value, and the second-value, respectively. If no such
* date exists, abort these steps and fail to parse the cookie-date.
*
* 7. Return the parsed-cookie-date as the result of this algorithm.
*
* @example
* ```
* parseDate('Wed, 09 Jun 2021 10:18:14 GMT')
* ```
*
* @param cookieDate - the cookie date string
* @public
*/
export function parseDate(str: Nullable<string>): Date | undefined {
if (!str) {
export function parseDate(cookieDate: Nullable<string>): Date | undefined {
if (!cookieDate) {
return
}

/* RFC6265 S5.1.1:
* 2. Process each date-token sequentially in the order the date-tokens
* appear in the cookie-date
*/
const tokens = str.split(DATE_DELIM)
const tokens = cookieDate.split(DATE_DELIM)
if (!tokens) {
return
}
Expand Down
Loading