1 /*
   2  * Copyright (c) 2016, 2017, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.net.URI;
  25 import jdk.incubator.http.HttpClient;
  26 import java.time.Duration;
  27 import java.util.Arrays;
  28 import java.util.function.BiFunction;
  29 import java.util.function.Function;
  30 import java.util.function.Supplier;
  31 import java.util.stream.Collectors;
  32 import java.util.stream.Stream;
  33 import jdk.incubator.http.HttpRequest;
  34 import static jdk.incubator.http.HttpRequest.BodyPublisher.fromString;
  35 import static jdk.incubator.http.HttpRequest.BodyPublisher.noBody;
  36 
  37 /**
  38  * @test
  39  * @bug 8170064
  40  * @summary  HttpRequest[.Builder] API and behaviour checks
  41  */
  42 public class HttpRequestBuilderTest {
  43 
  44     static final URI TEST_URI = URI.create("http://www.foo.com/");
  45 
  46 
  47     public static void main(String[] args) throws Exception {
  48 
  49         test0("newBuilder().build()",
  50               () -> HttpRequest.newBuilder().build(),
  51               IllegalStateException.class);
  52 
  53         test0("newBuilder(null)",
  54               () -> HttpRequest.newBuilder(null),
  55               NullPointerException.class);
  56 
  57         test0("newBuilder(URI.create(\"badScheme://www.foo.com/\")",
  58               () -> HttpRequest.newBuilder(URI.create("badScheme://www.foo.com/")),
  59               IllegalArgumentException.class);
  60 
  61         test0("newBuilder(URI.create(\"http://www.foo.com:-1/\")",
  62                 () -> HttpRequest.newBuilder(URI.create("http://www.foo.com:-1/")),
  63                 IllegalArgumentException.class);
  64 
  65         test0("newBuilder(URI.create(\"https://www.foo.com:-1/\")",
  66                 () -> HttpRequest.newBuilder(URI.create("https://www.foo.com:-1/")),
  67                 IllegalArgumentException.class);
  68 
  69         test0("newBuilder(" + TEST_URI + ").uri(null)",
  70               () -> HttpRequest.newBuilder(TEST_URI).uri(null),
  71               NullPointerException.class);
  72 
  73         test0("newBuilder(uri).build()",
  74               () -> HttpRequest.newBuilder(TEST_URI).build()
  75               /* no expected exceptions */ );
  76 
  77         HttpRequest.Builder builder = HttpRequest.newBuilder();
  78 
  79         builder = test1("uri", builder, builder::uri, (URI)null,
  80                         NullPointerException.class);
  81 
  82         builder = test1("uri", builder, builder::uri, URI.create("http://www.foo.com:-1/"),
  83                         IllegalArgumentException.class);
  84 
  85         builder = test1("uri", builder, builder::uri, URI.create("https://www.foo.com:-1/"),
  86                         IllegalArgumentException.class);
  87 
  88         builder = test2("header", builder, builder::header, (String) null, "bar",
  89                         NullPointerException.class);
  90 
  91         builder = test2("header", builder, builder::header, "foo", (String) null,
  92                         NullPointerException.class);
  93 
  94         builder = test2("header", builder, builder::header, (String)null,
  95                         (String) null, NullPointerException.class);
  96 
  97         builder = test2("header", builder, builder::header, "", "bar",
  98                         IllegalArgumentException.class);
  99 
 100         builder = test2("header", builder, builder::header, "foo", "\r",
 101                         IllegalArgumentException.class);
 102 
 103         builder = test1("headers", builder, builder::headers, (String[]) null,
 104                         NullPointerException.class);
 105 
 106         builder = test1("headers", builder, builder::headers, new String[0],
 107                         IllegalArgumentException.class);
 108 
 109         builder = test1("headers", builder, builder::headers,
 110                         (String[]) new String[] {null, "bar"},
 111                         NullPointerException.class);
 112 
 113         builder = test1("headers", builder, builder::headers,
 114                         (String[]) new String[] {"foo", null},
 115                         NullPointerException.class);
 116 
 117         builder = test1("headers", builder, builder::headers,
 118                         (String[]) new String[] {null, null},
 119                         NullPointerException.class);
 120 
 121         builder = test1("headers", builder, builder::headers,
 122                         (String[]) new String[] {"foo", "bar", null},
 123                         NullPointerException.class,
 124                         IllegalArgumentException.class);
 125 
 126         builder = test1("headers", builder, builder::headers,
 127                         (String[]) new String[] {"foo", "bar", null, null},
 128                         NullPointerException.class);
 129 
 130         builder = test1("headers", builder, builder::headers,
 131                         (String[]) new String[] {"foo", "bar", "baz", null},
 132                         NullPointerException.class);
 133 
 134         builder = test1("headers", builder, builder::headers,
 135                         (String[]) new String[] {"foo", "bar", "\r", "baz"},
 136                         IllegalArgumentException.class);
 137 
 138         builder = test1("headers", builder, builder::headers,
 139                         (String[]) new String[] {"foo", "bar", "baz", "\n"},
 140                         IllegalArgumentException.class);
 141 
 142         builder = test1("headers", builder, builder::headers,
 143                         (String[]) new String[] {"foo", "bar", "", "baz"},
 144                         IllegalArgumentException.class);
 145 
 146         builder = test1("headers", builder, builder::headers,
 147                         (String[]) new String[] {"foo", "bar", null, "baz"},
 148                         NullPointerException.class);
 149 
 150         builder = test1("headers", builder, builder::headers,
 151                         (String[]) new String[] {"foo", "bar", "baz"},
 152                         IllegalArgumentException.class);
 153 
 154         builder = test1("headers", builder, builder::headers,
 155                         (String[]) new String[] {"foo"},
 156                         IllegalArgumentException.class);
 157 
 158         builder = test1("DELETE", builder, builder::DELETE,
 159                         noBody(), null);
 160 
 161         builder = test1("POST", builder, builder::POST,
 162                         noBody(), null);
 163 
 164         builder = test1("PUT", builder, builder::PUT,
 165                         noBody(), null);
 166 
 167         builder = test2("method", builder, builder::method, "GET",
 168                         noBody(), null);
 169 
 170         builder = test1("DELETE", builder, builder::DELETE,
 171                         (HttpRequest.BodyPublisher)null,
 172                         NullPointerException.class);
 173 
 174         builder = test1("POST", builder, builder::POST,
 175                         (HttpRequest.BodyPublisher)null,
 176                         NullPointerException.class);
 177 
 178         builder = test1("PUT", builder, builder::PUT,
 179                         (HttpRequest.BodyPublisher)null,
 180                         NullPointerException.class);
 181 
 182         builder = test2("method", builder, builder::method, "GET",
 183                         (HttpRequest.BodyPublisher) null,
 184                         NullPointerException.class);
 185 
 186         builder = test2("setHeader", builder, builder::setHeader,
 187                         (String) null, "bar",
 188                         NullPointerException.class);
 189 
 190         builder = test2("setHeader", builder, builder::setHeader,
 191                         "foo", (String) null,
 192                         NullPointerException.class);
 193 
 194         builder = test2("setHeader", builder, builder::setHeader,
 195                         (String)null, (String) null,
 196                         NullPointerException.class);
 197 
 198         builder = test1("timeout", builder, builder::timeout,
 199                         (Duration)null,
 200                         NullPointerException.class);
 201 
 202         builder = test1("version", builder, builder::version,
 203                         (HttpClient.Version)null,
 204                         NullPointerException.class);
 205 
 206         builder = test2("method", builder, builder::method, null,
 207                         fromString("foo"),
 208                         NullPointerException.class);
 209 // see JDK-8170093
 210 //
 211 //        builder = test2("method", builder, builder::method, "foo",
 212 //                       HttpRequest.BodyProcessor.fromString("foo"),
 213 //                       IllegalArgumentException.class);
 214 //
 215 //        builder.build();
 216 
 217 
 218         method("newBuilder(TEST_URI).build().method() == GET",
 219                () -> HttpRequest.newBuilder(TEST_URI),
 220                "GET");
 221 
 222         method("newBuilder(TEST_URI).GET().build().method() == GET",
 223                () -> HttpRequest.newBuilder(TEST_URI).GET(),
 224                "GET");
 225 
 226         method("newBuilder(TEST_URI).POST(fromString(\"\")).GET().build().method() == GET",
 227                () -> HttpRequest.newBuilder(TEST_URI).POST(fromString("")).GET(),
 228                "GET");
 229 
 230         method("newBuilder(TEST_URI).PUT(fromString(\"\")).GET().build().method() == GET",
 231                () -> HttpRequest.newBuilder(TEST_URI).PUT(fromString("")).GET(),
 232                "GET");
 233 
 234         method("newBuilder(TEST_URI).DELETE(fromString(\"\")).GET().build().method() == GET",
 235                () -> HttpRequest.newBuilder(TEST_URI).DELETE(fromString("")).GET(),
 236                "GET");
 237 
 238         method("newBuilder(TEST_URI).POST(fromString(\"\")).build().method() == POST",
 239                () -> HttpRequest.newBuilder(TEST_URI).POST(fromString("")),
 240                "POST");
 241 
 242         method("newBuilder(TEST_URI).PUT(fromString(\"\")).build().method() == PUT",
 243                () -> HttpRequest.newBuilder(TEST_URI).PUT(fromString("")),
 244                "PUT");
 245 
 246         method("newBuilder(TEST_URI).DELETE(fromString(\"\")).build().method() == DELETE",
 247                () -> HttpRequest.newBuilder(TEST_URI).DELETE(fromString("")),
 248                "DELETE");
 249 
 250         method("newBuilder(TEST_URI).GET().POST(fromString(\"\")).build().method() == POST",
 251                () -> HttpRequest.newBuilder(TEST_URI).GET().POST(fromString("")),
 252                "POST");
 253 
 254         method("newBuilder(TEST_URI).GET().PUT(fromString(\"\")).build().method() == PUT",
 255                () -> HttpRequest.newBuilder(TEST_URI).GET().PUT(fromString("")),
 256                "PUT");
 257 
 258         method("newBuilder(TEST_URI).GET().DELETE(fromString(\"\")).build().method() == DELETE",
 259                () -> HttpRequest.newBuilder(TEST_URI).GET().DELETE(fromString("")),
 260                "DELETE");
 261 
 262 
 263 
 264     }
 265 
 266     private static boolean shouldFail(Class<? extends Exception> ...exceptions) {
 267         return exceptions != null && exceptions.length > 0;
 268     }
 269 
 270     private static String expectedNames(Class<? extends Exception> ...exceptions) {
 271         return Stream.of(exceptions).map(Class::getSimpleName)
 272                 .collect(Collectors.joining("|"));
 273     }
 274     private static boolean isExpected(Exception x,
 275                                      Class<? extends Exception> ...expected) {
 276         return expected != null && Stream.of(expected)
 277                 .filter(c -> c.isInstance(x))
 278                 .findAny().isPresent();
 279     }
 280 
 281     static void method(String name,
 282                        Supplier<HttpRequest.Builder> supplier,
 283                        String expectedMethod) {
 284         HttpRequest request = supplier.get().build();
 285         String method = request.method();
 286         if (request.method().equals("GET") && request.bodyPublisher().isPresent())
 287             throw new AssertionError("failed: " + name
 288                     + ". Unexpected body processor for GET: "
 289                     + request.bodyPublisher().get());
 290 
 291         if (expectedMethod.equals(method)) {
 292             System.out.println("success: " + name);
 293         } else {
 294             throw new AssertionError("failed: " + name
 295                     + ". Expected " + expectedMethod + ", got " + method);
 296         }
 297     }
 298 
 299     static void test0(String name,
 300                       Runnable r,
 301                       Class<? extends Exception> ...ex) {
 302         try {
 303             r.run();
 304             if (!shouldFail(ex)) {
 305                 System.out.println("success: " + name);
 306                 return;
 307             } else {
 308                 throw new AssertionError("Expected " + expectedNames(ex)
 309                         + " not raised for " + name);
 310             }
 311         } catch (Exception x) {
 312             if (!isExpected(x, ex)) {
 313                 throw x;
 314             } else {
 315                 System.out.println("success: " + name +
 316                         " - Got expected exception: " + x);
 317             }
 318         }
 319     }
 320 
 321     public static <R,P> R test1(String name, R receiver, Function<P, R> m, P arg,
 322                                Class<? extends Exception> ...ex) {
 323         String argMessage = arg == null ? "null" : arg.toString();
 324         if (arg instanceof String[]) {
 325             argMessage = Arrays.asList((String[])arg).toString();
 326         }
 327         try {
 328             R result =  m.apply(arg);
 329             if (!shouldFail(ex)) {
 330                 System.out.println("success: " + name + "(" + argMessage + ")");
 331                 return result;
 332             } else {
 333                 throw new AssertionError("Expected " + expectedNames(ex)
 334                     + " not raised for " + name + "(" + argMessage + ")");
 335             }
 336         } catch (Exception x) {
 337             if (!isExpected(x, ex)) {
 338                 throw x;
 339             } else {
 340                 System.out.println("success: " + name + "(" + argMessage + ")" +
 341                         " - Got expected exception: " + x);
 342                 return receiver;
 343             }
 344         }
 345     }
 346 
 347 
 348     public static <R,P1, P2> R test2(String name, R receiver, BiFunction<P1, P2, R> m,
 349                                P1 arg1, P2 arg2,
 350                                Class<? extends Exception> ...ex) {
 351         try {
 352             R result =  m.apply(arg1, arg2);
 353             if (!shouldFail(ex)) {
 354                 System.out.println("success: " + name + "(" + arg1 + ", "
 355                                    + arg2 + ")");
 356                 return result;
 357             } else {
 358                 throw new AssertionError("Expected " + expectedNames(ex)
 359                     + " not raised for "
 360                     + name + "(" + arg1 +", " + arg2 + ")");
 361             }
 362         } catch (Exception x) {
 363             if (!isExpected(x, ex)) {
 364                 throw x;
 365             } else {
 366                 System.out.println("success: " + name + "(" + arg1 + ", "
 367                         + arg2 + ") - Got expected exception: " + x);
 368                 return receiver;
 369             }
 370         }
 371     }
 372 }