Skip to content

Commit

Permalink
Change cookie path and no redirect on expired session
Browse files Browse the repository at this point in the history
- fixes #916
- fixes #917
  • Loading branch information
marschall committed Sep 11, 2018
1 parent 883d86f commit 084c69e
Show file tree
Hide file tree
Showing 58 changed files with 338 additions and 163 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
handling
handleExpired: aRequestContext
"This method is called whenever a request is received with a key that does not match a registered handler."

aRequestContext responseGenerator
expiredRegistryKey;
respond
"This method is called whenever a request is received with a key that does not match a registered handler."

aRequestContext request isXmlHttpRequest ifTrue: [
^ aRequestContext responseGenerator
forbidden;
respond ].

"Previously, Seaside used to send a redirect response (302) with the
'Location' header set to the same path as in the request (if possible).
Any session cookie would at this point have been set for deletion (i.e.
a 'Set-Cookie' header with a request for deletion would have been set).
Unfortunately, user-agents across the board don't play well with 'Set-Cookie'
and redirect responses.
Hence, we proceed and respond as usual. If a session is to be created,
another 'Set-Cookie' header will tell the browser to use the new
session identifier from now on.
Nice side-effect: user-agents will no longer need to perform the additional
redirect when a stale cookie is still in the cache.
See https://github.com/SeasideSt/Seaside/issues/916."
self handleDefault: aRequestContext
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"handlersDo:" : "lr 7/25/2011 19:03",
"unregisterAt:" : "pmm 7/21/2015 10:39",
"trackingStrategy" : "pmm 7/16/2011 14:48",
"handleExpired:" : "Nick 6/13/2010 17:54",
"handleExpired:" : "pmm 9/10/2018 12:16",
"cache:" : "jf 1/10/2009 18:43",
"initializeCache" : "pmm 9/9/2018 18:34"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ newCookie
| cookie baseUrl |
baseUrl := self handler url.
cookie := WACookie new
path: baseUrl pathStringUnencoded;
pathUnencoded: baseUrl pathStringUnencoded
encoded: (baseUrl pathStringEncodedWith: self codec);
httpOnly: true;
yourself.
baseUrl host isNil ifFalse: [ cookie domain: baseUrl host ].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"instance" : {
"newDocument" : "pmm 8/23/2014 14:50",
"consumer" : "pmm 8/31/2009 10:51",
"newCookie" : "pmm 9/8/2013 15:52",
"newCookie" : "pmm 9/10/2018 14:49",
"handler" : "jf 7/18/2009 22:36",
"request" : "jf 7/18/2009 22:26",
"registry" : "jf 7/18/2009 22:34",
Expand Down
18 changes: 17 additions & 1 deletion repository/Seaside-Core.package/WARequestCookie.class/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,23 @@ key
- xxxxx

path
- xxxxx
- According to https://tools.ietf.org/html/rfc6265#section-5.1.4 user-agents must use an algorithm equivalent to the following one:
1. Let uri-path be the path portion of the request-uri if such a
portion exists (and empty otherwise). For example, if the
request-uri contains just a path (and optional query string),
then the uri-path is that path (without the %x3F ("?") character
or query string), and if the request-uri contains a full
absoluteURI, the uri-path is the path component of that URI.

2. If the uri-path is empty or if the first character of the uri-
path is not a %x2F ("/") character, output %x2F ("/") and skip
the remaining steps.

3. If the uri-path contains no more than one %x2F ("/") character,
output %x2F ("/") and skip the remaining step.

4. Output the characters of the uri-path from the first character up
to, but not including, the right-most %x2F ("/").

ports
- xxxxx
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
initialization
initialize
super initialize.

"According to https://tools.ietf.org/html/rfc6265#section-5.1.4
user-agents must use '/' as the default path (see class comment)"
path := '/'.
pathEncoded := '/'
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
accessing
path: aString
self pathUnencoded: aString codec: nil
path := self sanitizePath: aString.

self
pathUnencoded: path
codec: nil
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
accessing
path
^ path ifNil: [ '/' ]
^ path
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
accessing
pathUnencoded: aString codec: aCodec
path := aString.
pathEncoded := aString isNil
ifTrue: [ '/' ]
ifFalse: [
| codec |
aString = '/' ifTrue: [
pathEncoded := '/'.
^ self ].

pathEncoded := String new: (aString size * 1.1) greaseInteger streamContents: [ :stream |
| codec encoder |
codec := aCodec isNil ifTrue: [ self requestContext codec ] ifFalse: [ aCodec ].
String new: (aString size * 1.1) greaseInteger streamContents: [ :stream |
| encoder |
encoder := GRPlatform current urlEncoderOn: stream codec: codec.
GRPlatform subStringsIn: path splitBy: $/ do: [ :each |
stream nextPut: $/.
encoder nextPutAll: each ] ] ]
encoder := GRPlatform current urlEncoderOn: stream codec: codec.
GRPlatform subStringsIn: aString splitBy: $/ do: [ :each |
stream nextPut: $/.
encoder nextPutAll: each ] ]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
accessing
pathUnencoded: aFirstString encoded: aSecondString
path := aFirstString.
pathEncoded := aSecondString
path := self sanitizePath: aFirstString.
pathEncoded := self sanitizePath: aSecondString
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
accessing
pathUnencoded
^ path
^ self path
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
private
sanitizePath: aString
"Make sure aString follows https://tools.ietf.org/html/rfc6265#section-5.1.4 rules"
| sanitized |
sanitized := aString.
(#(nil '' '/') includes: sanitized) ifTrue: [
"treat nil '' '/' all as '/"
sanitized := '/' ].
"make sure path starts with /"
sanitized first = $/ ifFalse: [
sanitized := '/', sanitized ].
"make sure path does not end with /"
[ sanitized size > 1 and: [ sanitized last = $/ ] ] whileTrue: [
sanitized := sanitized allButLast ].
^ sanitized
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
{
"instance" : {
"value:" : "pmm 2/21/2008 21:31",
"sanitizePath:" : "pmm 9/10/2018 18:05",
"initialize" : "pmm 9/10/2018 15:02",
"key" : "pmm 2/21/2008 21:30",
"pathEncoded" : "pmm 9/11/2013 12:38",
"ports:" : "pmm 2/21/2008 06:43",
"path" : "lr 7/25/2011 19:03",
"path" : "pmm 9/10/2018 12:26",
"ports" : "pmm 2/21/2008 06:43",
"postCopy" : "pmm 4/5/2008 15:22",
"version:" : "pmm 2/21/2008 22:36",
"setPorts:" : "pmm 9/1/2012 17:46",
"domain:" : "pmm 2/21/2008 06:42",
"pathUnencoded" : "pmm 9/11/2013 12:38",
"pathUnencoded:encoded:" : "pmm 9/11/2013 12:38",
"pathUnencoded" : "pmm 9/10/2018 14:53",
"pathUnencoded:encoded:" : "pmm 9/10/2018 14:47",
"domain" : "pmm 2/21/2008 06:42",
"pathUnencoded:codec:" : "pmm 9/11/2013 12:35",
"pathUnencoded:codec:" : "pmm 9/10/2018 15:39",
"version" : "pmm 2/21/2008 22:36",
"key:" : "pmm 2/21/2008 21:30",
"hash" : "lr 7/25/2011 20:09",
"=" : "pmm 3/22/2008 15:58",
"pathEncoded:codec:" : "pmm 9/11/2013 12:15",
"value" : "pmm 2/21/2008 21:31",
"path:" : "pmm 9/11/2013 12:35",
"path:" : "pmm 9/10/2018 14:43",
"port:" : "pmm 3/22/2008 20:09"
},
"class" : {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"commentStamp" : "pmm 9/8/2013 16:18",
"commentStamp" : "pmm 9/10/2018 18:07",
"super" : "WAObject",
"category" : "Seaside-Core-HTTP",
"classinstvars" : [ ],
Expand Down
4 changes: 2 additions & 2 deletions repository/Seaside-Core.package/monticello.meta/version

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ testCombine
combine: (Array with: cookie1 with: cookie2)
using: [ :each | each rfc6265String ].

self assert: actual = 'ikuser=1234; expires=Wed, 21-Nov-2007 12:42:48 GMT, JSESSIONID=8543783483494373483764'
self assert: actual = 'ikuser=1234; expires=Wed, 21-Nov-2007 12:42:48 GMT; path=/, JSESSIONID=8543783483494373483764; path=/'
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ testExpirePrinting
| cookie |
cookie := WACookie key: 'foo' value: 'bar'.
cookie expiry: (DateAndTime year: 2003 day: 4 hour: 5 minute: 6 second: 7 offset: Duration zero).
self assert: cookie rfc6265String = 'foo=bar; expires=Sat, 04-Jan-2003 05:06:07 GMT'
self assert: cookie rfc6265String = 'foo=bar; expires=Sat, 04-Jan-2003 05:06:07 GMT; path=/'
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
tests
testSettingEmptyPath
"According to https://tools.ietf.org/html/rfc6265#section-5.1.4
user-agents must use '/' as the default path (see class comment)"
| cookie |
cookie := WACookie new
key: 'name';
value: 'homer';
path: '';
yourself.

self assert: cookie path equals: '/'.
self assert: cookie pathUnencoded equals: '/'.
self assert: cookie pathEncoded equals: '/'
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
tests
testSettingNilPath
"According to https://tools.ietf.org/html/rfc6265#section-5.1.4
user-agents must use '/' as the default path (see class comment)"
| cookie |
cookie := WACookie new
key: 'name';
value: 'homer';
path: nil;
yourself.

self assert: cookie path equals: '/'.
self assert: cookie pathUnencoded equals: '/'.
self assert: cookie pathEncoded equals: '/'
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
tests
testSettingPathWithTrailingSlash
"According to https://tools.ietf.org/html/rfc6265#section-5.1.4
trailing slashes must be ignored by user-agents (see class comment)"
| cookie |
cookie := WACookie new
key: 'name';
value: 'homer';
path: '/springfield/';
yourself.

self assert: cookie path equals: '/springfield'.
self assert: cookie pathUnencoded equals: '/springfield'.
self assert: cookie pathEncoded equals: '/springfield'
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
tests
testSettingPathWithoutLeadingSlash
"According to https://tools.ietf.org/html/rfc6265#section-5.1.4
user-agents must ignore paths without leading slash and use '/'.
We ensure that the path starts with slash. (see class comment)"
| cookie |
cookie := WACookie new
key: 'name';
value: 'homer';
path: 'springfield/powerplant';
yourself.

self assert: cookie path equals: '/springfield/powerplant'.
self assert: cookie pathUnencoded equals: '/springfield/powerplant'.
self assert: cookie pathEncoded equals: '/springfield/powerplant'
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
tests
testSettingRegularPath
| cookie |
cookie := WACookie new
key: 'name';
value: 'homer';
path: '/springfield/powerplant';
yourself.

self assert: cookie path equals: '/springfield/powerplant'.
self assert: cookie pathUnencoded equals: '/springfield/powerplant'.
self assert: cookie pathEncoded equals: '/springfield/powerplant'
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
tests
testSettingRootPath
| cookie |
cookie := WACookie new
key: 'name';
value: 'homer';
path: '/';
yourself.

self assert: cookie path equals: '/'.
self assert: cookie pathUnencoded equals: '/'.
self assert: cookie pathEncoded equals: '/'
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ testWriteOn
| expiry cookie |
expiry := DateAndTime year: 2007 month: 11 day: 21 hour: 14 minute: 42 second: 48 offset: (Duration days: 0 hours: 2 minutes: 0 seconds: 0).
cookie := WACookie key: 'ikuser' value: '1234'.
self assert: cookie oldNetscapeString = 'ikuser=1234'.
self assert: cookie rfc2109String = 'ikuser="1234"; Version=1'.
self assert: cookie rfc2965String = 'ikuser="1234"; Version=1'.
self assert: cookie rfc6265String = 'ikuser=1234'.
self assert: cookie oldNetscapeString = 'ikuser=1234; path=/'.
self assert: cookie rfc2109String = 'ikuser="1234"; path="/"; Version=1'.
self assert: cookie rfc2965String = 'ikuser="1234"; path="/"; Version=1'.
self assert: cookie rfc6265String = 'ikuser=1234; path=/'.

cookie expiry: expiry.
cookie maxAge: 3600.
self assert: cookie oldNetscapeString = 'ikuser=1234; expires=Wed, 21-Nov-2007 12:42:48 GMT'.
self assert: cookie rfc2109String = 'ikuser="1234"; Max-Age="3600"; Version=1'.
self assert: cookie rfc2965String = 'ikuser="1234"; Max-Age="3600"; Version=1'.
self assert: cookie rfc6265String = 'ikuser=1234; expires=Wed, 21-Nov-2007 12:42:48 GMT; Max-Age=3600'.
self assert: cookie oldNetscapeString = 'ikuser=1234; expires=Wed, 21-Nov-2007 12:42:48 GMT; path=/'.
self assert: cookie rfc2109String = 'ikuser="1234"; Max-Age="3600"; path="/"; Version=1'.
self assert: cookie rfc2965String = 'ikuser="1234"; Max-Age="3600"; path="/"; Version=1'.
self assert: cookie rfc6265String = 'ikuser=1234; expires=Wed, 21-Nov-2007 12:42:48 GMT; Max-Age=3600; path=/'.

cookie path: '/seaside/counter'.
self assert: cookie oldNetscapeString = 'ikuser=1234; expires=Wed, 21-Nov-2007 12:42:48 GMT; path=/seaside/counter'.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
{
"instance" : {
"testCopy" : "pmm 9/1/2012 16:17",
"testWriteOn" : "pmm 8/16/2014 14:19",
"testFromStringRfc2965" : "pmm 9/11/2013 12:24",
"testExpireInPast" : "pmm 4/5/2008 15:42",
"testExpirePrinting" : "pmm 8/16/2014 13:40",
"testWriteOn" : "pmm 9/10/2018 15:10",
"testFromStringOldNetscape" : "pmm 9/11/2013 12:22",
"testSettingRootPath" : "pmm 9/10/2018 15:10",
"testPathEncoding" : "pmm 9/11/2013 12:42",
"testExpirePrinting" : "pmm 9/10/2018 15:08",
"testSettingNilPath" : "pmm 9/10/2018 15:09",
"testSettingPathWithoutLeadingSlash" : "pmm 9/10/2018 15:10",
"testEquals" : "pmm 9/1/2012 16:17",
"testCombine" : "pmm 8/16/2014 14:01"
"testExpireInPast" : "pmm 4/5/2008 15:42",
"testSettingEmptyPath" : "pmm 9/10/2018 15:09",
"testSettingPathWithTrailingSlash" : "pmm 9/10/2018 15:09",
"testFromStringRfc2965" : "pmm 9/11/2013 12:24",
"testSettingRegularPath" : "pmm 9/10/2018 15:10",
"testCombine" : "pmm 9/10/2018 15:07"
},
"class" : { }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ tests-cache
testDeleteCookie
| cookie actual |
cookie := (WARequestCookie key: 'key' value: 'value')
pathUnencoded: '/highway/to/hell' codec: GRNullCodec new;
pathUnencoded: '/highway/to/hell' encoded: '/highway/to/hell';
domain: 'hotel'
yourself.
self response deleteCookie: cookie.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"testCacheForeverExpiryDate" : "lr 1/17/2009 18:00",
"contents" : "lr 1/17/2009 17:28",
"testHeadersAtPut" : "lr 1/17/2009 17:35",
"testDeleteCookie" : "pmm 9/11/2013 12:36",
"testDeleteCookie" : "pmm 9/10/2018 15:53",
"testDoNotCacheExpiryDate" : "lr 1/17/2009 18:00",
"testMessage" : "pmm 9/1/2012 16:50",
"testStatus" : "lr 1/17/2009 17:40",
Expand Down
Loading

0 comments on commit 084c69e

Please sign in to comment.