Apache2-Translation

 view release on metacpan or  search on metacpan

lib/Apache2/Translation.pod  view on Meta::CPAN

  # another provider
  <TranslationProvider File>
      Configfile /path/to/config
  </TranslationProvider>

  # export our provider parameters
  <Location /config>
    SetHandler modperl
    PerlResponseHandler Apache2::Translation::Config
  </Location>

  # configuring the WEB interface
  PerlModule Apache2::Translation::Admin
  <Location /-/transadm/>
    SetHandler modperl
    PerlResponseHandler Apache2::Translation::Admin
  </Location>

=head1 DESCRIPTION

As the name implies C<Apache2::Translation> lives mostly in the URI Translation
Phase. It is somehow similar to C<mod_rewrite> but configuration
statements are read at runtime, thus, allowing to reconfigure
a server without restarting it.

The actual configuration statements are read by means of a
I<Translation Provider>, a Perl class offering
a particular interface, see below. Currently there are 3 providers
implemented, L<Apache2::Translation::DB>, L<Apache2::Translation::BDB>,
and L<Apache2::Translation::File>.

There is also a WEB interface (L<Apache2::Translation::Admin>).

=head2 B<An Example>

Let's begin with an example. Given some database table:

 id  key    uri      blk ord action
  1  front  :PRE:    0   0   Cond: $HOSTNAME !~ /^(?:www\.)xyz\.(?:com|de)$/
  2  front  :PRE:    0   1   Redirect: 'http://xyz.com'.$URI, 301
  3  front  :PRE:    1   0   Do: $CTX{lang}='en'
  4  front  :PRE:    1   1   Cond: $HOSTNAME =~ /de$/
  5  front  :PRE:    1   2   Do: $CTX{lang}='de'
  6  front  /static  0   0   File: $DOCROOT.'/'.$CTX{lang}.$MATCHED_PATH_INFO
  7  front  /appl1   0   0   Proxy: 'http://backend/'.$CTX{lang}.$URI
  8  front  /appl2   0   0   Proxy: 'http://backend/'.$URI.'?l='.$CTX{lang}
  9  front  /        0   0   Config: ['AuthName "secret"'], ['AuthType Basic']
 10  back   :PRE:    0   0   Cond: $r->connection->remote_ip ne '127.0.0.1'
 11  back   :PRE:    0   1   Error: 403, 'Forbidden by Apache2::Translation(11)'
 12  back   /appl1   0   0   PerlHandler: 'My::Application1'
 13  back   /appl2   0   0   PerlHandler: 'My::Application2'

The C<id> column in this table is not really necessary for
C<Apache2::Translation>. But if you want to deploy
L<Apache2::Translation::Admin> you need it.

Well, here we have a frontend/backend configuration. The frontend records
are labeled with the key C<front>, the backend records with C<back>.

When a request comes in first the records with C<:PRE:> in the C<uri>-field are
examined. Suppose, a request for C<http://abc.com/static/img.png>
comes in. Record 1 (id=1) checks the C<Host> header. The expression
after C<Cond:> is evaluated as Perl code. It obviously returns true.
C<Cond> stands for I<condition>. But how does it affect the further
workflow? Here C<blk> and C<ord> come in. All records with the same
C<key>, C<uri> and C<blk> form a B<block>. C<ord> gives an order within
this block. Within a block all actions are executed up to the first
condition that is false.

Now, because our condition in record 1 is true the action in record 2
(within the same block) is executed. It redirects the browser with a
HTTP code of 301 (MOVED PERMANENTLY) to C<http://xyz.com/static/img.png>.

When the redirected request comes back the condition in record 1 is
false. Hence, the next block (key=front, uri=:PRE:, blk=1) is evaluated.
First a C<lang> member of a context hash is set to C<en>. A C<Do> action
is similar to a condition, only its value is ignored. Record 4 then
checks if the C<Host> header matches C</de$/>. If so, then record 5 sets
the I<language> to C<de>.

Now, the records labeled with C<:PRE:> are finished. The handler starts
looking for blocks labeled with the request uri. That is, it looks
for a block with key=front, uri=/static/img.png. None is found.

Then it cuts off the last part of the uri (/img.png), repeats the
lookup and finds record 6. The C<File> action sets C<$r-E<gt>filename> to
C<$DOCROOT/en/img.png>. C<Apache2::Translation> provides some convenience
variables. They are tied to members of the request record.
C<$MATCHED_PATH_INFO> contains the uri part cut off
(C</img.png>). More on them below.

Now another round is started and the next uri part is cut off. Record 9
matches. We see a C<Config> action that sets C<AuthName> and C<AuthType>.

At the end the translation handler checks if C<$r-E<gt>filename> was set and
returns C<Apache2::Const::OK> or C<Apache2::Const::DECLINED> respectively.

I think that example gives a general idea, what C<Apache2::Translation>
does.

=head2 B<Processing States>

Internally C<Apache2::Translation> is implemented as a state machine. It
starts in the I<START> state, where some variables are initialized. From
there it shifts immediately to the I<PREPOC> state. Here all C<:PRE:>
rules are evaluated. From I<PREPROC> it shifts to I<PROC>. Now the rules
with real uris are examined. When the I<DONE> state is reached processing is
finished.

There is a special state named I<LOOKUPFILE>. It is only used for subrequests
that don't have an URI. For such requests the URI translation phase of the
request cycle is skipped. Hence a I<PerlTransHandler> would never be called.
Such requests are results of calling C<$r-E<gt>lookup_file> for example.

To catch also such requests install C<Apache2::Translation> both as
I<PerlTransHandler> as well as I<PerlMapToStorageHandler>. Then if such a
subrequest occures the handler enters the I<LOOKLUPFILE> state instead of
I<PREPROC>. From I<LOOKLUPFILE> it normally shifts to I<PROC> unless it
executes a C<Restart> action. In that case it shifts to I<PREPROC>.

You have to set C<$MATCHED_URI> to some initial value if you want to hop
through the I<PROC> phase. A still empty C<$MATCHED_URI> shifts from I<PROC>
immediately to I<DONE>.

B<Note>: The I<LOOKUPFILE> stuff is still somewhat experimental.

You can control the current state by means of the C<State>, C<Done> and
C<Restart> actions.

=head2 B<Blocks and Lists of Blocks>

Above, we have defined a B<block> as all records with the same
C<key>, C<uri> and C<block>. The actions within a block are ordered by
the C<order> field.

A B<list of blocks> is then an ordered list of all blocks with the same
C<key> and C<uri>. The order is given by the C<block> number.

=head2 B<Actions>

An action starts with a key word optionally followed by a colon and
some arguments. The key words are case insensitive.

C<Apache2::Translation> provides some environment for code snippets in
actions. They are compiled into perl functions. The compiled result is
cached. 2 variables, C<$r> and C<%CTX>, are provided plus a few
convenience variables. C<$r> is the current C<Apache2::RequestRec>.
C<%CTX> is a hash that can be used to store arbitrary data. This hash
is not used by Apache2::Translation itself. It can be used to pass data
between actions. But note, the hash is localized to the translation handler.



( run in 0.995 second using v1.01-cache-2.11-cpan-df04353d9ac )