I've finally managed to find a correct solution. It's relatively easy once
you put everything together.

In AppModule.bind():

        binder.bind ( BaseURLSource.class,
ForwardedBaseURLSourceImpl.class).withId (
"ForwardedBaseURLSource" );



Contribute service override to BaseURLSource:

    @Contribute(ServiceOverride.class)

    public static void setupApplicationServiceOverrides (
MappedConfiguration<Class<?>, Object> configuration,

            @Local @Service("ForwardedBaseURLSource") BaseURLSource
override ) {



        configuration.add ( BaseURLSource.class, override );

    }

Advise to Request.isSecure ():

    @Advise(serviceInterface=Request.class)

    public static void adviseHttpsMode ( MethodAdviceReceiver receiver ) {

        org.apache.tapestry5.plastic.MethodAdvice methodAdvice =
neworg.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;

            }

        }

    }

And, finally, ForwardedBaseURLSourceImpl class:

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 );

    }


}

That fixes all issues I had.



On Tue, Feb 18, 2014 at 10:18 AM, Daniel Jue <teamp...@gmail.com> wrote:

> I don't have the full solution here in front of me, but I know I've done
> this in the past with the Tapestry Spring Security integration, and I'm
> sure the Tynamo Shiro integration for T5 also does this.  You could snoop
> around the code in there until someone here gets you an answer that meets
> your needs.
>
>
> On Mon, Feb 17, 2014 at 5:52 PM, Ilya Obshadko <ilya.obsha...@gmail.com
> >wrote:
>
> > I've researched a little bit more and found BaseURLSource service which
> is
> > responsible for URL construction.
> >
> > But overriding BaseURLSource doesn't work because of circular dependency
> > during initialization, while trying to alter BaseURLSource using advisors
> > simply doesn't work at all (advisor never gets called).
> >
> > I'm stuck.
> >
> >
> >
> > On Tue, Feb 18, 2014 at 8:34 AM, Ilya Obshadko <ilya.obsha...@gmail.com
> > >wrote:
> >
> > > I have already implemented it using method advice, so that
> > > Request.isSecure () returns true when frontend sets appropriate header.
> > >
> > > However things turn strange at this point. All links rendered by
> PageLink
> > > component now look like:
> > >
> > > http://servername:443/context/page
> > >
> > > Note plain http instead of https in front. So the port does change, but
> > > protocol does not. What am I doing wrong? Could you point me in a right
> > > direction?
> > >
> > > This is very strange, because PageLink rendering uses the same
> mechanisms
> > > Link.toAbsoluteURI () does, and the latter works, while the former
> > doesn't.
> > >
> > >
> > >
> > >
> > > On Tue, Feb 18, 2014 at 8:03 AM, Thiago H de Paula Figueiredo <
> > > thiag...@gmail.com> wrote:
> > >
> > >> On Mon, 17 Feb 2014 17:31:53 -0300, Ilya Obshadko <
> > >> ilya.obsha...@gmail.com> wrote:
> > >>
> > >>  I understand how to do that with service advisors, but decoration
> > remains
> > >>> unclear. How do I override a single method from the interface using
> > >>> decoration? Could you provide a brief example?
> > >>>
> > >>
> > >> See http://tapestry.apache.org/tapestry-ioc-decorators.html,
> > >> AspectDecorator, its method AspectInterceptorBuilder
> > createBuilder(Class<T>
> > >> serviceInterface, T delegate, String description),
> > >> AspectInterceptorBuilder, which is a subinterface of
> > MethodAdviceReceiver,
> > >> which has the adviseMethod(Method, MethodAdvice) method.
> > >>
> > >> Summary: in almost the same way as advice.
> > >>
> > >> --
> > >> Thiago H. de Paula Figueiredo
> > >> Tapestry, Java and Hibernate consultant and developer
> > >> http://machina.com.br
> > >>
> > >> ---------------------------------------------------------------------
> > >> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> > >> For additional commands, e-mail: users-h...@tapestry.apache.org
> > >>
> > >>
> > >
> > >
> > > --
> > > Ilya Obshadko
> > >
> > >
> >
> >
> > --
> > Ilya Obshadko
> >
>



-- 
Ilya Obshadko

Reply via email to