1# vi:ai:sm:et:sw=4:ts=4:tw=0
2#
3# REST::Application - A framework for building RESTful web-applications.
4#
5# Copyright 2005 Matthew O'Connor <matthew@canonical.org>
6package REST::Application;
7use strict;
8use warnings;
9use Carp;
10use Tie::IxHash;
11use UNIVERSAL;
12use CGI;
13
14our $VERSION = '0.992';
15
16####################
17# Class Methods
18####################
19
20sub new {
21    my ($proto, %args) = @_;
22    my $class = ref($proto) ? ref($proto) : $proto;
23    my $self = bless({ __defaultQuery => CGI->new() }, $class);
24    $self->setup(%args);
25    return $self;
26}
27
28##################################
29# Instance Methods - Object State
30##################################
31
32sub query {
33    my $self = shift;
34
35    # Set default value if this method hasn't been called yet.
36    if (not exists $self->{__query}) {
37        $self->{__query} = $self->defaultQueryObject();
38    }
39
40    # Set the field if we got any arguments.
41    $self->{__query} = shift if @_;
42
43    return $self->{__query};
44}
45
46sub defaultQueryObject {
47    my $self = shift;
48
49    # Set the field if we got any arguments.
50    if (@_) {
51        $self->{__defaultQuery} = shift;
52    }
53
54    return $self->{__defaultQuery};
55}
56
57sub resourceHooks {
58    my $self = shift;
59
60    # Set default value if this method hasn't been called yet.
61    if (not exists $self->{__resourceHooks}) {
62        my %hooks;
63        tie(%hooks, "Tie::IxHash");  # For keeping hash key order preserved.
64        $self->{__resourceHooks} = \%hooks;
65    }
66
67    # If we got arguments then they should be an even sized list, otherwise a
68    # hash reference.
69    if (@_ and @_%2 == 0) {
70        %{ $self->{__resourceHooks} } = @_;
71    } elsif (@_ == 1) {
72        my $value = shift;
73        if (ref($value) ne 'HASH') {
74            croak "Expected hash reference or even-sized list.";
75        }
76        %{ $self->{__resourceHooks} } = %$value;
77    }
78
79    return $self->{__resourceHooks};
80}
81
82sub extraHandlerArgs {
83    my $self = shift;
84
85    # Set default value for method if it hasn't been called yet.
86    if (not exists $self->{__extraHandlerArgs}) {
87        $self->{__extraHandlerArgs} = [];
88    }
89
90    # If got arguments then process them.  We expect either a single array
91    # reference or a list
92    if (@_) {
93        if (@_ == 1 and ref($_[0]) eq 'ARRAY') {
94            $self->{__extraHandlerArgs} = shift;
95        } else {
96            $self->{__extraHandlerArgs} = [ @_ ];
97        }
98    }
99
100    return @{ $self->{__extraHandlerArgs} };
101}
102
103##################################
104# Instance Methods - Proxies
105##################################
106
107sub getPathInfo {
108    my $self = shift;
109    return $self->query->path_info();
110}
111
112sub getRealRequestMethod {
113    my $self = shift;
114    return uc( $self->query->request_method() || "" );
115}
116
117sub getRequestMethod {
118    my $self          = shift;
119    my $real_method   = $self->getRealRequestMethod();
120    my $tunnel_method = uc(
121               $self->query->http('X-HTTP-Method')
122            || $self->query->url_param('http_method')
123            || $self->query->param('http_method')
124            || $real_method
125    );
126
127    # POST can tunnel any method.
128    return $tunnel_method if $real_method eq 'POST';
129
130    # GET can only tunnel GET/HEAD
131    if ( $real_method eq 'GET' and $tunnel_method =~ /^(GET|HEAD)$/ ) {
132        return $tunnel_method;
133    }
134
135    return $real_method;
136}
137
138#############################
139# Instance Methods - Public
140#############################
141
142sub loadResource {
143    my ($self, $path, @extraArgs) = @_;
144    $path ||= $self->getMatchText();
145    my $handler = sub { $self->defaultResourceHandler(@_) };
146    my $matches = [];
147
148    # Loop through the keys of the hash returned by resourceHooks().  Each of
149    # the keys is a regular expression, see if the current path info matches
150    # that regular expression.  Save the parent matches for passing into the
151    # handler.
152    for my $pathRegex (keys %{ $self->resourceHooks() }) {
153        if ($self->checkMatch($path, $pathRegex)) {
154            $handler = $self->_getHandlerFromHook($pathRegex);
155            last;
156        }
157    }
158
159    return $self->callHandler($handler, @extraArgs);
160}
161
162sub getHandlerArgs {
163    my ($self, @extraArgs) = @_;
164    my @args = ($self,
165                $self->_getLastRegexMatches(),
166                $self->extraHandlerArgs(),
167                @extraArgs);
168
169    # Don't make $self the first argument if the handler is a method on $self,
170    # because in that case it'd be redundant.  Also see _getHandlerFromHook().
171    shift @args if $self->{__handlerIsOurMethod};
172
173    return @args;
174}
175
176sub callHandler {
177    my ($self, $handler, @extraArgs) = @_;
178    my @args = $self->getHandlerArgs(@extraArgs);
179
180    # Call the handler, carp if something goes wrong.
181    my $result;
182    eval {
183        $self->preHandler(\@args);  # no-op by default.
184        $result = $handler->(@args);
185        $self->postHandler(\$result, \@args); # no-op by default.
186    };
187    carp "Handler failed: $@\n" if $@;
188
189    # Convert the result to a scalar result if it isn't already.
190    my $ref = (ref($result) eq 'scalar') ? $result : \$result;
191
192    return $ref;
193}
194
195sub getMatchText {
196    my $self = shift;
197    return $self->getPathInfo();
198}
199
200sub checkMatch {
201    my ($self, $a, $b) = @_;
202    my $match = 0;
203
204    if ($a =~ /$b/) {
205        $self->_setLastRegexMatches();
206        $self->{__last_match_path} = $a;
207        $self->{__last_match_pattern} = $b;
208        $match = 1;
209    }
210
211    return $match;
212}
213
214sub getLastMatchPath {
215    my $self = shift;
216    return $self->{__last_match_path};
217}
218
219sub getLastMatchPattern {
220    my $self = shift;
221    return $self->{__last_match_pattern};
222}
223
224sub run {
225    my $self = shift;
226
227    # Get resource.
228    $self->preRun(); # A no-op by default.
229    my $repr = $self->loadResource(@_);
230    $self->postRun($repr); # A no-op by default.
231
232    # Get the headers and then add the representation to to the output stream.
233    my $output = $self->getHeaders();
234    $self->addRepresentation($repr, \$output);
235
236    # Send the output unless we're told not to by the environment.
237    print $output if not $ENV{REST_APP_RETURN_ONLY};
238
239    return $output;
240}
241
242sub getHeaders {
243    my $self = shift;
244    my $type = $self->headerType() || "";
245    my $header = "";
246
247    if ($type eq 'header') {
248        $header = $self->query->header($self->header());
249    } elsif ($type eq 'redirect') {
250        $header = $self->query->redirect($self->header());
251    } elsif ($type ne 'none') {
252        croak "Unexpected header type: \"$type\".";
253    }
254
255    return $header;
256}
257
258sub addRepresentation {
259    my ($self, $repr, $outputRef) = @_;
260
261    # Make sure $outputRef is a scalar ref and the scalar it references is
262    # defined.
263    return if ref($outputRef) ne 'SCALAR';
264    return if not defined $$outputRef;
265
266    # If we're given a scalar reference then dereference it first, otherwise
267    # just treat what we got as though it's a string.
268    if (ref($repr) eq 'SCALAR') {
269        $$outputRef .= $$repr if defined $$repr;
270    } else {
271        $$outputRef .= $repr if defined $repr;
272    }
273}
274
275sub headerType {
276    my $self = shift;
277
278    # Set the default value if this method has not been called yet.
279    if (not exists $self->{__headerType}) {
280        $self->{__headerType} = "header";
281    }
282
283    # If an argument was passed in then use them to set the header type.
284    if (@_) {
285        my $type = lc(shift || "");
286        if ($type =~ /^(redirect|header|none)$/) {
287            $self->{__headerType} = $type;
288        } else {
289            croak "Invalid header type specified: \"$type\"";
290        }
291    }
292
293    return $self->{__headerType};
294}
295
296sub header {
297    my $self = shift;
298
299    # Set the default value if this method has not been called yet.
300    if (not exists $self->{__header}) {
301        $self->{__header} = {};
302    }
303
304    # If arguments were passed in then use them to set the header type.
305    # Arguments can be passed in as a hash-ref or as an even sized list.
306    if (@_) {
307        if (@_%2 == 0) { # even-sized list, must be hash
308            %{ $self->{__header} } = @_;
309        } elsif (ref($_[0]) eq 'HASH') {  # First item must be a hash reference
310            $self->{__header} = shift;
311        } else {
312            croak "Expected even-sized list or hash reference.";
313        }
314    }
315
316    return %{$self->{__header}};
317}
318
319sub resetHeader {
320    my $self = shift;
321    my %old = $self->header();
322    $self->headerType('header');
323    $self->{__header} = {};
324    return %old;
325}
326
327sub setRedirect {
328    my ($self, $url) = @_;
329    $self->headerType('redirect');
330    $self->header(-url => $url || "");
331}
332
333##############################################
334# Instance Methods - Intended for Overloading
335##############################################
336
337sub setup { return }
338sub preRun { return }
339sub postRun{ return }
340sub preHandler { return }
341sub postHandler { return }
342sub defaultResourceHandler { return }
343
344#############################
345# Instance Methods - Private
346#############################
347
348# CodeRef _getHandlerFromHook(String $pathRegex)
349#
350# This method retrieves a code reference which will yield the resource of the
351# given $pathRegex, where $pathRegex is a key into the resource hooks hash (it
352# isn't used as a regex in this method, just a hash key).
353sub _getHandlerFromHook {
354    my ($self, $pathRegex) = @_;
355    my $ref = $self->resourceHooks()->{$pathRegex};
356    my $refType = ref($ref);
357    my $handler = sub { $self->defaultResourceHandler(@_) };
358    my $method = $self->getRequestMethod() || "getResource";
359
360    # If we get a hash, then use the request method to narrow down the choice.
361    # We do this first because we allow the same range of handler types for a
362    # particular HTTP method that we do for a more generic handler.
363    if ($refType eq 'HASH') {
364        %$ref = map { uc($_) => $ref->{$_} } keys %$ref;  # Uppercase the keys
365        my $http_method = $self->getRequestMethod();
366        if (exists $ref->{$http_method}) {
367            $ref = $ref->{$http_method}
368        } elsif (exists $ref->{'*'}) {
369            $ref = $ref->{'*'};
370        } else {
371            return $handler;  # Just bail now with the default handler.
372        }
373        $refType = ref($ref);
374    }
375
376    # If we still have a hash then assume we're doing Content Negotation
377    if ($refType eq 'HASH') {
378        my $type = $self->bestContentType(keys %$ref);
379        $ref = $ref->{$type};
380        $refType = ref($ref);
381    }
382
383    # Based on the the reference's type construct the handler.
384    if ($refType eq "CODE") {
385        # A code reference
386        $handler = $ref;
387    } elsif ($refType eq "ARRAY") {
388        # Array reference which holds a $object and "method name" pair.
389        my ($thing, $smethod) = @$ref;
390        $smethod ||= $method;
391        if (ref $thing) {
392            $handler = $self->makeHandlerFromRef($thing, $smethod);
393        } else {
394            $handler = $self->makeHandlerFromClass($thing, $smethod);
395        }
396    } elsif ($refType) {
397        # Object with GET, PUT, etc, or getResource method.
398        $handler = $self->makeHandlerFromRef($ref, $method);
399    } elsif ($ref) {
400        # A bare string signifying a method name
401        $handler = sub { $self->$ref(@_) };
402        $self->{__handlerIsOurMethod} = 1;  # See callHandler().
403    }
404
405    return $handler;
406}
407
408sub makeHandlerFromRef {
409    my ($self, $ref, $method) = @_;
410    return sub { $ref->$method(@_) };
411}
412
413sub makeHandlerFromClass {
414    my ($self, $class, $method) = @_;
415    return sub { $class->$method(@_) };
416}
417
418sub bestContentType {
419    my ($self, @types) = @_;
420    return ($self->simpleContentNegotiation(@types))[0] || '*/*';
421}
422
423# We don't support the full range of content negtiation because a) it's
424# overkill and b) it makes it hard to specify the hooks cleanly, also see (a).
425sub simpleContentNegotiation {
426    my ($self, @types) = @_;
427    my @accept_types = $self->getContentPrefs();
428    my $score = sub { $self->scoreType(shift, @accept_types) };
429    return sort {$score->($b) <=> $score->($a)} @types;
430}
431
432# The pattern matching stuff was stolen from CGI.pm
433sub scoreType {
434    my ($self, $type, @accept_types) = @_;
435    my $score = scalar(@accept_types);
436    for my $accept_type (@accept_types) {
437        return $score if $type eq $accept_type;
438        my $pat;
439        ($pat = $accept_type) =~ s/([^\w*])/\\$1/g; # escape meta characters
440        $pat =~ s/\*/.*/g; # turn it into a pattern
441        return $score if $type =~ /$pat/;
442        $score--;
443    }
444    return 0;
445}
446
447# Basic idea stolen from CGI.pm.  Its semantics made it hard to pull out the
448# information I wanted without a lot of trickery, so I improved upon the
449# original.  Same with libwww's HTTP::Negotiate algorithim, it's also hard to
450# make go with what we want.
451sub getContentPrefs {
452    my $self = shift;
453    my $default_weight = 1;
454    my @prefs;
455
456    # Parse the Accept header, and save type name, score, and position.
457    my @accept_types = split /,/, $self->getAcceptHeader();
458    my $order = 0;
459    for my $accept_type (@accept_types) {
460        my ($weight) = ($accept_type =~ /q=(\d\.\d+|\d+)/);
461        my ($name) = ($accept_type =~ m#(\S+/[^;]+)#);
462        next unless $name;
463        push @prefs, { name => $name, order => $order++};
464        if (defined $weight) {
465            $prefs[-1]->{score} = $weight;
466        } else {
467            $prefs[-1]->{score} = $default_weight;
468            $default_weight -= 0.001;
469        }
470    }
471
472    # Sort the types by score, subscore by order, and pull out just the name
473    @prefs = map {$_->{name}} sort {$b->{score} <=> $a->{score} ||
474                                    $a->{order} <=> $b->{order}} @prefs;
475    return @prefs, '*/*';  # Allows allow for */*
476}
477
478sub getAcceptHeader {
479    my $self = shift;
480    return $self->query->http('accept') || "";
481}
482
483# List _getLastRegexMatches(void)
484#
485# Returns a list of all the paren matches in the last regular expression who's
486# matches were saved with _saveLastRegexMatches().
487sub _getLastRegexMatches {
488    my $self = shift;
489    my $matches = $self->{__lastRegexMatches} || [];
490    return @$matches;
491}
492
493# ArrayRef _setLastRegexMatches(void)
494#
495# Grabs the values of $1, $2, etc. as set by the last regular expression to run
496# in the current dyanamic scope.  This of course exploits that $1, $2, etc. and
497# @+ are dynamically scoped.  A reference to an array is returned where the
498# array values are $1, $2, $3, etc.  _getLastRegexMatches() can also be used to
499# retrieve the values saved by this method.
500sub _setLastRegexMatches {
501    my $self = shift;
502    no strict 'refs'; # For the $$_ symbolic reference below.
503    my @matches = map $$_, (1 ..  scalar(@+)-1);  # See "perlvar" for @+.
504    $self->{__lastRegexMatches} = \@matches;
505}
506
5071;
508__END__
509=pod
510
511=head1 NAME
512
513L<REST::Application> - A framework for building RESTful web-applications.
514
515=head1 SYNOPSIS
516
517    # MyRESTApp L<REST::Application> instance / mod_perl handler
518    package MyRESTApp;
519    use Apache;
520    use Apache::Constants qw(:common);
521
522    sub handler {
523        __PACKAGE__->new(request => $r)->run();
524        return OK;
525    }
526
527    sub getMatchText { return Apache->uri }
528
529    sub setup {
530        my $self = shift;
531        $self->resourceHooks(
532            qr{/rest/parts/(\d+)} => 'get_part',
533            # ... other handlers here ...
534        );
535    }
536
537    sub get_part {
538        my ($self, $part_num) = @_;
539        # Business logic to retrieve part num
540    }
541
542    # Apache conf
543    <Location /rest>
544        perl-script .cgi
545        PerlHandler MyRESTApp
546    </Location>
547
548=head1 DESCRIPTION
549
550This module acts as a base class for applications which implement a RESTful
551interface.   When an HTTP request is received some dispatching logic in
552L<L<REST::Application>> is invoked, calling different handlers based on what the
553kind of HTTP request it was (i.e. GET, PUT, etc) and what resource it was
554trying to access.  This module won't ensure that your API is RESTful but
555hopefully it will aid in developing a REST API.
556
557=head1 OVERVIEW
558
559The following list describes the basic way this module is intended to be used.
560It does not capture everything the module can do.
561
562=over 8
563
564=item 1. Subclass
565
566Subclass L<REST::Application>, i.e. C<use base 'REST::Application'>.
567
568=item 2. Overload C<setup()>
569
570Overload the C<setup()> method and set up some resource hooks with the
571C<resourceHooks()> method.  Hooks are mappings of the form:
572
573            REGEX => handler
574
575where handler is either a method name, a code reference, an object which
576supports a method with the same name as the HTTP method (or C<getResource> if
577no such method), or a reference to an array of the form: C<[$objectRef,
578"methodName"]> (C<$objectRef> can be a class name instead).
579
580The regular expressions are applied, by default, to the path info of the HTTP
581request.  Anything captured by parens in the regex will be passed into the
582handler as arguments.
583
584For example:
585
586    qr{/parts/(\d+)$} => "getPartByNumber",
587
588The above hook will call a method named C<getPartByNumber> on the current
589object (i.e. $self, an instance of L<REST::Application>) if the path info of
590the requested URI matches the above regular expression.  The first argument to
591the method will be the part number, since that's the first element captured in
592the regular expression.
593
594=item 3. Write code.
595
596Write the code for the handler specified above.  So here we'd define the
597C<getPartByNumber> method.
598
599=item 4. Create a handler/loader.
600
601Create an Apache handler, for example:
602
603    use MyRESTApp;
604    sub handler {
605        my $r = shift;
606        my $app = MyRESTApp->new(request => $r);
607        $app->run();
608    }
609
610or a small CGI script with the following code:
611
612    #!/usr/bin/perl
613    use MyRESTApp;
614    MyRESTApp->new()->run();
615
616In the second case, for a CGI script, you'll probably need to do something
617special to get Apache to load up your script unless you give it a .cgi
618extension.  It would be unRESTful to allow your script to have a .cgi
619extension, so you should go the extra mile and configure Apache to run your
620script without it.  For example, it'd be bad to have your users go to:
621
622    http://www.foo.tld/parts.cgi/12345.html
623
624=item 5. Call the C<run()> method.
625
626When the C<run()> method is called the path info is extracted from the HTTP
627request.  The regexes specified in step 2 are processed, in order, and if one
628matches then the handler is called.  If the regex had paren. matching then the
629matched elements are passed into the handler.  A handler is also passed a copy
630of the L<REST::Application> object instance (except for the case when the
631handler is a method on the L<REST::Application> object, in that case it'd be
632redundant).  So, when writing a subroutine handler you'd do:
633
634            sub rest_handler {
635                my ($rest, @capturedArgs) = @_;
636                ...
637            }
638
639=item 6. Return a representation of the resource.
640
641The handler is processed and should return a string or a scalar reference to a
642string.  Optionally the handler should set any header information via the
643C<header()> method on instance object pased in.
644
645=head1 CALLING ORDER
646
647The L<REST::Application> base class provides a good number of methods, each of
648which can be overloaded.  By default you only need to overload the C<setup()>
649method but you may wish to overload others.  To help with this the following
650outline is the calling order of the various methods in the base class.  You can
651find detailed descriptions of each method in the METHODS section of this
652document.
653
654If a method is followed by the string NOOP then that means it does nothing by
655default and it exists only to be overloaded.
656
657    new()
658        setup() - NOOP
659    run()
660        preRun() - NOOP
661        loadResource()
662            getMatchText()
663                getPathInfo()
664                    query()
665                        defaultQueryObject()
666            defaultResourceHandler() - NOOP
667            resourceHooks()
668            checkMatch()
669                _setLastRegexMatches()
670            _getHandlerFromHook()
671                resourceHooks()
672                defaultResourceHandler() - NOOP
673                getRequestMethod()
674                    query()
675                        defaultQueryObject()
676                bestContentType()
677                    simpleContentNegotiation
678                        getContentPrefs
679                            getAcceptHeader
680                        scoreType()
681            callHandler()
682                getHandlerArgs
683                    _getLastRegexMatches()
684                    extraHandlerArgs()
685                preHandler() - NOOP
686                ... your handler called here ...
687                postHandler() - NOOP
688        postRun() - NOOP
689        getHeaders()
690            headerType()
691            query()
692                defaultQueryObject()
693            header()
694        addRepresentation()
695
696The only methods not called as part of the new() or run() methods are the
697helper methods C<resetHeader()> and C<setRedirect()>, both of which call the
698C<header()> and C<headerType()> methods.
699
700For example, if you wanted to have your code branch on the entire URI of the
701HTTP request rather than just the path info you'd merely overload
702C<getMatchText()> to return the URI rather than the path info.
703
704=back
705
706=head1 METHODS
707
708=head2 new(%args)
709
710This method creates a new L<REST::Application> object and returns it.  The
711arguments passed in via C<%args>, if any, are passed untouched to the
712C<setup()> method.
713
714=head2 query([$newCGI])
715
716This accessor/mutator retrieves the current CGI query object or sets it if one
717is passed in.
718
719=head2 defaultQueryObject([$newCGI])
720
721This method retrieves/sets the default query object.  This method is called if
722C<query()> is called for the first time and no query object has been set yet.
723
724=head2 resourceHooks([%hash])
725
726This method is used to set the resource hooks.  A L<REST::Application> hook is
727a regex to handler mapping.  The hooks are passed in as a hash (or a reference
728to one) and the keys are treated as regular expressions while the values are
729treated as handlers should B<PATH_INFO> match the regex that maps to that
730handler.
731
732Handlers can be code references, methods on the current object, methods on
733other objects, or class methods.  Also, handlers can be differ based on what
734the B<REQUEST_METHOD> was (e.g. GET, PUT, POST, DELETE, etc).
735
736The handler's types are as follows:
737
738=over 8
739
740=item string
741
742The handler is considered to be a method on the current L<REST::Application>
743instance.
744
745=item code ref
746
747The code ref is considered to be the handler.
748
749=item object ref
750
751The object is considered to have a method the same name as the HTTP method.
752That is, if the object is being called because of GET then C<GET()> is called,
753if it is called because of a C<DELETE> then C<DELETE()> is called.
754C<getResource()> method will be used if C<getRequestMethod()> returns
755false.
756
757=item array ref
758
759The array is expected to be two elements long, the first element is a class
760name or object instance.  The 2nd element is a method name on that
761class/instance.  IF the 2nd element is ommitted then the method name is assumed
762to be the same as the B<REQUEST_METHOD>, e.g. C<GET()>, C<PUT()>, whatever.
763
764=item hash ref
765
766The current B<REQUEST_METHOD> is used as a key to the hash, the value should be
767one the four above handler types.  In this way you can specify different
768handlers for each of the request types.  The request method can also be
769specified as '*', in which case that is used if a more specific match is not
770found.
771
772It is possible for the value of the handler to be another hash ref, rather than
773one of the four above types.  In this case it is assumed content-negotion is
774wanted.  The keys of this second hash are MIME types and the values are one of
775the four above types.  For example:
776
777    $self->resourceHooks(
778        qr{/parts/(\d+)} => {
779            GET => {
780                'text/json' => 'get_json',
781                'text/xml', => 'get_xml',
782                'text/xml' => 'get_html',
783                '*/*' => 'get_html',
784            },
785            '*' => sub { die "Bad Method!" },
786        }
787    );
788
789=back
790
791The return value of the handler is expected to be a string, which
792L<REST::Application> will then send to the browser with the
793C<sendRepresentation()> method.
794
795If no argument is supplied to C<resourceHooks()> then the current set of hooks
796is returned.  The returned hash referces is a tied IxHash, so the keys are kept
797sorted.
798
799=head2 loadResource([$path])
800
801This method will take the value of B<PATH_INFO>, iterate through the path
802regex's set in C<resourceHooks()> and if it finds a match call the associated
803handler and return the handler's value, which should be a scalar.  If $path is
804passed in then that is used instead of B<PATH_INFO>.
805
806=head2 run()
807
808This method calls C<loadResource()> with no arguments and then takes that
809output and sends it to the remote client.  Headers are sent with
810C<sendHeaders()> and the representation is sent with C<sendRepresentation()>.
811
812If the environment variable B<REST_APP_RETURN_ONLY> is set then output isn't
813sent to the client.  The return value of this method is the text output it
814sends (or would've sent).
815
816=head2 sendHeaders()
817
818This method returns the headers as a string.
819
820=head2 sendRepresentation($representation)
821
822This method just returns C<$representation>.  It is provided soely for
823overloading purposes.
824
825=head2 headerType([$type])
826
827This accessor/mutator controls the type of header to be returned.  This method
828returns one of "header, redirect, or none."  If C<$type> is passed in then that
829is used to set the header type.
830
831=head2 header([%args])
832
833This accessor/mutator controls the header values sent.  If called without
834arguments then it simply returns the current header values as a hash, where the
835keys are the header fields and the values are the header field values.
836
837If this method is called multiple times then the values of %args are additive.
838So calling C<$self->header(-type => "text/html")> and C<$self->header(-foo =>
839"bar")> results in both the content-type header being set and the "foo" header
840being set.
841
842=head2 resetHeader()
843
844This header causes the current header values to be reset.  The previous values
845are returned.
846
847=head2 defaultResourceHandler()
848
849This method is called by C<loadResource()> if no regex in C<resourceHooks()>
850matches the current B<PATH_INFO>.  It returns undef by default, it exists for
851overloading.
852
853=head2 bestContentType(@types)
854
855Given a list of MIME types this function returns the best matching type
856considering the Accept header of the current request (as returned by
857C<getAcceptHeader()>.
858
859=head2 simpleContentNegotiation(@types)
860
861Given a list of MIME types this function returns the same list sorted from best
862match to least considering the Accept header as returned by
863C<getAcceptHeader()>.
864
865=head2 getContentPrefs()
866
867Returns the list of MIME types in the Accept header form most preferred to
868least preferred.  Quality weights are taken into account.
869
870=head2 getAcceptHeader()
871
872Returns the value of the Accept header as a single string.
873
874=head2 scoreType($type, @accept_types)
875
876Returns an integer, only good for sorting, for where C<$type> fits among the
877C<@accept_types>.  This method takes wildcards into account.  So C<text/plain>
878matches C<text/*>.  The integer returned is the position in C<@accept_types> of
879the matching MIME type.  It assumped @accept_types is already sorted from best
880to worst.
881
882=head2 getLastMatchPath()
883
884Returns the last path passed to C<checkMatch()> which successfully matched
885against.  Unless you're overloading things in funny ways the value returned
886will be the path that caused the current handler to be invoked.
887
888=head2 getLastMatchPattern()
889
890Similar to C<getLastMatchPath()> except this is the pattern that was applied to
891the path.
892
893=head2 getRequestMethod()
894
895This method tries to be smart and allow tunneling of the other HTTP methods
896over GET or PUT.  You can tunnel three ways with the higher up taking
897precedence:
898
8991) Pass an X-HTTP-Method header
9002) Pass the 'http_method' query parameter
9013) Pass a parameter via POST
902
903Only POST and GET, being the most common, can be used to tunnel.  In an attempt
904to prevent people from being bad, GET can only be used to tunnel GET or HEAD.
905POST can be used to tunnel anything.
906
907=head1 AUTHORS
908
909Matthew O'Connor E<lt>matthew@canonical.org<gt>
910
911=head1 LICENSE
912
913This program is free software. It is subject to the same license as Perl itself.
914
915=head1 SEE ALSO
916
917L<CGI>, L<CGI::Application>, L<Tie::IxHash>, L<CGI::Application::Dispatch>
918
919=cut
920