@@ -32,6 +32,8 @@ function hasBom (buf) {
32
32
**/
33
33
function EventSource ( url , eventSourceInitDict ) {
34
34
var readyState = EventSource . CONNECTING
35
+ var headers = eventSourceInitDict && eventSourceInitDict . headers
36
+ var hasNewOrigin = false
35
37
Object . defineProperty ( this , 'readyState' , {
36
38
get : function ( ) {
37
39
return readyState
@@ -53,11 +55,12 @@ function EventSource (url, eventSourceInitDict) {
53
55
readyState = EventSource . CONNECTING
54
56
_emit ( 'error' , new Event ( 'error' , { message : message } ) )
55
57
56
- // The url may have been changed by a temporary
57
- // redirect. If that's the case, revert it now.
58
+ // The url may have been changed by a temporary redirect. If that's the case,
59
+ // revert it now, and flag that we are no longer pointing to a new origin
58
60
if ( reconnectUrl ) {
59
61
url = reconnectUrl
60
62
reconnectUrl = null
63
+ hasNewOrigin = false
61
64
}
62
65
setTimeout ( function ( ) {
63
66
if ( readyState !== EventSource . CONNECTING || self . connectionInProgress ) {
@@ -70,9 +73,9 @@ function EventSource (url, eventSourceInitDict) {
70
73
71
74
var req
72
75
var lastEventId = ''
73
- if ( eventSourceInitDict && eventSourceInitDict . headers && eventSourceInitDict . headers [ 'Last-Event-ID' ] ) {
74
- lastEventId = eventSourceInitDict . headers [ 'Last-Event-ID' ]
75
- delete eventSourceInitDict . headers [ 'Last-Event-ID' ]
76
+ if ( headers && headers [ 'Last-Event-ID' ] ) {
77
+ lastEventId = headers [ 'Last-Event-ID' ]
78
+ delete headers [ 'Last-Event-ID' ]
76
79
}
77
80
78
81
var discardTrailingNewline = false
@@ -86,9 +89,10 @@ function EventSource (url, eventSourceInitDict) {
86
89
var isSecure = options . protocol === 'https:'
87
90
options . headers = { 'Cache-Control' : 'no-cache' , 'Accept' : 'text/event-stream' }
88
91
if ( lastEventId ) options . headers [ 'Last-Event-ID' ] = lastEventId
89
- if ( eventSourceInitDict && eventSourceInitDict . headers ) {
90
- for ( var i in eventSourceInitDict . headers ) {
91
- var header = eventSourceInitDict . headers [ i ]
92
+ if ( headers ) {
93
+ var reqHeaders = hasNewOrigin ? removeUnsafeHeaders ( headers ) : headers
94
+ for ( var i in reqHeaders ) {
95
+ var header = reqHeaders [ i ]
92
96
if ( header ) {
93
97
options . headers [ i ] = header
94
98
}
@@ -148,13 +152,17 @@ function EventSource (url, eventSourceInitDict) {
148
152
149
153
// Handle HTTP redirects
150
154
if ( res . statusCode === 301 || res . statusCode === 302 || res . statusCode === 307 ) {
151
- if ( ! res . headers . location ) {
155
+ var location = res . headers . location
156
+ if ( ! location ) {
152
157
// Server sent redirect response without Location header.
153
158
_emit ( 'error' , new Event ( 'error' , { status : res . statusCode , message : res . statusMessage } ) )
154
159
return
155
160
}
161
+ var prevOrigin = new URL ( url ) . origin
162
+ var nextOrigin = new URL ( location ) . origin
163
+ hasNewOrigin = prevOrigin !== nextOrigin
156
164
if ( res . statusCode === 307 ) reconnectUrl = url
157
- url = res . headers . location
165
+ url = location
158
166
process . nextTick ( connect )
159
167
return
160
168
}
@@ -463,3 +471,23 @@ function MessageEvent (type, eventInitDict) {
463
471
}
464
472
}
465
473
}
474
+
475
+ /**
476
+ * Returns a new object of headers that does not include any authorization and cookie headers
477
+ *
478
+ * @param {Object } headers An object of headers ({[headerName]: headerValue})
479
+ * @return {Object } a new object of headers
480
+ * @api private
481
+ */
482
+ function removeUnsafeHeaders ( headers ) {
483
+ var safe = { }
484
+ for ( var key in headers ) {
485
+ if ( / ^ ( c o o k i e | a u t h o r i z a t i o n ) $ / i. test ( key ) ) {
486
+ continue
487
+ }
488
+
489
+ safe [ key ] = headers [ key ]
490
+ }
491
+
492
+ return safe
493
+ }
0 commit comments