Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
ZNTA-937 - handle server redirect gracefully
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Huang committed Mar 1, 2016
1 parent 3cdd044 commit 6163f8c
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2015, Red Hat, Inc. and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.zanata.rest.client;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.ws.rs.core.MediaType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jersey.api.client.ClientHandler;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.ClientRequest;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.filter.ClientFilter;

/**
* @author Patrick Huang <a href="mailto:[email protected]">[email protected]</a>
*/
public class InvalidContentTypeFilter extends ClientFilter {
private static final Logger log =
LoggerFactory.getLogger(InvalidContentTypeFilter.class);
private static final String ERROR_MSG = "Receiving HTML from the server. " +
"Most likely hitting a redirect or server returning error page. " +
"Please check the server URL is correct (in zanata.ini and in zanata.xml) and make sure you use the non-redirected address.";


@Override
public ClientResponse handle(ClientRequest clientRequest)
throws ClientHandlerException {
ClientHandler ch = getNext();
ClientResponse resp = ch.handle(clientRequest);

if (MediaType.TEXT_HTML_TYPE.isCompatible(resp.getType())) {
log.error(ERROR_MSG);
String title = findPageTitle(resp);
String snippet = String.format("Wrong content type received: [%s]. Content page title: [%s]",
resp.getType(), title);

log.error(snippet);
throw new IllegalStateException(snippet);
} else {
return resp;
}
}

private String findPageTitle(ClientResponse resp) {
String body = resp.getEntity(String.class).replaceAll("\\n", " ");
Pattern pattern = Pattern.compile(".*<title>(.*)</title>.*");
Matcher matcher = pattern.matcher(body);
if (matcher.matches()) {
return matcher.group(1);
}
return "";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2015, Red Hat, Inc. and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.zanata.rest.client;

import java.net.URI;
import javax.ws.rs.core.Response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jersey.api.client.ClientHandler;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.ClientRequest;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.filter.ClientFilter;

/**
* @author Patrick Huang <a href="mailto:[email protected]">[email protected]</a>
*/
public class RedirectFilter extends ClientFilter {
private static final Logger log =
LoggerFactory.getLogger(RedirectFilter.class);

@Override
public ClientResponse handle(ClientRequest clientRequest)
throws ClientHandlerException {
ClientHandler ch = getNext();
ClientResponse resp = ch.handle(clientRequest);

if (resp.getClientResponseStatus().getFamily() !=
Response.Status.Family.REDIRECTION) {
return resp;
} else {
// try location
log.debug("Server returns redirection status: {}. Try to follow it",
resp.getClientResponseStatus());
URI redirectTarget = resp.getLocation();
if (redirectTarget != null) {
clientRequest.setURI(redirectTarget);
}
return ch.handle(clientRequest);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,12 @@ public RestClientFactory(URI base, String username, String apiKey,
clientConfig.getClasses().add(JacksonJsonProvider.class);

client = Client.create(clientConfig);
client.addFilter(new RedirectFilter());
client.addFilter(
new ApiKeyHeaderFilter(username, apiKey, clientVersion));
client.addFilter(new AcceptTypeFilter());
client.addFilter(new TraceDebugFilter(logHttp));
client.addFilter(new InvalidContentTypeFilter());
}

private static void sslConfiguration(boolean sslCertDisabled,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.zanata.rest.client;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.hamcrest.MatcherAssert;
import org.junit.Test;

import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.*;

public class InvalidContentTypeFilterTest {

private String sampleText =
"<!DOCTYPE composition PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" +
"\n" +
" <html class=\"new-zanata-html\"><head>\n" +
" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n" +
" <title>Zanata: Home</title>\n" +
" <link rel=\"shortcut icon\" href=\"/javax.faces.resource/jars/assets/img/logo/logo.ico\" type=\"image/x-icon\" />\n" +
" <link type=\"text/css\" rel=\"stylesheet\" href=\"/resources/fontello/css/fontello.css\" />\n" +
" <link type=\"text/css\" rel=\"stylesheet\" class=\"user\" href=\"/javax.faces.resource/jars/assets/css/zanata.css\" />\n" +
" <link type=\"text/css\" rel=\"stylesheet\" href=\"/javax.faces.resource/jars/assets/css/style.min.css\" />";

private String text = " <title>Zanata: Home</title> \n";

@Test
public void testPatternMatch() {
Pattern pattern = Pattern.compile(".*<title>(.*)</title>.*", Pattern.CASE_INSENSITIVE);

Matcher matcher = pattern.matcher(sampleText.replaceAll("\\n", " "));

MatcherAssert.assertThat(matcher.matches(), equalTo(true));
MatcherAssert.assertThat(matcher.group(1), equalTo("Zanata: Home"));
}

}

0 comments on commit 6163f8c

Please sign in to comment.