1 /*
2 * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
239 URIConnectionHolder(URI uri, Map<String,Object> connectionProperties) throws IOException {
240 this.uri = uri;
241 urlConnection = uri.toURL().openConnection();
242 if (connectionProperties != null) {
243 for(Map.Entry<String,Object> entry : connectionProperties.entrySet()) {
244 Object value = entry.getValue();
245 if (value instanceof String) {
246 urlConnection.setRequestProperty(entry.getKey(), (String)value);
247 }
248 }
249 }
250 channel = openChannel(null);
251 }
252
253 boolean needBuffer() {
254 String scheme = uri.getScheme().toLowerCase();
255 return ("http".equals(scheme) || "https".equals(scheme));
256 }
257
258 boolean isSeekable() {
259 return (urlConnection instanceof HttpURLConnection) || (urlConnection instanceof JarURLConnection);
260 }
261
262 boolean isRandomAccess() {
263 return false;
264 }
265
266 int readBlock(long position, int size) throws IOException {
267 throw new IOException();
268 }
269
270 public long seek(long position) {
271 if (urlConnection instanceof HttpURLConnection) {
272 URLConnection tmpURLConnection = null;
273
274 //closeConnection();
275 try{
276 tmpURLConnection = uri.toURL().openConnection();
277
278 HttpURLConnection httpConnection = (HttpURLConnection)tmpURLConnection;
279 httpConnection.setRequestMethod("GET");
280 httpConnection.setUseCaches(false);
281 httpConnection.setRequestProperty("Range", "bytes=" + position + "-");
282 // If range request worked properly we should get responce code 206 (HTTP_PARTIAL)
283 // Else fail seek and let progressbuffer to download all data. It is pointless for us to download it and throw away.
284 if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_PARTIAL) {
285 closeConnection();
286 urlConnection = tmpURLConnection;
287 tmpURLConnection = null;
288 channel = openChannel(null);
289 return position;
290 } else {
291 return -1;
292 }
293 } catch (IOException ioex) {
294 return -1;
295 } finally {
296 if (tmpURLConnection != null) {
297 Locator.closeConnection(tmpURLConnection);
298 }
299 }
300 } else if (urlConnection instanceof JarURLConnection) {
301 try {
302 closeConnection();
303
304 urlConnection = uri.toURL().openConnection();
305
306 // Skip data that we do not need
307 long skip_left = position;
308 InputStream inputStream = urlConnection.getInputStream();
309 do {
310 long skip = inputStream.skip(skip_left);
311 skip_left -= skip;
312 } while (skip_left > 0);
313
314 channel = openChannel(inputStream);
315
316 return position;
317 } catch (IOException ioex) {
318 return -1;
319 }
320 }
321
322 return -1;
323 }
324
325 @Override
326 public void closeConnection() {
327 super.closeConnection();
328
329 Locator.closeConnection(urlConnection);
330 urlConnection = null;
331 }
332
333 private ReadableByteChannel openChannel(InputStream inputStream) throws IOException {
334 return (inputStream == null) ?
335 Channels.newChannel(urlConnection.getInputStream()) :
336 Channels.newChannel(inputStream);
337 }
338 }
339
340 // A "ConnectionHolder" that "reads" from a ByteBuffer, generally loaded from
341 // some unsupported or buggy source
342 private static class MemoryConnectionHolder extends ConnectionHolder {
343 private final ByteBuffer backingBuffer;
344
345 public MemoryConnectionHolder(ByteBuffer buf) {
346 if (null == buf) {
347 throw new IllegalArgumentException("Can't connect to null buffer...");
348 }
349
350 if (buf.isDirect()) {
351 // we can use it, or rather a duplicate directly
352 backingBuffer = buf.duplicate();
353 } else {
354 // operate on a copy of the buffer
355 backingBuffer = ByteBuffer.allocateDirect(buf.capacity());
356 backingBuffer.put(buf);
|
1 /*
2 * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
239 URIConnectionHolder(URI uri, Map<String,Object> connectionProperties) throws IOException {
240 this.uri = uri;
241 urlConnection = uri.toURL().openConnection();
242 if (connectionProperties != null) {
243 for(Map.Entry<String,Object> entry : connectionProperties.entrySet()) {
244 Object value = entry.getValue();
245 if (value instanceof String) {
246 urlConnection.setRequestProperty(entry.getKey(), (String)value);
247 }
248 }
249 }
250 channel = openChannel(null);
251 }
252
253 boolean needBuffer() {
254 String scheme = uri.getScheme().toLowerCase();
255 return ("http".equals(scheme) || "https".equals(scheme));
256 }
257
258 boolean isSeekable() {
259 return (urlConnection instanceof HttpURLConnection) ||
260 (urlConnection instanceof JarURLConnection) ||
261 isJRT();
262 }
263
264 boolean isRandomAccess() {
265 return false;
266 }
267
268 int readBlock(long position, int size) throws IOException {
269 throw new IOException();
270 }
271
272 public long seek(long position) {
273 if (urlConnection instanceof HttpURLConnection) {
274 URLConnection tmpURLConnection = null;
275
276 //closeConnection();
277 try{
278 tmpURLConnection = uri.toURL().openConnection();
279
280 HttpURLConnection httpConnection = (HttpURLConnection)tmpURLConnection;
281 httpConnection.setRequestMethod("GET");
282 httpConnection.setUseCaches(false);
283 httpConnection.setRequestProperty("Range", "bytes=" + position + "-");
284 // If range request worked properly we should get responce code 206 (HTTP_PARTIAL)
285 // Else fail seek and let progressbuffer to download all data. It is pointless for us to download it and throw away.
286 if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_PARTIAL) {
287 closeConnection();
288 urlConnection = tmpURLConnection;
289 tmpURLConnection = null;
290 channel = openChannel(null);
291 return position;
292 } else {
293 return -1;
294 }
295 } catch (IOException ioex) {
296 return -1;
297 } finally {
298 if (tmpURLConnection != null) {
299 Locator.closeConnection(tmpURLConnection);
300 }
301 }
302 } else if ((urlConnection instanceof JarURLConnection) || isJRT()) {
303 try {
304 closeConnection();
305
306 urlConnection = uri.toURL().openConnection();
307
308 // Skip data that we do not need
309 long skip_left = position;
310 InputStream inputStream = urlConnection.getInputStream();
311 do {
312 long skip = inputStream.skip(skip_left);
313 skip_left -= skip;
314 } while (skip_left > 0);
315
316 channel = openChannel(inputStream);
317
318 return position;
319 } catch (IOException ioex) {
320 return -1;
321 }
322 }
323
324 return -1;
325 }
326
327 @Override
328 public void closeConnection() {
329 super.closeConnection();
330
331 Locator.closeConnection(urlConnection);
332 urlConnection = null;
333 }
334
335 private ReadableByteChannel openChannel(InputStream inputStream) throws IOException {
336 return (inputStream == null) ?
337 Channels.newChannel(urlConnection.getInputStream()) :
338 Channels.newChannel(inputStream);
339 }
340
341 private boolean isJRT() {
342 String scheme = uri.getScheme().toLowerCase();
343 return "jrt".equals(scheme);
344 }
345 }
346
347 // A "ConnectionHolder" that "reads" from a ByteBuffer, generally loaded from
348 // some unsupported or buggy source
349 private static class MemoryConnectionHolder extends ConnectionHolder {
350 private final ByteBuffer backingBuffer;
351
352 public MemoryConnectionHolder(ByteBuffer buf) {
353 if (null == buf) {
354 throw new IllegalArgumentException("Can't connect to null buffer...");
355 }
356
357 if (buf.isDirect()) {
358 // we can use it, or rather a duplicate directly
359 backingBuffer = buf.duplicate();
360 } else {
361 // operate on a copy of the buffer
362 backingBuffer = ByteBuffer.allocateDirect(buf.capacity());
363 backingBuffer.put(buf);
|