]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/frontends/android/app/src/main/java/org/strongswan/android/logic/SimpleFetcher.java
Merge branch 'tun-device-ipv6'
[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;
ad2d20e5 25import java.net.SocketTimeoutException;
7b417757 26import java.net.URL;
ad2d20e5
TB
27import java.util.ArrayList;
28import java.util.concurrent.CancellationException;
29import java.util.concurrent.ExecutionException;
30import java.util.concurrent.ExecutorService;
31import java.util.concurrent.Executors;
32import java.util.concurrent.Future;
33import java.util.concurrent.TimeUnit;
34import java.util.concurrent.TimeoutException;
7b417757 35
3b9696fc
TB
36import androidx.annotation.Keep;
37
7b417757
TB
38@Keep
39public class SimpleFetcher
40{
ad2d20e5
TB
41 private static ExecutorService mExecutor = Executors.newCachedThreadPool();
42 private static Object mLock = new Object();
43 private static ArrayList<Future> mFutures = new ArrayList<>();
44 private static boolean mDisabled;
45
46 public static byte[] fetch(String uri, byte[] data, String contentType)
7b417757 47 {
ad2d20e5
TB
48 Future<byte[]> future;
49
50 synchronized (mLock)
7b417757 51 {
ad2d20e5 52 if (mDisabled)
829cc56a 53 {
ad2d20e5 54 return null;
829cc56a 55 }
ad2d20e5
TB
56 future = mExecutor.submit(() -> {
57 URL url = new URL(uri);
58 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
59 conn.setConnectTimeout(10000);
60 conn.setReadTimeout(10000);
7433f167 61 conn.setRequestProperty("Connection", "close");
ad2d20e5
TB
62 try
63 {
64 if (contentType != null)
65 {
66 conn.setRequestProperty("Content-Type", contentType);
67 }
68 if (data != null)
69 {
70 conn.setDoOutput(true);
71 conn.setFixedLengthStreamingMode(data.length);
72 OutputStream out = new BufferedOutputStream(conn.getOutputStream());
73 out.write(data);
74 out.close();
75 }
76 return streamToArray(conn.getInputStream());
77 }
78 catch (SocketTimeoutException e)
79 {
80 return null;
81 }
82 finally
83 {
84 conn.disconnect();
85 }
86 });
87
88 mFutures.add(future);
89 }
90
91 try
92 {
93 /* this enforces a timeout as the ones set on HttpURLConnection might not work reliably */
94 return future.get(10000, TimeUnit.MILLISECONDS);
95 }
96 catch (InterruptedException|ExecutionException|TimeoutException|CancellationException e)
97 {
98 return null;
99 }
100 finally
101 {
102 synchronized (mLock)
829cc56a 103 {
ad2d20e5 104 mFutures.remove(future);
829cc56a 105 }
7b417757 106 }
ad2d20e5
TB
107 }
108
109 /**
110 * Enable fetching after it has been disabled.
111 */
112 public static void enable()
113 {
114 synchronized (mLock)
115 {
116 mDisabled = false;
117 }
118 }
119
120 /**
121 * Disable the fetcher and abort any future requests.
122 *
f6aafb30 123 * The native thread is not cancelable as it is working on an IKE_SA (canceling the methods of
ad2d20e5
TB
124 * HttpURLConnection is not reliably possible anyway), so to abort while fetching we cancel the
125 * Future (causing a return from fetch() immediately) and let the executor thread continue its
126 * thing in the background.
127 *
128 * Also prevents future fetches until enabled again (e.g. if we aborted OCSP but would then
129 * block in the subsequent fetch for a CRL).
130 */
131 public static void disable()
132 {
133 synchronized (mLock)
7b417757 134 {
ad2d20e5
TB
135 mDisabled = true;
136 for (Future future : mFutures)
137 {
138 future.cancel(true);
139 }
7b417757
TB
140 }
141 }
142
829cc56a 143 private static byte[] streamToArray(InputStream in) throws IOException
7b417757
TB
144 {
145 ByteArrayOutputStream out = new ByteArrayOutputStream();
146 byte[] buf = new byte[1024];
147 int len;
148
149 try
150 {
151 while ((len = in.read(buf)) != -1)
152 {
153 out.write(buf, 0, len);
154 }
155 return out.toByteArray();
156 }
157 catch (IOException e)
158 {
159 e.printStackTrace();
160 }
829cc56a
TB
161 finally
162 {
163 in.close();
164 }
7b417757
TB
165 return null;
166 }
167}