src/java.net.http/share/classes/java/net/http/HttpResponse.java
branchhttp-client-branch
changeset 56257 82a9340bdda6
parent 56203 be57b0428d84
child 56260 df3f97c19c1d
equal deleted inserted replaced
56256:0fe17c3f9b4f 56257:82a9340bdda6
    31 import java.net.URI;
    31 import java.net.URI;
    32 import java.nio.ByteBuffer;
    32 import java.nio.ByteBuffer;
    33 import java.nio.charset.Charset;
    33 import java.nio.charset.Charset;
    34 import java.nio.channels.FileChannel;
    34 import java.nio.channels.FileChannel;
    35 import java.nio.charset.StandardCharsets;
    35 import java.nio.charset.StandardCharsets;
    36 import java.nio.file.Files;
       
    37 import java.nio.file.OpenOption;
    36 import java.nio.file.OpenOption;
    38 import java.nio.file.Path;
    37 import java.nio.file.Path;
    39 import java.util.List;
    38 import java.util.List;
    40 import java.util.Objects;
    39 import java.util.Objects;
    41 import java.util.Optional;
    40 import java.util.Optional;
   161      * @return HTTP protocol version
   160      * @return HTTP protocol version
   162      */
   161      */
   163     public HttpClient.Version version();
   162     public HttpClient.Version version();
   164 
   163 
   165 
   164 
   166     private static String pathForSecurityCheck(Path path) {
       
   167         return path.toFile().getPath();
       
   168     }
       
   169 
       
   170 
       
   171     /**
   165     /**
   172      * A handler for response bodies.  The class {@link BodyHandlers BodyHandlers}
   166      * A handler for response bodies.  The class {@link BodyHandlers BodyHandlers}
   173      * provides implementations of many common body handlers.
   167      * provides implementations of many common body handlers.
   174      *
   168      *
   175      * <p> The {@code BodyHandler} interface allows inspection of the response
   169      * <p> The {@code BodyHandler} interface allows inspection of the response
   502             List<OpenOption> opts = List.of(openOptions);
   496             List<OpenOption> opts = List.of(openOptions);
   503             if (opts.contains(DELETE_ON_CLOSE) || opts.contains(READ)) {
   497             if (opts.contains(DELETE_ON_CLOSE) || opts.contains(READ)) {
   504                 // these options make no sense, since the FileChannel is not exposed
   498                 // these options make no sense, since the FileChannel is not exposed
   505                 throw new IllegalArgumentException("invalid openOptions: " + opts);
   499                 throw new IllegalArgumentException("invalid openOptions: " + opts);
   506             }
   500             }
   507 
   501             return PathBodyHandler.create(file, opts);
   508             SecurityManager sm = System.getSecurityManager();
       
   509             if (sm != null) {
       
   510                 String fn = pathForSecurityCheck(file);
       
   511                 sm.checkWrite(fn);
       
   512             }
       
   513             return new PathBodyHandler(file, opts);
       
   514         }
   502         }
   515 
   503 
   516         /**
   504         /**
   517          * Returns a {@code BodyHandler<Path>} that returns a
   505          * Returns a {@code BodyHandler<Path>} that returns a
   518          * {@link BodySubscriber BodySubscriber}{@code <Path>}.
   506          * {@link BodySubscriber BodySubscriber}{@code <Path>}.
   559          * @return a response body handler
   547          * @return a response body handler
   560          * @throws IllegalArgumentException if the given path does not exist,
   548          * @throws IllegalArgumentException if the given path does not exist,
   561          *          is not a directory, is not writable, or if an invalid set
   549          *          is not a directory, is not writable, or if an invalid set
   562          *          of open options are specified
   550          *          of open options are specified
   563          * @throws SecurityException If a security manager has been installed
   551          * @throws SecurityException If a security manager has been installed
   564          *          and it denies {@linkplain SecurityManager#checkRead(String)
   552          *          and it denies
   565          *          read access} or {@linkplain SecurityManager#checkWrite(String)
   553          *          {@linkplain SecurityManager#checkRead(String) read access}
   566          *          write access} to the directory.
   554          *          to the directory, or it denies
       
   555          *          {@linkplain SecurityManager#checkWrite(String) write access}
       
   556          *          to the directory, or it denies
       
   557          *          {@linkplain SecurityManager#checkWrite(String) write access}
       
   558          *          to the files within the directory.
   567          */
   559          */
   568         public static BodyHandler<Path> ofFileDownload(Path directory,
   560         public static BodyHandler<Path> ofFileDownload(Path directory,
   569                                                        OpenOption... openOptions) {
   561                                                        OpenOption... openOptions) {
   570             Objects.requireNonNull(directory);
   562             Objects.requireNonNull(directory);
   571             List<OpenOption> opts = List.of(openOptions);
   563             List<OpenOption> opts = List.of(openOptions);
   572             if (opts.contains(DELETE_ON_CLOSE)) {
   564             if (opts.contains(DELETE_ON_CLOSE)) {
   573                 throw new IllegalArgumentException("invalid option: " + DELETE_ON_CLOSE);
   565                 throw new IllegalArgumentException("invalid option: " + DELETE_ON_CLOSE);
   574             }
   566             }
   575 
   567             return FileDownloadBodyHandler.create(directory, opts);
   576             SecurityManager sm = System.getSecurityManager();
       
   577             if (sm != null) {
       
   578                 String fn = pathForSecurityCheck(directory);
       
   579                 sm.checkWrite(fn);
       
   580                 sm.checkRead(fn);
       
   581             }
       
   582 
       
   583             if (Files.notExists(directory))
       
   584                 throw new IllegalArgumentException("non-existent directory: " + directory);
       
   585             if (!Files.isDirectory(directory))
       
   586                 throw new IllegalArgumentException("not a directory: " + directory);
       
   587             if (!Files.isWritable(directory))
       
   588                 throw new IllegalArgumentException("non-writable directory: " + directory);
       
   589 
       
   590             return new FileDownloadBodyHandler(directory, opts);
       
   591         }
   568         }
   592 
   569 
   593         /**
   570         /**
   594          * Returns a {@code BodyHandler<InputStream>} that returns a
   571          * Returns a {@code BodyHandler<InputStream>} that returns a
   595          * {@link BodySubscriber BodySubscriber}{@code <InputStream>} obtained from
   572          * {@link BodySubscriber BodySubscriber}{@code <InputStream>} obtained from
  1056             List<OpenOption> opts = List.of(openOptions);
  1033             List<OpenOption> opts = List.of(openOptions);
  1057             if (opts.contains(DELETE_ON_CLOSE) || opts.contains(READ)) {
  1034             if (opts.contains(DELETE_ON_CLOSE) || opts.contains(READ)) {
  1058                 // these options make no sense, since the FileChannel is not exposed
  1035                 // these options make no sense, since the FileChannel is not exposed
  1059                 throw new IllegalArgumentException("invalid openOptions: " + opts);
  1036                 throw new IllegalArgumentException("invalid openOptions: " + opts);
  1060             }
  1037             }
  1061 
  1038             return PathSubscriber.create(file, opts);
  1062             SecurityManager sm = System.getSecurityManager();
       
  1063             if (sm != null) {
       
  1064                 String fn = pathForSecurityCheck(file);
       
  1065                 sm.checkWrite(fn);
       
  1066             }
       
  1067             return new PathSubscriber(file, opts);
       
  1068         }
  1039         }
  1069 
  1040 
  1070         /**
  1041         /**
  1071          * Returns a {@code BodySubscriber} which stores the response body in a
  1042          * Returns a {@code BodySubscriber} which stores the response body in a
  1072          * file opened with the given name.
  1043          * file opened with the given name.