Catalyst::Plugin::Session::State::URIと携帯端末とfragment付きリンク

C::P::Session::State::URIは便利なんだけどfragmentが付いてるリンクまでセッションIDを埋め込んでしまうので微妙。

なんでかっていうとDoCoMo等、クエリとfragmentが存在する場合、ページ内リンクにならずにページ遷移してしまうんだよね。

ちなみにfragmentってのは以下のようなものね。

<a href="#">foo</a>

動画のダウンロードとかでオブジェクトタグ使ってるとダウンロードできなくなってしまうので困った困った。

なのでfragment付いてる時はセッションIDを埋め込まないようにするモジュールを作った。

package MyApp::Session::State::MobileURI;
use strict;
use warnings;

our $VERSION = 0.01;

sub session_should_rewrite_uri {
    my ( $c, $uri_text ) = @_;

    my $uri_obj = eval { URI->new($uri_text) } || return;
    
    # ignore the url outside
    my $rel = $uri_obj->abs( $c->request->base );
    
    return unless index( $rel, $c->request->base ) == 0;

    return unless $c->session_should_rewrite_uri_mime_type($rel);

    if ( my $param = $c->config->{session}{param} )
    {    # use param style rewriting

        # 「#」がついていたらセッションIDを突っ込まない
        return if defined $uri_obj->fragment;

        # if the URI query string doesn't contain $param
        return not defined $uri_obj->query_param($param);

    } else {    # use path style rewriting

        # if the URI isn't already rewritten
        return $uri_obj->path !~ m#/-/#;

    }
}

1;

こーんなのをこしらえて

use Catalyst qw(




    Session
    +MyApp::Session::State::MobileURI
    Session::State::URI
    Session::Store::DBIC




);

のように、Session::State::URIの前に設定すればおk。

これでfragment付きの場合にセッションIDが埋め込まれなくなって問題解決なり。

まーPCでは埋め込まれてもいいという人は$c->req->mobile_agentから判定して携帯端末の時だけ外すとかカスタマイズすればいいと思いまする。