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

Add date header to server responses #139

Merged
merged 1 commit into from
Mar 7, 2017

Conversation

legionth
Copy link
Contributor

@legionth legionth commented Mar 6, 2017

According to https://tools.ietf.org/html/rfc7231#section-7.1.1.2 a Date header should be added to the response message.

The date of a server will only be added when none date is given in the response header.

README.md Outdated
@@ -207,6 +207,9 @@ See [`writeHead()`](#writehead) for more details.

See the above usage example and the class outline for details.

A `Date` header will be automatically add the system date and time if none is given.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sentence does not parse :) Probably something like:

A Date header will be automatically added with the system date and time if none is given.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. Thank you!

README.md Outdated
@@ -207,6 +207,9 @@ See [`writeHead()`](#writehead) for more details.

See the above usage example and the class outline for details.

A `Date` header will be automatically add the system date and time if none is given.
Add a custom `Date` header via `writeHead()`](#writehead).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The leading [ for the link is missing here:

[writeHead()](#writehead)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change it in the newest commit.

src/Response.php Outdated
@@ -204,6 +204,15 @@ public function writeHead($status = 200, array $headers = array())
);
}

// assign date header if no 'date' is given, use the current time where this code is running
if (!isset($lower['Date'])) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must test against $lower['date'] (lowercase). Also, looks like this case isn't properly tested :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you are right. Changed it in the newest commit.

src/Response.php Outdated
if (!isset($lower['Date'])) {
// example: "Date: Tue, 15 Nov 1994 08:12:31 GMT"
$headers = array_merge(
array('Date' => date('D, d M Y H:i:s T')),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be gmdate('D, d M Y H:i:s') . ' GMT'.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's defined in the section just above the one you linked: https://tools.ietf.org/html/rfc7231#section-7.1.1.1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the link!

When a sender generates a
header field that contains one or more timestamps defined as
HTTP-date, the sender MUST generate those timestamps in the
IMF-fixdate format.
[…]
Preferred format:
IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @kelunik and @clue . I changed the behavior in the latest commit. Check it out.

Copy link
Member

@clue clue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An origin server MUST NOT send a Date header field if it does not
have a clock capable of providing a reasonable approximation of the
current instance in Coordinated Universal Time.

https://tools.ietf.org/html/rfc7231#section-7.1.1.2

I think this change makes perfect sense for 99% of our consumers 👍

However, the RFC specifically says one MUST NOT add a Date header if the system does not have an appropriate clock. How can I disable sending this header if my system has no such clock?

$this->assertContains("Date: ", $buffer);
$this->assertContains("Transfer-Encoding: chunked\r\n", $buffer);
$this->assertContains("Connection: close\r\n\r\n", $buffer);
$this->assertContains("\r\n\r\n", $buffer);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these changes needed? (See also below) They add quite a bit of noise to this PR.

My vote would be that the previous tests explicitly tested receiving a complete, valid HTTP response, while the new tests only test certain header fields. What is the motivation for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the newest commit, only one line changed. I removed the date from the previous tests via writeHead('Date' => array()). I think this is better readable now.

src/Response.php Outdated
if (!isset($lower['Date'])) {
// example: "Date: Tue, 15 Nov 1994 08:12:31 GMT"
$headers = array_merge(
array('Date' => date('D, d M Y H:i:s T')),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kelunik
Copy link

kelunik commented Mar 6, 2017

@clue If your system has no such clock, microtime won't exist in PHP and the event loop won't run, so nothing to worry about.

@clue
Copy link
Member

clue commented Mar 6, 2017

@kelunik microtime() will exist, however it actually returns a timestamp at an arbitrary point in time, most likely several years back and will continue to progress "normally", but will never approach the "real time". Unfortunately, this is quite common for many smaller systems, such as embedded systems or microcontroller/SOC boards.

I'm not saying this should be our main target here, but we SHOULD at least support sending NO Date header at all in these cases 👍

@legionth legionth force-pushed the date-header branch 2 times, most recently from 9b3eed7 to 49a2fe4 Compare March 6, 2017 10:31
README.md Outdated
@@ -207,6 +207,10 @@ See [`writeHead()`](#writehead) for more details.

See the above usage example and the class outline for details.

A Date header will be automatically added with the system date and time if none is given.
Add a custom `Date` header via [`writeHead()`](#writehead). If you don't have a appropriate clock to
rely on, you should unset this header with an empty array: `writeHead('Date' => array())`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Text LGTM, but should probably moved down to writeHead() 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put it into the writeHead chapter, also added some examples to it

src/Response.php Outdated
$headers = array_merge(
array('Date' => gmdate('D, d M Y H:i:s') . ' GMT'),
$headers
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this LGTM, is there a particular reason you're not using an direct array assignment here? (should be faster too)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was no particular reason. Must be my daily condition. Changed it in the newest commit.

@kelunik
Copy link

kelunik commented Mar 6, 2017

@clue If HAVE_GETTIMEOFDAY is not defined, microtime isn't registered as function, see https://github.com/php/php-src/blob/c6982995504b6e21e8a5ade29cfb16a55196dc43/ext/standard/microtime.h#L24.

@clue
Copy link
Member

clue commented Mar 6, 2017

@clue If HAVE_GETTIMEOFDAY is not defined, microtime isn't registered as function

Thanks for digging this out, but I suppose this discussion should not be really part of this PR? :)

My concern was mostly for systems that do in fact have a clock, but where the consumer of this library knows that it is always going to be out of sync, such as being several years in the past, but otherwise "normally ticking".

I think the current version should already cover this, so the changes LGTM 👍

Copy link
Member

@clue clue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, LGTM 👍

@clue clue added this to the v0.6.0 milestone Mar 6, 2017
@WyriHaximus
Copy link
Member

@legionth LGTM, could you resolve conflicts?

@legionth
Copy link
Contributor Author

legionth commented Mar 7, 2017

Ping @WyriHaximus . Resolved the conflicts

@WyriHaximus
Copy link
Member

@legionth 👍

@WyriHaximus WyriHaximus merged commit 5c5cb0b into reactphp:master Mar 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants