http-client-branch: HTTP Client file publishers, handlers, and subscribers as capability objects
--- a/src/java.net.http/share/classes/java/net/http/HttpRequest.java Fri Feb 16 10:34:17 2018 +0000
+++ b/src/java.net.http/share/classes/java/net/http/HttpRequest.java Fri Feb 16 15:06:29 2018 +0000
@@ -580,6 +580,10 @@
/**
* A request body publisher that takes data from the contents of a File.
*
+ * <p> Security manager permission checks are performed in this factory
+ * method, when a {@code BodyPublisher} is created. Care must be taken
+ * that the {@code BodyPublisher} is not shared with untrusted code.
+ *
* @param path the path to the file containing the body
* @return a BodyPublisher
* @throws java.io.FileNotFoundException if the path is not found
--- a/src/java.net.http/share/classes/java/net/http/HttpResponse.java Fri Feb 16 10:34:17 2018 +0000
+++ b/src/java.net.http/share/classes/java/net/http/HttpResponse.java Fri Feb 16 15:06:29 2018 +0000
@@ -33,9 +33,9 @@
import java.nio.charset.Charset;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -54,6 +54,8 @@
import jdk.internal.net.http.ResponseBodyHandlers.PathBodyHandler;
import jdk.internal.net.http.ResponseBodyHandlers.PushPromisesHandlerWithMap;
import jdk.internal.net.http.ResponseSubscribers;
+import jdk.internal.net.http.ResponseSubscribers.PathSubscriber;
+import static java.nio.file.StandardOpenOption.*;
import static jdk.internal.net.http.common.Utils.charsetFrom;
/**
@@ -449,49 +451,53 @@
* been completely written to the file, and {@link #body()} returns a
* reference to its {@link Path}.
*
- * @param file the filename to store the body in
+ * <p> Security manager permission checks are performed in this factory
+ * method, when a {@code BodyHandler} is created. Care must be taken
+ * that the {@code BodyHandler} is not shared with untrusted code.
+ *
+ * @param file the file to store the body in
* @param openOptions any options to use when opening/creating the file
* @return a response body handler
+ * @throws IllegalArgumentException if an invalid set of open options
+ * are specified
* @throws SecurityException If a security manager has been installed
* and it denies {@link SecurityManager#checkWrite(String)
- * write access} to the file. The {@link
- * SecurityManager#checkDelete(String) checkDelete} method is
- * invoked to check delete access if the file is opened with
- * the {@code DELETE_ON_CLOSE} option.
+ * write access} to the file.
*/
public static BodyHandler<Path> asFile(Path file, OpenOption... openOptions) {
Objects.requireNonNull(file);
List<OpenOption> opts = List.of(openOptions);
+ if (opts.contains(DELETE_ON_CLOSE) || opts.contains(READ)) {
+ // these options make no sense, since the FileChannel is not exposed
+ throw new IllegalArgumentException("invalid openOptions: " + opts);
+ }
+
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
String fn = pathForSecurityCheck(file);
sm.checkWrite(fn);
- if (opts.contains(StandardOpenOption.DELETE_ON_CLOSE))
- sm.checkDelete(fn);
- if (opts.contains(StandardOpenOption.READ))
- sm.checkRead(fn);
}
- return new PathBodyHandler(file, openOptions);
+ return new PathBodyHandler(file, opts);
}
/**
* Returns a {@code BodyHandler<Path>} that returns a
- * {@link BodySubscriber BodySubscriber}{@code <Path>} obtained from
- * {@link BodySubscriber#asFile(Path) BodySubscriber.asFile(Path)}.
+ * {@link BodySubscriber BodySubscriber}{@code <Path>}.
+ *
+ * <p> Equivalent to: {@code asFile(file, CREATE, WRITE)}
*
- * <p> When the {@code HttpResponse} object is returned, the body has
- * been completely written to the file, and {@link #body()} returns a
- * reference to its {@link Path}.
+ * <p> Security manager permission checks are performed in this factory
+ * method, when a {@code BodyHandler} is created. Care must be taken
+ * that the {@code BodyHandler} is not shared with untrusted code.
*
* @param file the file to store the body in
* @return a response body handler
- * @throws SecurityException if a security manager has been installed
+ * @throws SecurityException If a security manager has been installed
* and it denies {@link SecurityManager#checkWrite(String)
- * write access} to the file
+ * write access} to the file.
*/
public static BodyHandler<Path> asFile(Path file) {
- return BodyHandler.asFile(file, StandardOpenOption.CREATE,
- StandardOpenOption.WRITE);
+ return BodyHandler.asFile(file, CREATE, WRITE);
}
/**
@@ -511,31 +517,44 @@
* by the server. If the destination directory does not exist or cannot
* be written to, then the response will fail with an {@link IOException}.
*
+ * <p> Security manager permission checks are performed in this factory
+ * method, when a {@code BodyHandler} is created. Care must be taken
+ * that the {@code BodyHandler} is not shared with untrusted code.
+ *
* @param directory the directory to store the file in
- * @param openOptions open options
+ * @param openOptions open options used when opening the file
* @return a response body handler
+ * @throws IllegalArgumentException if the given path does not exist,
+ * is not a directory, is not writable, or if an invalid set
+ * of open options are specified
* @throws SecurityException If a security manager has been installed
- * and it denies {@link SecurityManager#checkWrite(String)
- * write access} to the file. The {@link
- * SecurityManager#checkDelete(String) checkDelete} method is
- * invoked to check delete access if the file is opened with
- * the {@code DELETE_ON_CLOSE} option.
+ * and it denies {@linkplain SecurityManager#checkRead(String)
+ * read access} or {@linkplain SecurityManager#checkWrite(String)
+ * write access} to the directory.
*/
- //####: check if the dir exists and is writable??
public static BodyHandler<Path> asFileDownload(Path directory,
OpenOption... openOptions) {
Objects.requireNonNull(directory);
List<OpenOption> opts = List.of(openOptions);
+ if (opts.contains(DELETE_ON_CLOSE)) {
+ throw new IllegalArgumentException("invalid option: " + DELETE_ON_CLOSE);
+ }
+
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
String fn = pathForSecurityCheck(directory);
sm.checkWrite(fn);
- if (opts.contains(StandardOpenOption.DELETE_ON_CLOSE))
- sm.checkDelete(fn);
- if (opts.contains(StandardOpenOption.READ))
- sm.checkRead(fn);
+ sm.checkRead(fn);
}
- return new FileDownloadBodyHandler(directory, openOptions);
+
+ if (Files.notExists(directory))
+ throw new IllegalArgumentException("non-existent directory: " + directory);
+ if (!Files.isDirectory(directory))
+ throw new IllegalArgumentException("not a directory: " + directory);
+ if (!Files.isWritable(directory))
+ throw new IllegalArgumentException("non-writable directory: " + directory);
+
+ return new FileDownloadBodyHandler(directory, opts);
}
/**
@@ -934,11 +953,6 @@
);
}
- // no security check
- private static BodySubscriber<Path> asFileImpl(Path file, OpenOption... openOptions) {
- return new ResponseSubscribers.PathSubscriber(file, openOptions);
- }
-
/**
* Returns a {@code BodySubscriber} which stores the response body in a
* file opened with the given options and name. The file will be opened
@@ -951,39 +965,44 @@
* <p> The {@link HttpResponse} using this subscriber is available after
* the entire response has been read.
*
+ * <p> Security manager permission checks are performed in this factory
+ * method, when a {@code BodySubscriber} is created. Care must be taken
+ * that the {@code BodyHandler} is not shared with untrusted code.
+ *
* @param file the file to store the body in
* @param openOptions the list of options to open the file with
* @return a body subscriber
- * @throws SecurityException If a security manager has been installed
+ * @throws IllegalArgumentException if an invalid set of open options
+ * are specified
+ * @throws SecurityException if a security manager has been installed
* and it denies {@link SecurityManager#checkWrite(String)
- * write access} to the file. The {@link
- * SecurityManager#checkDelete(String) checkDelete} method is
- * invoked to check delete access if the file is opened with the
- * {@code DELETE_ON_CLOSE} option.
+ * write access} to the file
*/
public static BodySubscriber<Path> asFile(Path file, OpenOption... openOptions) {
Objects.requireNonNull(file);
List<OpenOption> opts = List.of(openOptions);
+ if (opts.contains(DELETE_ON_CLOSE) || opts.contains(READ)) {
+ // these options make no sense, since the FileChannel is not exposed
+ throw new IllegalArgumentException("invalid openOptions: " + opts);
+ }
+
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
String fn = pathForSecurityCheck(file);
sm.checkWrite(fn);
- if (opts.contains(StandardOpenOption.DELETE_ON_CLOSE))
- sm.checkDelete(fn);
- if (opts.contains(StandardOpenOption.READ))
- sm.checkRead(fn);
}
- return asFileImpl(file, openOptions);
+ return new PathSubscriber(file, opts);
}
/**
* Returns a {@code BodySubscriber} which stores the response body in a
- * file opened with the given name. Has the same effect as calling
- * {@link #asFile(Path, OpenOption...) asFile} with the standard open
- * options {@code CREATE} and {@code WRITE}
+ * file opened with the given name.
+ *
+ * <p> Equivalent to: {@code asFile(file, CREATE, WRITE)}
*
- * <p> The {@link HttpResponse} using this subscriber is available after
- * the entire response has been read.
+ * <p> Security manager permission checks are performed in this factory
+ * method, when a {@code BodySubscriber} is created. Care must be taken
+ * that the {@code BodyHandler} is not shared with untrusted code.
*
* @param file the file to store the body in
* @return a body subscriber
@@ -992,7 +1011,7 @@
* write access} to the file
*/
public static BodySubscriber<Path> asFile(Path file) {
- return asFile(file, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
+ return asFile(file, CREATE, WRITE);
}
/**
--- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java Fri Feb 16 10:34:17 2018 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java Fri Feb 16 15:06:29 2018 +0000
@@ -116,10 +116,6 @@
this.expectContinue = request.expectContinue();
this.secure = uri.getScheme().toLowerCase(Locale.US).equals("https");
this.requestPublisher = request.bodyPublisher().orElse(null);
- if (acc != null && requestPublisher instanceof RequestPublishers.FilePublisher) {
- // Restricts the file publisher with the senders ACC, if any
- ((RequestPublishers.FilePublisher)requestPublisher).setAccessControlContext(acc);
- }
this.timeout = request.timeout().orElse(null);
this.version = request.version();
this.authority = null;
--- a/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java Fri Feb 16 10:34:17 2018 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java Fri Feb 16 15:06:29 2018 +0000
@@ -42,7 +42,6 @@
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.PushPromiseHandler;
import java.net.http.HttpTimeoutException;
-import jdk.internal.net.http.UntrustedBodyHandler;
import jdk.internal.net.http.common.Log;
import jdk.internal.net.http.common.MinimalFuture;
import jdk.internal.net.http.common.ConnectionExpiredException;
@@ -119,11 +118,6 @@
this.acc = acc;
this.executor = client.theExecutor();
this.responseHandler = responseHandler;
- if (acc != null) {
- // Restricts the file publisher with the senders ACC, if any
- if (responseHandler instanceof UntrustedBodyHandler)
- ((UntrustedBodyHandler)this.responseHandler).setAccessControlContext(acc);
- }
if (pushPromiseHandler != null) {
this.pushGroup = new PushGroup<>(pushPromiseHandler, request, acc);
--- a/src/java.net.http/share/classes/jdk/internal/net/http/PushGroup.java Fri Feb 16 10:34:17 2018 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/PushGroup.java Fri Feb 16 15:06:29 2018 +0000
@@ -26,7 +26,6 @@
package jdk.internal.net.http;
import java.security.AccessControlContext;
-import java.security.AccessController;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.net.http.HttpRequest;
@@ -70,9 +69,6 @@
this.noMorePushesCF = new MinimalFuture<>();
this.pushPromiseHandler = pushPromiseHandler;
this.initiatingRequest = initiatingRequest;
- // Restricts the file publisher with the senders ACC, if any
- if (pushPromiseHandler instanceof UntrustedBodyHandler)
- ((UntrustedBodyHandler)this.pushPromiseHandler).setAccessControlContext(acc);
this.acc = acc;
}
@@ -109,9 +105,6 @@
synchronized (this) {
if (acceptor.accepted()) {
- if (acceptor.bodyHandler instanceof UntrustedBodyHandler) {
- ((UntrustedBodyHandler) acceptor.bodyHandler).setAccessControlContext(acc);
- }
numberOfPushes++;
remainingPushes++;
}
--- a/src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java Fri Feb 16 10:34:17 2018 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java Fri Feb 16 15:06:29 2018 +0000
@@ -219,27 +219,18 @@
public static class FilePublisher implements BodyPublisher {
private final File file;
- private volatile AccessControlContext acc;
public FilePublisher(Path name) {
file = name.toFile();
}
- void setAccessControlContext(AccessControlContext acc) {
- this.acc = acc;
- }
-
@Override
public void subscribe(Flow.Subscriber<? super ByteBuffer> subscriber) {
- if (System.getSecurityManager() != null && acc == null)
- throw new InternalError(
- "Unexpected null acc when security manager has been installed");
-
InputStream is;
try {
PrivilegedExceptionAction<FileInputStream> pa =
() -> new FileInputStream(file);
- is = AccessController.doPrivileged(pa, acc);
+ is = AccessController.doPrivileged(pa);
} catch (PrivilegedActionException pae) {
throw new UncheckedIOException((IOException)pae.getCause());
}
@@ -250,9 +241,8 @@
@Override
public long contentLength() {
- assert System.getSecurityManager() != null ? acc != null: true;
PrivilegedAction<Long> pa = () -> file.length();
- return AccessController.doPrivileged(pa, acc);
+ return AccessController.doPrivileged(pa);
}
}
--- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java Fri Feb 16 10:34:17 2018 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java Fri Feb 16 15:06:29 2018 +0000
@@ -31,7 +31,7 @@
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.security.AccessControlContext;
+import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentMap;
@@ -52,30 +52,19 @@
/**
* A Path body handler.
- *
- * Note: Exists mainly too allow setting of the senders ACC post creation of
- * the handler.
*/
- public static class PathBodyHandler implements UntrustedBodyHandler<Path> {
+ public static class PathBodyHandler implements BodyHandler<Path>{
private final Path file;
- private final OpenOption[]openOptions;
- private volatile AccessControlContext acc;
+ private final List<OpenOption> openOptions;
- public PathBodyHandler(Path file, OpenOption... openOptions) {
+ public PathBodyHandler(Path file, List<OpenOption> openOptions) {
this.file = file;
this.openOptions = openOptions;
}
@Override
- public void setAccessControlContext(AccessControlContext acc) {
- this.acc = acc;
- }
-
- @Override
public BodySubscriber<Path> apply(int statusCode, HttpHeaders headers) {
- PathSubscriber bs = (PathSubscriber) asFileImpl(file, openOptions);
- bs.setAccessControlContext(acc);
- return bs;
+ return new PathSubscriber(file, openOptions);
}
}
@@ -125,22 +114,16 @@
}
}
- // Similar to Path body handler, but for file download. Supports setting ACC.
- public static class FileDownloadBodyHandler implements UntrustedBodyHandler<Path> {
+ // Similar to Path body handler, but for file download.
+ public static class FileDownloadBodyHandler implements BodyHandler<Path> {
private final Path directory;
- private final OpenOption[] openOptions;
- private volatile AccessControlContext acc;
+ private final List<OpenOption> openOptions;
- public FileDownloadBodyHandler(Path directory, OpenOption... openOptions) {
+ public FileDownloadBodyHandler(Path directory, List<OpenOption> openOptions) {
this.directory = directory;
this.openOptions = openOptions;
}
- @Override
- public void setAccessControlContext(AccessControlContext acc) {
- this.acc = acc;
- }
-
/** The "attachment" disposition-type and separator. */
static final String DISPOSITION_TYPE = "attachment;";
@@ -221,14 +204,7 @@
"Resulting file, " + file.toString() + ", outside of given directory");
}
- PathSubscriber bs = (PathSubscriber)asFileImpl(file, openOptions);
- bs.setAccessControlContext(acc);
- return bs;
+ return new PathSubscriber(file, openOptions);
}
}
-
- // no security check
- private static BodySubscriber<Path> asFileImpl(Path file, OpenOption... openOptions) {
- return new ResponseSubscribers.PathSubscriber(file, openOptions);
- }
}
--- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java Fri Feb 16 10:34:17 2018 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java Fri Feb 16 15:06:29 2018 +0000
@@ -35,7 +35,6 @@
import java.nio.charset.Charset;
import java.nio.file.OpenOption;
import java.nio.file.Path;
-import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
@@ -114,32 +113,23 @@
private final Path file;
private final CompletableFuture<Path> result = new MinimalFuture<>();
+ private final OpenOption[] options;
private volatile Flow.Subscription subscription;
private volatile FileChannel out;
- private volatile AccessControlContext acc;
- private final OpenOption[] options;
- public PathSubscriber(Path file, OpenOption... options) {
+ public PathSubscriber(Path file, List<OpenOption> options) {
this.file = file;
- this.options = options;
- }
-
- public void setAccessControlContext(AccessControlContext acc) {
- this.acc = acc;
+ this.options = options.stream().toArray(OpenOption[]::new);
}
@Override
public void onSubscribe(Flow.Subscription subscription) {
- if (System.getSecurityManager() != null && acc == null)
- throw new InternalError(
- "Unexpected null acc when security manager has been installed");
-
this.subscription = subscription;
try {
PrivilegedExceptionAction<FileChannel> pa =
() -> FileChannel.open(file, options);
- out = AccessController.doPrivileged(pa, acc);
+ out = AccessController.doPrivileged(pa);
} catch (PrivilegedActionException pae) {
Throwable t = pae.getCause() != null ? pae.getCause() : pae;
result.completeExceptionally(t);
--- a/src/java.net.http/share/classes/jdk/internal/net/http/UntrustedBodyHandler.java Fri Feb 16 10:34:17 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.internal.net.http;
-
-import java.security.AccessControlContext;
-import java.net.http.HttpResponse;
-
-/** A body handler that is further restricted by a given ACC. */
-public interface UntrustedBodyHandler<T> extends HttpResponse.BodyHandler<T> {
- void setAccessControlContext(AccessControlContext acc);
-}
--- a/test/jdk/java/net/httpclient/SubscriberPublisherAPIExceptions.java Fri Feb 16 10:34:17 2018 +0000
+++ b/test/jdk/java/net/httpclient/SubscriberPublisherAPIExceptions.java Fri Feb 16 15:06:29 2018 +0000
@@ -39,7 +39,9 @@
import org.testng.annotations.Test;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.StandardOpenOption.CREATE;
+import static java.nio.file.StandardOpenOption.DELETE_ON_CLOSE;
import static java.nio.file.StandardOpenOption.WRITE;
+import static java.nio.file.StandardOpenOption.READ;
import static org.testng.Assert.assertThrows;
/*
@@ -92,8 +94,13 @@
}
@Test
- public void handlerAPIExceptions() {
+ public void handlerAPIExceptions() throws Exception {
Path path = Paths.get(".").resolve("tt");
+ Path file = Files.createFile(Paths.get(".").resolve("aFile"));
+ Path doesNotExist = Paths.get(".").resolve("doneNotExist");
+ if (Files.exists(doesNotExist))
+ throw new AssertionError("Unexpected " + doesNotExist);
+
assertThrows(NPE, () -> BodyHandler.asByteArrayConsumer(null));
assertThrows(NPE, () -> BodyHandler.asFile(null));
assertThrows(NPE, () -> BodyHandler.asFile(null, CREATE, WRITE));
@@ -108,11 +115,19 @@
assertThrows(NPE, () -> BodyHandler.asFileDownload(path, new OpenOption[] {CREATE, null}));
assertThrows(NPE, () -> BodyHandler.asFileDownload(path, new OpenOption[] {null, CREATE}));
assertThrows(NPE, () -> BodyHandler.asFileDownload(null, (OpenOption[])null));
+ assertThrows(IAE, () -> BodyHandler.asFileDownload(file, CREATE, WRITE));
+ assertThrows(IAE, () -> BodyHandler.asFileDownload(doesNotExist, CREATE, WRITE));
assertThrows(NPE, () -> BodyHandler.asString(null));
assertThrows(NPE, () -> BodyHandler.buffering(null, 1));
assertThrows(IAE, () -> BodyHandler.buffering(new NoOpHandler(), 0));
assertThrows(IAE, () -> BodyHandler.buffering(new NoOpHandler(), -1));
assertThrows(IAE, () -> BodyHandler.buffering(new NoOpHandler(), Integer.MIN_VALUE));
+
+ // implementation specific exceptions
+ assertThrows(IAE, () -> BodyHandler.asFile(path, READ));
+ assertThrows(IAE, () -> BodyHandler.asFile(path, DELETE_ON_CLOSE));
+ assertThrows(IAE, () -> BodyHandler.asFile(path, READ, DELETE_ON_CLOSE));
+ assertThrows(IAE, () -> BodyHandler.asFileDownload(path, DELETE_ON_CLOSE));
}
@Test
@@ -134,6 +149,11 @@
assertThrows(NPE, () -> BodySubscriber.mapping(null, Function.identity()));
assertThrows(NPE, () -> BodySubscriber.mapping(BodySubscriber.asByteArray(), null));
assertThrows(NPE, () -> BodySubscriber.mapping(null, null));
+
+ // implementation specific exceptions
+ assertThrows(IAE, () -> BodySubscriber.asFile(path, READ));
+ assertThrows(IAE, () -> BodySubscriber.asFile(path, DELETE_ON_CLOSE));
+ assertThrows(IAE, () -> BodySubscriber.asFile(path, READ, DELETE_ON_CLOSE));
}
static class NoOpHandler implements BodyHandler<Void> {
--- a/test/jdk/java/net/httpclient/security/filePerms/FileProcessorPermissionTest.java Fri Feb 16 10:34:17 2018 +0000
+++ b/test/jdk/java/net/httpclient/security/filePerms/FileProcessorPermissionTest.java Fri Feb 16 15:06:29 2018 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -73,18 +73,10 @@
() -> HttpResponse.BodyHandler.asFile(asFilePath),
() -> HttpResponse.BodyHandler.asFile(asFilePath, CREATE),
() -> HttpResponse.BodyHandler.asFile(asFilePath, CREATE, WRITE),
- () -> HttpResponse.BodyHandler.asFile(asFilePath, CREATE, WRITE, READ),
- () -> HttpResponse.BodyHandler.asFile(asFilePath, CREATE, WRITE, READ, DELETE_ON_CLOSE),
() -> HttpResponse.BodyHandler.asFileDownload(CWD),
() -> HttpResponse.BodyHandler.asFileDownload(CWD, CREATE),
- () -> HttpResponse.BodyHandler.asFileDownload(CWD, CREATE, WRITE),
- () -> HttpResponse.BodyHandler.asFileDownload(CWD, CREATE, WRITE, READ),
- () -> HttpResponse.BodyHandler.asFileDownload(CWD, CREATE, WRITE, READ, DELETE_ON_CLOSE),
-
- // TODO: what do these even mean by themselves, maybe ok means nothing?
- () -> HttpResponse.BodyHandler.asFile(asFilePath, DELETE_ON_CLOSE),
- () -> HttpResponse.BodyHandler.asFile(asFilePath, READ)
+ () -> HttpResponse.BodyHandler.asFileDownload(CWD, CREATE, WRITE)
);
// sanity, just run http ( no security manager )