1 /*
2 * Copyright (c) 2015, 2016, 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
27
28 import java.io.IOException;
29 import java.io.UncheckedIOException;
30 import java.net.URI;
31 import jdk.incubator.http.internal.common.Utils;
32
33 class RedirectFilter implements HeaderFilter {
34
35 HttpRequestImpl request;
36 HttpClientImpl client;
37 HttpClient.Redirect policy;
38 String method;
39 MultiExchange<?,?> exchange;
40 static final int DEFAULT_MAX_REDIRECTS = 5;
41 URI uri;
42
43 static final int max_redirects = Utils.getIntegerNetProperty(
44 "jdk.httpclient.redirects.retrylimit", DEFAULT_MAX_REDIRECTS
45 );
46
47 @Override
48 public synchronized void request(HttpRequestImpl r, MultiExchange<?,?> e) throws IOException {
49 this.request = r;
50 this.client = e.client();
51 this.policy = client.followRedirects();
52
53 this.method = r.method();
54 this.uri = r.uri();
55 this.exchange = e;
56 }
57
58 @Override
59 public synchronized HttpRequestImpl response(Response r) throws IOException {
60 return handleResponse(r);
61 }
62
63 /**
64 * checks to see if new request needed and returns it.
65 * Null means response is ok to return to user.
66 */
67 private HttpRequestImpl handleResponse(Response r) {
68 int rcode = r.statusCode();
69 if (rcode == 200 || policy == HttpClient.Redirect.NEVER) {
70 return null;
71 }
72 if (rcode >= 300 && rcode <= 399) {
73 URI redir = getRedirectedURI(r.headers());
74 if (canRedirect(redir) && ++exchange.numberOfRedirects < max_redirects) {
75 //System.out.println("Redirecting to: " + redir);
76 return new HttpRequestImpl(redir, method, request);
77 } else {
78 //System.out.println("Redirect: giving up");
79 return null;
80 }
81 }
82 return null;
83 }
84
85 private URI getRedirectedURI(HttpHeaders headers) {
86 URI redirectedURI;
87 String ss = headers.firstValue("Location").orElse("Not present");
88 redirectedURI = headers.firstValue("Location")
89 .map((s) -> URI.create(s))
90 .orElseThrow(() -> new UncheckedIOException(
91 new IOException("Invalid redirection")));
92
93 // redirect could be relative to original URL, but if not
94 // then redirect is used.
95 redirectedURI = uri.resolve(redirectedURI);
96 return redirectedURI;
97 }
98
99 private boolean canRedirect(URI redir) {
100 String newScheme = redir.getScheme();
101 String oldScheme = uri.getScheme();
102 switch (policy) {
103 case ALWAYS:
104 return true;
105 case NEVER:
106 return false;
107 case SECURE:
108 return newScheme.equalsIgnoreCase("https");
109 case SAME_PROTOCOL:
|
1 /*
2 * Copyright (c) 2015, 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. 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
27
28 import java.io.IOException;
29 import java.io.UncheckedIOException;
30 import java.net.URI;
31 import jdk.incubator.http.internal.common.Utils;
32
33 class RedirectFilter implements HeaderFilter {
34
35 HttpRequestImpl request;
36 HttpClientImpl client;
37 HttpClient.Redirect policy;
38 String method;
39 MultiExchange<?,?> exchange;
40 static final int DEFAULT_MAX_REDIRECTS = 5;
41 URI uri;
42
43 static final int max_redirects = Utils.getIntegerNetProperty(
44 "jdk.httpclient.redirects.retrylimit", DEFAULT_MAX_REDIRECTS
45 );
46
47 // A public no-arg constructor is required by FilterFactory
48 public RedirectFilter() {}
49
50 @Override
51 public synchronized void request(HttpRequestImpl r, MultiExchange<?,?> e) throws IOException {
52 this.request = r;
53 this.client = e.client();
54 this.policy = client.followRedirects();
55
56 this.method = r.method();
57 this.uri = r.uri();
58 this.exchange = e;
59 }
60
61 @Override
62 public synchronized HttpRequestImpl response(Response r) throws IOException {
63 return handleResponse(r);
64 }
65
66 /**
67 * checks to see if new request needed and returns it.
68 * Null means response is ok to return to user.
69 */
70 private HttpRequestImpl handleResponse(Response r) {
71 int rcode = r.statusCode();
72 if (rcode == 200 || policy == HttpClient.Redirect.NEVER) {
73 return null;
74 }
75 if (rcode >= 300 && rcode <= 399) {
76 URI redir = getRedirectedURI(r.headers());
77 if (canRedirect(redir) && ++exchange.numberOfRedirects < max_redirects) {
78 //System.out.println("Redirecting to: " + redir);
79 return new HttpRequestImpl(redir, method, request);
80 } else {
81 //System.out.println("Redirect: giving up");
82 return null;
83 }
84 }
85 return null;
86 }
87
88 private URI getRedirectedURI(HttpHeaders headers) {
89 URI redirectedURI;
90 redirectedURI = headers.firstValue("Location")
91 .map(URI::create)
92 .orElseThrow(() -> new UncheckedIOException(
93 new IOException("Invalid redirection")));
94
95 // redirect could be relative to original URL, but if not
96 // then redirect is used.
97 redirectedURI = uri.resolve(redirectedURI);
98 return redirectedURI;
99 }
100
101 private boolean canRedirect(URI redir) {
102 String newScheme = redir.getScheme();
103 String oldScheme = uri.getScheme();
104 switch (policy) {
105 case ALWAYS:
106 return true;
107 case NEVER:
108 return false;
109 case SECURE:
110 return newScheme.equalsIgnoreCase("https");
111 case SAME_PROTOCOL:
|