1+ package com .nativescript .https ;
2+ /*
3+ * Copyright (C) 2016 Square, Inc.
4+ *
5+ * Licensed under the Apache License, Version 2.0 (the "License");
6+ * you may not use this file except in compliance with the License.
7+ * You may obtain a copy of the License at
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ */
17+
18+ import java .io .IOException ;
19+ import java .net .CookieHandler ;
20+ import java .net .HttpCookie ;
21+ import java .util .ArrayList ;
22+ import java .util .Collections ;
23+ import java .util .List ;
24+ import java .util .Map ;
25+ import okhttp3 .Cookie ;
26+ import okhttp3 .CookieJar ;
27+ import okhttp3 .HttpUrl ;
28+ import okhttp3 .internal .platform .Platform ;
29+
30+ import static okhttp3 .internal .Util .delimiterOffset ;
31+ import static okhttp3 .internal .Util .trimSubstring ;
32+ import static okhttp3 .internal .platform .Platform .WARN ;
33+
34+ /** A cookie jar that delegates to a {@link java.net.CookieHandler}. */
35+ public final class QuotePreservingCookieJar implements CookieJar {
36+ private final CookieHandler cookieHandler ;
37+
38+ public QuotePreservingCookieJar (CookieHandler cookieHandler ) {
39+ this .cookieHandler = cookieHandler ;
40+ }
41+
42+ @ Override public void saveFromResponse (HttpUrl url , List <Cookie > cookies ) {
43+ if (cookieHandler != null ) {
44+ List <String > cookieStrings = new ArrayList <>();
45+ for (Cookie cookie : cookies ) {
46+ cookieStrings .add (cookie .toString ().replaceAll ("; domain=" , "; domain=." ));
47+ }
48+ Map <String , List <String >> multimap = Collections .singletonMap ("Set-Cookie" , cookieStrings );
49+ try {
50+ cookieHandler .put (url .uri (), multimap );
51+ } catch (IOException e ) {
52+ Platform .get ().log (WARN , "Saving cookies failed for " + url .resolve ("/..." ), e );
53+ }
54+ }
55+ }
56+
57+ @ Override public List <Cookie > loadForRequest (HttpUrl url ) {
58+ // The RI passes all headers. We don't have 'em, so we don't pass 'em!
59+ Map <String , List <String >> headers = Collections .emptyMap ();
60+ Map <String , List <String >> cookieHeaders ;
61+ try {
62+ cookieHeaders = cookieHandler .get (url .uri (), headers );
63+ } catch (IOException e ) {
64+ Platform .get ().log (WARN , "Loading cookies failed for " + url .resolve ("/..." ), e );
65+ return Collections .emptyList ();
66+ }
67+
68+ List <Cookie > cookies = null ;
69+ for (Map .Entry <String , List <String >> entry : cookieHeaders .entrySet ()) {
70+ String key = entry .getKey ();
71+ if (("Cookie" .equalsIgnoreCase (key ) || "Cookie2" .equalsIgnoreCase (key ))
72+ && !entry .getValue ().isEmpty ()) {
73+ for (String header : entry .getValue ()) {
74+ if (cookies == null ) cookies = new ArrayList <>();
75+ cookies .addAll (decodeHeaderAsJavaNetCookies (url , header ));
76+ }
77+ }
78+ }
79+
80+ return cookies != null
81+ ? Collections .unmodifiableList (cookies )
82+ : Collections .<Cookie >emptyList ();
83+ }
84+
85+ /**
86+ * Convert a request header to OkHttp's cookies via {@link HttpCookie}. That extra step handles
87+ * multiple cookies in a single request header, which {@link Cookie#parse} doesn't support.
88+ */
89+ private List <Cookie > decodeHeaderAsJavaNetCookies (HttpUrl url , String header ) {
90+ List <Cookie > result = new ArrayList <>();
91+ for (int pos = 0 , limit = header .length (), pairEnd ; pos < limit ; pos = pairEnd + 1 ) {
92+ pairEnd = delimiterOffset (header , pos , limit , ";," );
93+ int equalsSign = delimiterOffset (header , pos , pairEnd , '=' );
94+ String name = trimSubstring (header , pos , equalsSign );
95+ if (name .startsWith ("$" )) continue ;
96+
97+ // We have either name=value or just a name.
98+ String value = equalsSign < pairEnd
99+ ? trimSubstring (header , equalsSign + 1 , pairEnd )
100+ : "" ;
101+
102+ result .add (new Cookie .Builder ()
103+ .name (name )
104+ .value (value )
105+ .domain (url .host ())
106+ .build ());
107+ }
108+ return result ;
109+ }
110+ }
0 commit comments