@@ -20,6 +20,7 @@ var copy = require('copy-to');
20
20
* - {String|Array} allowHeaders `Access-Control-Allow-Headers`
21
21
* - {String|Number} maxAge `Access-Control-Max-Age` in seconds
22
22
* - {Boolean} credentials `Access-Control-Allow-Credentials`
23
+ * - {Boolean} keepHeadersOnError Add set headers to `err.header` if an error is thrown
23
24
* @return {Function }
24
25
* @api public
25
26
*/
@@ -49,6 +50,8 @@ module.exports = function (options) {
49
50
50
51
options . credentials = ! ! options . credentials ;
51
52
53
+ options . keepHeadersOnError = options . keepHeadersOnError === undefined || ! ! options . keepHeadersOnError ;
54
+
52
55
return function * cors ( next ) {
53
56
// If the Origin header is not present terminate this set of steps. The request is outside the scope of this specification.
54
57
var requestOrigin = this . get ( 'Origin' ) ;
@@ -70,54 +73,76 @@ module.exports = function (options) {
70
73
origin = options . origin || requestOrigin ;
71
74
}
72
75
76
+ var headersSet = { } ;
77
+
78
+ function set ( self , key , value ) {
79
+ self . set ( key , value ) ;
80
+ headersSet [ key ] = value ;
81
+ }
82
+
73
83
if ( this . method !== 'OPTIONS' ) {
74
84
// Simple Cross-Origin Request, Actual Request, and Redirects
75
85
76
- this . set ( 'Access-Control-Allow-Origin' , origin ) ;
86
+ set ( this , 'Access-Control-Allow-Origin' , origin ) ;
77
87
78
88
if ( options . credentials === true ) {
79
- this . set ( 'Access-Control-Allow-Credentials' , 'true' ) ;
89
+ set ( this , 'Access-Control-Allow-Credentials' , 'true' ) ;
80
90
}
81
91
82
92
if ( options . exposeHeaders ) {
83
- this . set ( 'Access-Control-Expose-Headers' , options . exposeHeaders ) ;
93
+ set ( this , 'Access-Control-Expose-Headers' , options . exposeHeaders ) ;
84
94
}
85
-
86
- yield next ;
87
95
} else {
88
96
// Preflight Request
89
97
90
98
// If there is no Access-Control-Request-Method header or if parsing failed,
91
99
// do not set any additional headers and terminate this set of steps.
92
100
// The request is outside the scope of this specification.
93
- if ( ! this . get ( 'Access-Control-Request-Method' ) ) {
94
- // this not preflight request, ignore it
95
- return yield next ;
96
- }
97
-
98
- this . set ( 'Access-Control-Allow-Origin' , origin ) ;
99
-
100
- if ( options . credentials === true ) {
101
- this . set ( 'Access-Control-Allow-Credentials' , 'true' ) ;
102
- }
103
-
104
- if ( options . maxAge ) {
105
- this . set ( 'Access-Control-Max-Age' , options . maxAge ) ;
106
- }
107
-
108
- if ( options . allowMethods ) {
109
- this . set ( 'Access-Control-Allow-Methods' , options . allowMethods ) ;
101
+ if ( this . get ( 'Access-Control-Request-Method' ) ) {
102
+ set ( this , 'Access-Control-Allow-Origin' , origin ) ;
103
+
104
+ if ( options . credentials === true ) {
105
+ set ( this , 'Access-Control-Allow-Credentials' , 'true' ) ;
106
+ }
107
+
108
+ if ( options . maxAge ) {
109
+ set ( this , 'Access-Control-Max-Age' , options . maxAge ) ;
110
+ }
111
+
112
+ if ( options . allowMethods ) {
113
+ set ( this , 'Access-Control-Allow-Methods' , options . allowMethods ) ;
114
+ }
115
+
116
+ var allowHeaders = options . allowHeaders ;
117
+ if ( ! allowHeaders ) {
118
+ allowHeaders = this . get ( 'Access-Control-Request-Headers' ) ;
119
+ }
120
+ if ( allowHeaders ) {
121
+ set ( this , 'Access-Control-Allow-Headers' , allowHeaders ) ;
122
+ }
123
+
124
+ this . status = 204 ;
110
125
}
126
+ }
111
127
112
- var allowHeaders = options . allowHeaders ;
113
- if ( ! allowHeaders ) {
114
- allowHeaders = this . get ( 'Access-Control-Request-Headers' ) ;
115
- }
116
- if ( allowHeaders ) {
117
- this . set ( 'Access-Control-Allow-Headers' , allowHeaders ) ;
128
+ if ( options . keepHeadersOnError ) {
129
+ try {
130
+ yield next ;
131
+ } catch ( err ) {
132
+ err . headers = err . headers || { } ;
133
+ if ( Object . assign ) {
134
+ Object . assign ( err . headers , headersSet ) ;
135
+ } else {
136
+ for ( var key in headersSet ) {
137
+ if ( headersSet . hasOwnProperty ( key ) ) {
138
+ err . headers [ key ] = headersSet [ key ] ;
139
+ }
140
+ }
141
+ }
142
+ throw err ;
118
143
}
119
-
120
- this . status = 204 ;
144
+ } else {
145
+ yield next ;
121
146
}
122
147
} ;
123
148
} ;
0 commit comments