]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/frontends/android/app/src/main/java/org/strongswan/android/logic/SimpleFetcher.java
Version bump to 6.0.2dr3
[thirdparty/strongswan.git] / src / frontends / android / app / src / main / java / org / strongswan / android / logic / SimpleFetcher.java
CommitLineData
7b417757 1/*
ad2d20e5 2 * Copyright (C) 2017-2018 Tobias Brunner
19ef2aec
TB
3 *
4 * Copyright (C) secunet Security Networks AG
7b417757
TB
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17package org.strongswan.android.logic;
18
829cc56a 19import java.io.BufferedOutputStream;
7b417757
TB
20import java.io.ByteArrayOutputStream;
21import java.io.IOException;
22import java.io.InputStream;
829cc56a 23import java.io.OutputStream;
7b417757 24import java.net.HttpURLConnection;
b944159f 25import java.net.Proxy;
ad2d20e5 26import java.net.SocketTimeoutException;
7b417757 27import java.net.URL;
ad2d20e5
TB
28import java.util.ArrayList;
29import java.util.concurrent.CancellationException;
30import java.util.concurrent.ExecutionException;
31import java.util.concurrent.ExecutorService;
32import java.util.concurrent.Executors;
33import java.util.concurrent.Future;
34import java.util.concurrent.TimeUnit;
35import java.util.concurrent.TimeoutException;
7b417757 36
3b9696fc
TB
37import androidx.annotation.Keep;
38
7b417757
TB
39@Keep
40public class SimpleFetcher
41{
ad2d20e5
TB
42 private static ExecutorService mExecutor = Executors.newCachedThreadPool();
43 private static Object mLock = new Object();
44 private static ArrayList<Future> mFutures = new ArrayList<>();
45 private static boolean mDisabled;
46
47 public static byte[] fetch(String uri, byte[] data, String contentType)
7b417757 48 {
ad2d20e5
TB
49 Future<byte[]> future;
50
51 synchronized (mLock)
7b417757 52 {
ad2d20e5 53 if (mDisabled)
829cc56a 54 {
ad2d20e5 55 return null;
829cc56a 56 }
ad2d20e5
TB
57 future = mExecutor.submit(() -> {
58 URL url = new URL(uri);
b944159f 59 HttpURLConnection conn = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
ad2d20e5
TB
60 conn.setConnectTimeout(10000);
61 conn.setReadTimeout(10000);
7433f167 62 conn.setRequestProperty("Connection", "close");
ad2d20e5
TB
63 try
64 {
65 if (contentType != null)
66 {
67 conn.setRequestProperty("Content-Type", contentType);
68 }
69 if (data != null)
70 {
71 conn.setDoOutput(true);
72 conn.setFixedLengthStreamingMode(data.length);
73 OutputStream out = new BufferedOutputStream(conn.getOutputStream());
74 out.write(data);
75 out.close();
76 }
77 return streamToArray(conn.getInputStream());
78 }
79 catch (SocketTimeoutException e)
80 {
81 return null;
82 }
83 finally
84 {
85 conn.disconnect();
86 }
87 });
88
89 mFutures.add(future);
90 }
91
92 try
93 {
94 /* this enforces a timeout as the ones set on HttpURLConnection might not work reliably */
95 return future.get(10000, TimeUnit.MILLISECONDS);
96 }
97 catch (InterruptedException|ExecutionException|TimeoutException|CancellationException e)
98 {
99 return null;
100 }
101 finally
102 {
103 synchronized (mLock)
829cc56a 104 {
ad2d20e5 105 mFutures.remove(future);
829cc56a 106 }
7b417757 107 }
ad2d20e5
TB
108 }
109
110 /**
111 * Enable fetching after it has been disabled.
112 */
113 public static void enable()
114 {
115 synchronized (mLock)
116 {
117 mDisabled = false;
118 }
119 }
120
121 /**
122 * Disable the fetcher and abort any future requests.
123 *
f6aafb30 124 * The native thread is not cancelable as it is working on an IKE_SA (canceling the methods of
ad2d20e5
TB
125 * HttpURLConnection is not reliably possible anyway), so to abort while fetching we cancel the
126 * Future (causing a return from fetch() immediately) and let the executor thread continue its
127 * thing in the background.
128 *
129 * Also prevents future fetches until enabled again (e.g. if we aborted OCSP but would then
130 * block in the subsequent fetch for a CRL).
131 */
132 public static void disable()
133 {
134 synchronized (mLock)
7b417757 135 {
ad2d20e5
TB
136 mDisabled = true;
137 for (Future future : mFutures)
138 {
139 future.cancel(true);
140 }
7b417757
TB
141 }
142 }
143
829cc56a 144 private static byte[] streamToArray(InputStream in) throws IOException
7b417757
TB
145 {
146 ByteArrayOutputStream out = new ByteArrayOutputStream();
147 byte[] buf = new byte[1024];
148 int len;
149
150 try
151 {
152 while ((len = in.read(buf)) != -1)
153 {
154 out.write(buf, 0, len);
155 }
156 return out.toByteArray();
157 }
158 catch (IOException e)
159 {
160 e.printStackTrace();
161 }
829cc56a
TB
162 finally
163 {
164 in.close();
165 }
7b417757
TB
166 return null;
167 }
168}