add HttpRequestOptions.dontFollowRedirects (#3473)

This implements the option to have http.request() not follow server's 3xx redirection replies
but instead return the exact redirection code and headers.

* on iOS, it uses a different NSURLSession instance for non-following request,
  with a NSURLSessionTaskDelegate implementing URLSessinTaskWillPerformHTTPRedirection...

* on Android, it just passes the option on to org.nativescript.widgets.Async.Http;
  so this requires the respective commit in tns-core-modules-widgets to work
This commit is contained in:
Daniel Turing
2017-01-12 10:18:20 +01:00
committed by Vladimir Enchev
parent 4f3f09e9ae
commit ee4b790728
4 changed files with 40 additions and 1 deletions

View File

@@ -155,6 +155,9 @@ function buildJavaOptions(options: http.HttpRequestOptions) {
if (types.isNumber(options.timeout)) { if (types.isNumber(options.timeout)) {
javaOptions.timeout = options.timeout; javaOptions.timeout = options.timeout;
} }
if (types.isBoolean(options.dontFollowRedirects)) {
javaOptions.dontFollowRedirects = options.dontFollowRedirects;
}
if (options.headers) { if (options.headers) {
var arrayList = new java.util.ArrayList<org.nativescript.widgets.Async.Http.KeyValuePair>(); var arrayList = new java.util.ArrayList<org.nativescript.widgets.Async.Http.KeyValuePair>();

View File

@@ -20,7 +20,28 @@ var USER_AGENT_HEADER = "User-Agent";
var USER_AGENT = `Mozilla/5.0 (i${device}; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25`; var USER_AGENT = `Mozilla/5.0 (i${device}; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25`;
var sessionConfig = getter(NSURLSessionConfiguration, NSURLSessionConfiguration.defaultSessionConfiguration); var sessionConfig = getter(NSURLSessionConfiguration, NSURLSessionConfiguration.defaultSessionConfiguration);
var queue = getter(NSOperationQueue, NSOperationQueue.mainQueue); var queue = getter(NSOperationQueue, NSOperationQueue.mainQueue);
var session = NSURLSession.sessionWithConfigurationDelegateDelegateQueue(sessionConfig, null, queue);
class NSURLSessionTaskDelegateImpl extends NSObject implements NSURLSessionTaskDelegate {
public static ObjCProtocols = [NSURLSessionTaskDelegate];
public URLSessionTaskWillPerformHTTPRedirectionNewRequestCompletionHandler(session: NSURLSession, task: NSURLSessionTask, response: NSHTTPURLResponse, request: NSURLRequest, completionHandler: (p1: NSURLRequest) => void): void {
completionHandler(null);
}
}
var sessionTaskDelegateInstance: NSURLSessionTaskDelegateImpl = <NSURLSessionTaskDelegateImpl>NSURLSessionTaskDelegateImpl.new();
var defaultSession;
function ensureDefaultSession() {
if (!defaultSession) {
defaultSession = NSURLSession.sessionWithConfigurationDelegateDelegateQueue(sessionConfig, null, queue);
}
}
var sessionNotFollowingRedirects;
function ensureSessionNotFollowingRedirects() {
if (!sessionNotFollowingRedirects) {
sessionNotFollowingRedirects = NSURLSession.sessionWithConfigurationDelegateDelegateQueue(sessionConfig, sessionTaskDelegateInstance, queue);
}
}
var imageSource: typeof imageSourceModule; var imageSource: typeof imageSourceModule;
function ensureImageSource() { function ensureImageSource() {
@@ -57,6 +78,15 @@ export function request(options: http.HttpRequestOptions): Promise<http.HttpResp
urlRequest.timeoutInterval = options.timeout / 1000; urlRequest.timeoutInterval = options.timeout / 1000;
} }
var session;
if (types.isBoolean(options.dontFollowRedirects) && options.dontFollowRedirects) {
ensureSessionNotFollowingRedirects();
session = sessionNotFollowingRedirects;
} else {
ensureDefaultSession();
session = defaultSession;
}
var dataTask = session.dataTaskWithRequestCompletionHandler(urlRequest, var dataTask = session.dataTaskWithRequestCompletionHandler(urlRequest,
function (data: NSData, response: NSHTTPURLResponse, error: NSError) { function (data: NSData, response: NSHTTPURLResponse, error: NSError) {
if (error) { if (error) {

View File

@@ -89,6 +89,11 @@ declare module "http" {
* Gets or sets the request timeout in milliseconds. * Gets or sets the request timeout in milliseconds.
*/ */
timeout?: number; timeout?: number;
/**
* Gets or sets wether to *not* follow server's redirection responses.
*/
dontFollowRedirects?: boolean;
} }
/** /**

View File

@@ -30,6 +30,7 @@
public timeout: number; public timeout: number;
public screenWidth: number; public screenWidth: number;
public screenHeight: number; public screenHeight: number;
public dontFollowRedirects: boolean;
} }
export class RequestResult { export class RequestResult {