Skip to content

Instantly share code, notes, and snippets.

@xfyre
Last active April 22, 2018 20:57
Show Gist options
  • Save xfyre/9104238 to your computer and use it in GitHub Desktop.
Save xfyre/9104238 to your computer and use it in GitHub Desktop.
handling X-Forwarded-Proto in Tapestry 5
/**
* Pre-requisites:
* - add <Set name="forwarded">true</Set> to jetty.xml connector configuration section
* - set RequestHeader set X-Forwarded-Proto "https" env=HTTPS in apache configuration
*/
/* extend BaseURLSourceImpl */
public class ForwardedBaseURLSourceImpl extends BaseURLSourceImpl {
private final Request request;
public ForwardedBaseURLSourceImpl ( Request request,
@Inject @Symbol(SymbolConstants.HOSTNAME) String hostname,
@Symbol(SymbolConstants.HOSTPORT) int hostPort,
@Symbol(SymbolConstants.HOSTPORT_SECURE) int secureHostPort ) {
super ( request, hostname, hostPort, secureHostPort );
this.request = request;
}
@Override
public String getBaseURL ( boolean secure ) {
if ( ! secure && "https".equalsIgnoreCase ( request.getHeader ( "X-Forwarded-Proto" ) ) )
return super.getBaseURL ( true );
return super.getBaseURL ( secure );
}
}
/* re-bind BaseURLSource service with different ID in AppModule */
public static void bind ( ServiceBinder binder ) {
binder.bind ( BaseURLSource.class, ForwardedBaseURLSourceImpl.class ).withId ( "ForwardedBaseURLSource" );
// Make bind() calls on the binder object to define most IoC services.
// Use service builder methods (example below) when the implementation
// is provided inline, or requires more initialization than simply
// invoking the constructor.
}
/**
* Override BaseURLSource service to respect X-Forwarded-Proto header
* @param configuration
* @param override
*/
@Contribute(ServiceOverride.class)
public static void setupApplicationServiceOverrides ( MappedConfiguration<Class<?>, Object> configuration,
@Local @Service("ForwardedBaseURLSource") BaseURLSource override ) {
configuration.add ( BaseURLSource.class, override );
}
/**
* Override isSecure() returned by Request interface
* @param receiver
*/
@Advise(serviceInterface=Request.class)
public static void adviseHttpsMode ( MethodAdviceReceiver receiver ) {
org.apache.tapestry5.plastic.MethodAdvice methodAdvice = new org.apache.tapestry5.plastic.MethodAdvice () {
@Override
public void advise ( MethodInvocation invocation ) {
Request request = (Request) invocation.getInstance ();
if ( "https".equalsIgnoreCase ( request.getHeader ( "X-Forwarded-Proto" ) ) )
invocation.setReturnValue ( true );
else
invocation.proceed ();
}
};
for ( Method m : receiver.getInterface ().getMethods () ) {
if ( m.getName ().equals ( "isSecure" ) ) {
receiver.adviseMethod ( m, methodAdvice );
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment