Skip to content

Commit

Permalink
feat: basick cookie support
Browse files Browse the repository at this point in the history
  • Loading branch information
farfromrefug committed Apr 11, 2020
1 parent 0d9d331 commit 91fe3c7
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 3 deletions.
13 changes: 11 additions & 2 deletions src/https.android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ export function disableSSLPinning() {
console.info('nativescript-https > Disabled SSL pinning by default');

let Client: okhttp3.OkHttpClient;

let cookieJar: com.nativescript.https.QuotePreservingCookieJar;
let cookieManager: java.net.CookieManager;
function getClient(reload: boolean = false, timeout: number = 10): okhttp3.OkHttpClient {
// if (!Client) {
// Client = new okhttp3.OkHttpClient()
Expand All @@ -113,6 +114,11 @@ function getClient(reload: boolean = false, timeout: number = 10): okhttp3.OkHtt
if (Client && reload === false && _timeout === timeout) {
return Client;
}
if (!cookieJar) {
cookieManager = new java.net.CookieManager();
cookieManager.setCookiePolicy(java.net.CookiePolicy.ACCEPT_ALL);
cookieJar = new com.nativescript.https.QuotePreservingCookieJar(cookieManager);
}

_timeout = timeout;

Expand Down Expand Up @@ -191,6 +197,9 @@ function getClient(reload: boolean = false, timeout: number = 10): okhttp3.OkHtt
if (cache) {
client.cache(cache);
}
if (cookieJar) {
client.cookieJar(cookieJar)
}

// set connection timeout to override okhttp3 default
if (timeout) {
Expand All @@ -211,7 +220,7 @@ export function request(opts: Https.HttpsRequestOptions): Promise<Https.HttpsRes
request.url(opts.url);

if (opts.headers) {
// console.log('adding request header', opts.headers)
console.log('adding request header', opts.headers)
Object.keys(opts.headers).forEach(key => request.addHeader(key, opts.headers[key] as any));
}

Expand Down
4 changes: 3 additions & 1 deletion src/https.ios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ export function request(opts: Https.HttpsRequestOptions): Promise<Https.HttpsRes
manager.responseSerializer = AFHTTPResponseSerializer.serializer();
}
manager.requestSerializer.allowsCellularAccess = true;
manager.securityPolicy = (policies.secured === true) ? policies.secure : policies.def;
manager.requestSerializer.HTTPShouldHandleCookies = true;
manager.securityPolicy =
policies.secured === true ? policies.secure : policies.def;

if (opts.cachePolicy) {
switch (opts.cachePolicy) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package com.nativescript.https;
/*
* Copyright (C) 2016 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.io.IOException;
import java.net.CookieHandler;
import java.net.HttpCookie;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.internal.platform.Platform;

import static okhttp3.internal.Util.delimiterOffset;
import static okhttp3.internal.Util.trimSubstring;
import static okhttp3.internal.platform.Platform.WARN;

/** A cookie jar that delegates to a {@link java.net.CookieHandler}. */
public final class QuotePreservingCookieJar implements CookieJar {
private final CookieHandler cookieHandler;

public QuotePreservingCookieJar(CookieHandler cookieHandler) {
this.cookieHandler = cookieHandler;
}

@Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
if (cookieHandler != null) {
List<String> cookieStrings = new ArrayList<>();
for (Cookie cookie : cookies) {
cookieStrings.add(cookie.toString().replaceAll("; domain=", "; domain=."));
}
Map<String, List<String>> multimap = Collections.singletonMap("Set-Cookie", cookieStrings);
try {
cookieHandler.put(url.uri(), multimap);
} catch (IOException e) {
Platform.get().log(WARN, "Saving cookies failed for " + url.resolve("/..."), e);
}
}
}

@Override public List<Cookie> loadForRequest(HttpUrl url) {
// The RI passes all headers. We don't have 'em, so we don't pass 'em!
Map<String, List<String>> headers = Collections.emptyMap();
Map<String, List<String>> cookieHeaders;
try {
cookieHeaders = cookieHandler.get(url.uri(), headers);
} catch (IOException e) {
Platform.get().log(WARN, "Loading cookies failed for " + url.resolve("/..."), e);
return Collections.emptyList();
}

List<Cookie> cookies = null;
for (Map.Entry<String, List<String>> entry : cookieHeaders.entrySet()) {
String key = entry.getKey();
if (("Cookie".equalsIgnoreCase(key) || "Cookie2".equalsIgnoreCase(key))
&& !entry.getValue().isEmpty()) {
for (String header : entry.getValue()) {
if (cookies == null) cookies = new ArrayList<>();
cookies.addAll(decodeHeaderAsJavaNetCookies(url, header));
}
}
}

return cookies != null
? Collections.unmodifiableList(cookies)
: Collections.<Cookie>emptyList();
}

/**
* Convert a request header to OkHttp's cookies via {@link HttpCookie}. That extra step handles
* multiple cookies in a single request header, which {@link Cookie#parse} doesn't support.
*/
private List<Cookie> decodeHeaderAsJavaNetCookies(HttpUrl url, String header) {
List<Cookie> result = new ArrayList<>();
for (int pos = 0, limit = header.length(), pairEnd; pos < limit; pos = pairEnd + 1) {
pairEnd = delimiterOffset(header, pos, limit, ";,");
int equalsSign = delimiterOffset(header, pos, pairEnd, '=');
String name = trimSubstring(header, pos, equalsSign);
if (name.startsWith("$")) continue;

// We have either name=value or just a name.
String value = equalsSign < pairEnd
? trimSubstring(header, equalsSign + 1, pairEnd)
: "";

result.add(new Cookie.Builder()
.name(name)
.value(value)
.domain(url.host())
.build());
}
return result;
}
}
3 changes: 3 additions & 0 deletions src/references.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ declare namespace com {
public constructor();
onStringResponse( responseString:string, statusCode: number, headers: okhttp3.Headers)
}
class QuotePreservingCookieJar extends okhttp3.CookieJar {
constructor(cookieHandler:java.net.CookieHandler)
}
}
}
}

0 comments on commit 91fe3c7

Please sign in to comment.