forked from angular/angular
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstatic_request.ts
More file actions
173 lines (164 loc) · 5.58 KB
/
Copy pathstatic_request.ts
File metadata and controls
173 lines (164 loc) · 5.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
import {ContentType, RequestMethod} from './enums';
import {RequestArgs} from './interfaces';
import {Headers} from './headers';
import {URLSearchParams} from './url_search_params';
import {normalizeMethodName} from './http_utils';
import {isPresent, StringWrapper} from '../src/facade/lang';
// TODO(jeffbcross): properly implement body accessors
/**
* Creates `Request` instances from provided values.
*
* The Request's interface is inspired by the Request constructor defined in the [Fetch
* Spec](https://fetch.spec.whatwg.org/#request-class),
* but is considered a static value whose body can be accessed many times. There are other
* differences in the implementation, but this is the most significant.
*
* `Request` instances are typically created by higher-level classes, like {@link Http} and
* {@link Jsonp}, but it may occasionally be useful to explicitly create `Request` instances.
* One such example is when creating services that wrap higher-level services, like {@link Http},
* where it may be useful to generate a `Request` with arbitrary headers and search params.
*
* ```typescript
* import {Injectable, Injector} from '@angular/core';
* import {HTTP_PROVIDERS, Http, Request, RequestMethod} from '@angular/http';
*
* @Injectable()
* class AutoAuthenticator {
* constructor(public http:Http) {}
* request(url:string) {
* return this.http.request(new Request({
* method: RequestMethod.Get,
* url: url,
* search: 'password=123'
* }));
* }
* }
*
* var injector = Injector.resolveAndCreate([HTTP_PROVIDERS, AutoAuthenticator]);
* var authenticator = injector.get(AutoAuthenticator);
* authenticator.request('people.json').subscribe(res => {
* //URL should have included '?password=123'
* console.log('people', res.json());
* });
* ```
*/
export class Request {
/**
* Http method with which to perform the request.
*/
method: RequestMethod;
/**
* {@link Headers} instance
*/
headers: Headers;
/** Url of the remote resource */
url: string;
/** Body of the request **/
private _body: any;
/** Type of the request body **/
private contentType: ContentType;
/** Enable use credentials */
withCredentials: boolean;
constructor(requestOptions: RequestArgs) {
// TODO: assert that url is present
let url = requestOptions.url;
this.url = requestOptions.url;
if (isPresent(requestOptions.search)) {
let search = requestOptions.search.toString();
if (search.length > 0) {
let prefix = '?';
if (StringWrapper.contains(this.url, '?')) {
prefix = (this.url[this.url.length - 1] == '&') ? '' : '&';
}
// TODO: just delete search-query-looking string in url?
this.url = url + prefix + search;
}
}
this._body = requestOptions.body;
this.contentType = this.detectContentType();
this.method = normalizeMethodName(requestOptions.method);
// TODO(jeffbcross): implement behavior
// Defaults to 'omit', consistent with browser
// TODO(jeffbcross): implement behavior
this.headers = new Headers(requestOptions.headers);
this.withCredentials = requestOptions.withCredentials;
}
/**
* Returns the request's body as string, assuming that body exists. If body is undefined, return
* empty
* string.
*/
text(): string { return isPresent(this._body) ? this._body.toString() : ''; }
/**
* Returns the request's body as JSON string, assuming that body exists. If body is undefined,
* return
* empty
* string.
*/
json(): string { return isPresent(this._body) ? JSON.stringify(this._body) : ''; }
/**
* Returns the request's body as array buffer, assuming that body exists. If body is undefined,
* return
* null.
*/
arrayBuffer(): ArrayBuffer {
if (this._body instanceof ArrayBuffer) return <ArrayBuffer>this._body;
throw "The request body isn't an array buffer";
}
/**
* Returns the request's body as blob, assuming that body exists. If body is undefined, return
* null.
*/
blob(): Blob {
if (this._body instanceof Blob) return <Blob>this._body;
if (this._body instanceof ArrayBuffer) return new Blob([this._body]);
throw "The request body isn't either a blob or an array buffer";
}
/**
* Returns the content type of request's body based on its type.
*/
detectContentType() {
if (this._body == null) {
return ContentType.NONE;
} else if (this._body instanceof URLSearchParams) {
return ContentType.FORM;
} else if (this._body instanceof FormData) {
return ContentType.FORM_DATA;
} else if (this._body instanceof Blob) {
return ContentType.BLOB;
} else if (this._body instanceof ArrayBuffer) {
return ContentType.ARRAY_BUFFER;
} else if (this._body && typeof this._body == 'object') {
return ContentType.JSON;
} else {
return ContentType.TEXT;
}
}
/**
* Returns the request's body according to its type. If body is undefined, return
* null.
*/
getBody(): any {
switch (this.contentType) {
case ContentType.JSON:
return this.json();
case ContentType.FORM:
return this.text();
case ContentType.FORM_DATA:
return this._body;
case ContentType.TEXT:
return this.text();
case ContentType.BLOB:
return this.blob();
case ContentType.ARRAY_BUFFER:
return this.arrayBuffer();
default:
return null;
}
}
}
const noop = function () {};
const w = typeof window == 'object' ? window : noop;
const FormData = w['FormData'] || noop;
const Blob = w['Blob'] || noop;
const ArrayBuffer = w['ArrayBuffer'] || noop;