Skip to content
This repository has been archived by the owner on Feb 22, 2018. It is now read-only.

feat(Http): Http service can make cross-site requests (get, post, put, e... #1026

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat(Http): Http service can make cross-site requests (get, post, put…
…, etc.) which use credentials (such as cookies or authorization headers).

Closes #945
  • Loading branch information
mvuksano committed May 22, 2014
commit 94601604b870b4dcc53a93a5d170afa297d8d85a
60 changes: 35 additions & 25 deletions lib/core_dom/http.dart
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ class Http {
* - headers: Map of strings or functions which return strings representing
* HTTP headers to send to the server. If the return value of a function
* is null, the header will not be sent.
* - withCredentials: True if cross-site requests should use credentials such as cookies or
* authorization headers; false otherwise. If not specified, defaults to false.
* - xsrfHeaderName: TBI
* - xsrfCookieName: TBI
* - interceptors: Either a [HttpInterceptor] or a [HttpInterceptors]
Expand All @@ -422,6 +424,7 @@ class Http {
data,
Map<String, dynamic> params,
Map<String, dynamic> headers,
bool withCredentials: false,
xsrfHeaderName,
xsrfCookieName,
interceptors,
Expand Down Expand Up @@ -481,7 +484,8 @@ class Http {
var result = _backend.request(url,
method: method,
requestHeaders: config.headers,
sendData: config.data).then((dom.HttpRequest value) {
sendData: config.data,
withCredentials: withCredentials).then((dom.HttpRequest value) {
// TODO: Uncomment after apps migrate off of this class.
// assert(value.status >= 200 && value.status < 300);

Expand Down Expand Up @@ -535,15 +539,16 @@ class Http {
String data,
Map<String, dynamic> params,
Map<String, String> headers,
bool withCredentials: false,
xsrfHeaderName,
xsrfCookieName,
interceptors,
cache,
timeout
}) => call(method: 'GET', url: url, data: data, params: params,
headers: headers, xsrfHeaderName: xsrfHeaderName,
xsrfCookieName: xsrfCookieName, interceptors: interceptors,
cache: cache, timeout: timeout);
}) => call(method: 'GET', url: url, data: data, params: params, headers: headers,
withCredentials: withCredentials, xsrfHeaderName: xsrfHeaderName,
xsrfCookieName: xsrfCookieName, interceptors: interceptors, cache: cache,
timeout: timeout);

/**
* Shortcut method for DELETE requests. See [call] for a complete description
Expand All @@ -553,15 +558,16 @@ class Http {
String data,
Map<String, dynamic> params,
Map<String, String> headers,
bool withCredentials: false,
xsrfHeaderName,
xsrfCookieName,
interceptors,
cache,
timeout
}) => call(method: 'DELETE', url: url, data: data, params: params,
headers: headers, xsrfHeaderName: xsrfHeaderName,
xsrfCookieName: xsrfCookieName, interceptors: interceptors,
cache: cache, timeout: timeout);
}) => call(method: 'DELETE', url: url, data: data, params: params, headers: headers,
withCredentials: withCredentials, xsrfHeaderName: xsrfHeaderName,
xsrfCookieName: xsrfCookieName, interceptors: interceptors, cache: cache,
timeout: timeout);

/**
* Shortcut method for HEAD requests. See [call] for a complete description
Expand All @@ -571,15 +577,16 @@ class Http {
String data,
Map<String, dynamic> params,
Map<String, String> headers,
bool withCredentials: false,
xsrfHeaderName,
xsrfCookieName,
interceptors,
cache,
timeout
}) => call(method: 'HEAD', url: url, data: data, params: params,
headers: headers, xsrfHeaderName: xsrfHeaderName,
xsrfCookieName: xsrfCookieName, interceptors: interceptors,
cache: cache, timeout: timeout);
}) => call(method: 'HEAD', url: url, data: data, params: params, headers: headers,
withCredentials: withCredentials, xsrfHeaderName: xsrfHeaderName,
xsrfCookieName: xsrfCookieName, interceptors: interceptors, cache: cache,
timeout: timeout);

/**
* Shortcut method for PUT requests. See [call] for a complete description
Expand All @@ -588,15 +595,16 @@ class Http {
async.Future<HttpResponse> put(String url, String data, {
Map<String, dynamic> params,
Map<String, String> headers,
bool withCredentials: false,
xsrfHeaderName,
xsrfCookieName,
interceptors,
cache,
timeout
}) => call(method: 'PUT', url: url, data: data, params: params,
headers: headers, xsrfHeaderName: xsrfHeaderName,
xsrfCookieName: xsrfCookieName, interceptors: interceptors,
cache: cache, timeout: timeout);
}) => call(method: 'PUT', url: url, data: data, params: params, headers: headers,
withCredentials: withCredentials, xsrfHeaderName: xsrfHeaderName,
xsrfCookieName: xsrfCookieName, interceptors: interceptors, cache: cache,
timeout: timeout);

/**
* Shortcut method for POST requests. See [call] for a complete description
Expand All @@ -605,15 +613,16 @@ class Http {
async.Future<HttpResponse> post(String url, String data, {
Map<String, dynamic> params,
Map<String, String> headers,
bool withCredentials: false,
xsrfHeaderName,
xsrfCookieName,
interceptors,
cache,
timeout
}) => call(method: 'POST', url: url, data: data, params: params,
headers: headers, xsrfHeaderName: xsrfHeaderName,
xsrfCookieName: xsrfCookieName, interceptors: interceptors,
cache: cache, timeout: timeout);
}) => call(method: 'POST', url: url, data: data, params: params, headers: headers,
withCredentials: withCredentials, xsrfHeaderName: xsrfHeaderName,
xsrfCookieName: xsrfCookieName, interceptors: interceptors, cache: cache,
timeout: timeout);

/**
* Shortcut method for JSONP requests. See [call] for a complete description
Expand All @@ -623,15 +632,16 @@ class Http {
String data,
Map<String, dynamic> params,
Map<String, String> headers,
bool withCredentials: false,
xsrfHeaderName,
xsrfCookieName,
interceptors,
cache,
timeout
}) => call(method: 'JSONP', url: url, data: data, params: params,
headers: headers, xsrfHeaderName: xsrfHeaderName,
xsrfCookieName: xsrfCookieName, interceptors: interceptors,
cache: cache, timeout: timeout);
}) => call(method: 'JSONP', url: url, data: data, params: params, headers: headers,
withCredentials: withCredentials, xsrfHeaderName: xsrfHeaderName,
xsrfCookieName: xsrfCookieName, interceptors: interceptors, cache: cache,
timeout: timeout);

/**
* Parse raw headers into key-value object
Expand Down
54 changes: 54 additions & 0 deletions test/core_dom/http_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,23 @@ void main() {
flush();
}));

describe('backend', () {
beforeEachModule((Module module) {
FakeBackend fakeBackend = new FakeBackend();
module.bind(HttpBackend, toFactory: (i) => fakeBackend);
module.bind(FakeBackend, toFactory: (i) => i.get(HttpBackend));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could it be toValue: fackBackend for both of them ?

});

it('should pass on withCredentials to backend and use GET as default method',
async((FakeBackend backend) {
http(url: '/url', method: 'GET', withCredentials: true);
microLeap();
expect(backend.url).toEqual('/url');
expect(backend.method).toEqual('GET');
expect(backend.withCredentials).toBeTruthy();
}));
});


describe('params', () {
it('should do basic request with params and encode', async(() {
Expand Down Expand Up @@ -1356,3 +1373,40 @@ class FakeFile implements File {
Blob slice([int start, int end, String contentType]) => null;
int get lastModified => new DateTime.now().millisecondsSinceEpoch;
}

class FakeBackend extends Mock implements HttpBackend {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use MockHttpBackend?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jbdeboer MockHttpBackend won't tell me if the method was called with correct parameters. Is there a way to get that info from MockHttpBacked?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you use something like https://github.com/angular/angular.dart/blob/a5d5c2b17a64acadb7935bf734da7e92d3a4cf74/test/core_dom/http_spec.dart#L72

It should be extended to support withCrdentials, ie
backend.expect('GET', '/url', withCrdentials: true).respond('');

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to @vicb's comment. You should extend the MockHttpBackend as well.


String url;
String method;
bool withCredentials;
String responseType;
String mimeType;
Map<String, String> requestHeaders;
dynamic sendData;

Future<HttpRequest> request(String url, {
String method,
bool withCredentials,
String responseType,
String mimeType,
Map<String, String> requestHeaders,
sendData,
void onProgress(ProgressEvent e)}) {
this.url = url;
this.method = method;
this.withCredentials = withCredentials;
this.responseType = responseType;
this.mimeType = mimeType;
this.requestHeaders = requestHeaders;
this.sendData = sendData;
HttpRequest request = new HttpRequest();
return new Future.value(new HttpRequest());
}
}

class FakeHttpRequest extends Mock implements HttpRequest {
FakeHttpRequest() {
when(callsTo('get status')).thenReturn(200);
when(callsTo('get responseText')).thenReturn('Fake Request');
}
}