Skip to content

Commit 6c6a23d

Browse files
committed
1 parent 5f237cb commit 6c6a23d

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

src/headers.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ function validateValue(value) {
2222
}
2323
}
2424

25+
function checkGuard(obj) {
26+
if (obj._guard === 'immutable') {
27+
throw new TypeError("Cannot modify header. Immutable guard is set.")
28+
}
29+
}
30+
2531
/**
2632
* Find the key in the map object given a header name.
2733
*
@@ -46,9 +52,10 @@ export default class Headers {
4652
* Headers class
4753
*
4854
* @param Object headers Response headers
55+
* @param Object options
4956
* @return Void
5057
*/
51-
constructor(init = undefined) {
58+
constructor(init = undefined, options = undefined) {
5259
this[MAP] = Object.create(null);
5360

5461
if (init instanceof Headers) {
@@ -101,6 +108,19 @@ export default class Headers {
101108
} else {
102109
throw new TypeError('Provided initializer must be an object');
103110
}
111+
112+
if (options == null) {
113+
// no op
114+
} else if (typeof options === 'object') {
115+
if (options.guard) {
116+
// @TODO validate values for guard
117+
this._guard = options.guard;
118+
} else {
119+
this._guard = 'none';
120+
}
121+
} else {
122+
throw new TypeError('Provided options must be an object');
123+
}
104124
}
105125

106126
/**
@@ -146,6 +166,8 @@ export default class Headers {
146166
* @return Void
147167
*/
148168
set(name, value) {
169+
checkGuard(this);
170+
149171
name = `${name}`;
150172
value = `${value}`;
151173
validateName(name);
@@ -162,6 +184,8 @@ export default class Headers {
162184
* @return Void
163185
*/
164186
append(name, value) {
187+
checkGuard(this);
188+
165189
name = `${name}`;
166190
value = `${value}`;
167191
validateName(name);
@@ -193,6 +217,8 @@ export default class Headers {
193217
* @return Void
194218
*/
195219
delete(name) {
220+
checkGuard(this);
221+
196222
name = `${name}`;
197223
validateName(name);
198224
const key = find(this[MAP], name);

src/response.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
import { STATUS_CODES } from 'http';
9+
import { parse as parse_url } from 'url';
910
import Headers from './headers.js';
1011
import Body, { cloneBody , getInstanceName} from './body';
1112

@@ -74,6 +75,34 @@ export default class Response {
7475
name: `cloned(${getInstanceName(this)})`
7576
});
7677
}
78+
79+
static redirect(url, status) {
80+
//1. Let parsedURL be the result of parsing url with current settings object’s API base URL.
81+
//2. If parsedURL is failure, then throw a TypeError.
82+
const parsedURL = parse_url(url);
83+
84+
//3. If status is not a redirect status, then throw a RangeError.
85+
let intStatus = parseInt(status, 10);å
86+
if(intStatus < 300 || intStatus > 399) {
87+
throw new RangeError('Not a redirect status');
88+
}
89+
90+
//4. Let r be a new Response object, whose response is a new response.
91+
//5. Set r’s headers to a new Headers object whose guard is "immutable".
92+
//6. Set r’s response’s status to status.
93+
//7. Append `Location` to parsedURL, serialized and isomorphic encoded, in r’s response’s header list.
94+
const r = new Response(new Body(""), {
95+
url,
96+
status: intStatus,
97+
name: `redirected(${url})`,
98+
headers: new Headers({
99+
Location: url,
100+
}, { guard: 'immutable' }),
101+
});
102+
103+
//8. Return r.
104+
return r;
105+
}
77106
}
78107

79108
Body.mixIn(Response.prototype);

0 commit comments

Comments
 (0)