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 23 */ 24 25 package java.net.http; 26 27 import java.io.IOException; 28 import java.io.UncheckedIOException; 29 import java.net.URI; 30 31 class RedirectFilter implements HeaderFilter { 32 33 HttpRequestImpl requestImpl; 34 HttpRequest request; 35 HttpClientImpl client; 36 HttpClient.Redirect policy; 37 String method; 38 final static int DEFAULT_MAX_REDIRECTS = 5; 39 URI uri; 40 41 final static int max_redirects = Utils.getIntegerNetProperty( 42 "java.net.httpclient.redirects.retrylimit", DEFAULT_MAX_REDIRECTS 43 ); 44 45 @Override 46 public void request(HttpRequestImpl r) throws IOException { 47 this.request = r; 48 this.policy = request.followRedirects(); 49 this.client = r.getClient(); 50 this.method = r.method(); 51 this.requestImpl = r; 52 this.uri = r.uri(); 53 } 54 55 @Override 56 public HttpRequestImpl response(HttpResponseImpl r) throws IOException { 57 return handleResponse(r); 58 } 59 60 /** 61 * checks to see if new request needed and returns it. 62 * Null means response is ok to return to user. 63 */ 64 private HttpRequestImpl handleResponse(HttpResponseImpl r) { 65 int rcode = r.statusCode(); 66 if (rcode == 200 || policy == HttpClient.Redirect.NEVER) { 67 return null; 68 } 69 if (rcode >= 300 && rcode <= 399) { 70 URI redir = getRedirectedURI(r.headers()); 71 if (canRedirect(r) && ++r.request.exchange.numberOfRedirects < max_redirects) { 72 //System.out.println("Redirecting to: " + redir); 73 return new HttpRequestImpl(redir, request, client, method, requestImpl); 74 } else { 75 //System.out.println("Redirect: giving up"); 76 return null; 77 } 78 } 79 return null; 80 } 81 82 private URI getRedirectedURI(HttpHeaders headers) { 83 URI redirectedURI; 84 String ss = headers.firstValue("Location").orElse("Not present"); 85 redirectedURI = headers.firstValue("Location") 86 .map((s) -> URI.create(s)) 87 .orElseThrow(() -> new UncheckedIOException( 88 new IOException("Invalid redirection"))); 89 90 // redirect could be relative to original URL, but if not 91 // then redirect is used. 92 redirectedURI = uri.resolve(redirectedURI); 93 return redirectedURI; 94 } 95 96 private boolean canRedirect(HttpResponse r) { 97 return requestImpl.followRedirectsImpl().redirect(r); 98 } 99 }