Apache2-API

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

    "-head"
        HEAD url

    "-header"
        add headers to (get|post|head) request

    "-help"
        display this message

    "-http11"
        run all tests with "HTTP/1.1" (keep alive) requests

    "-no-httpd"
        run the tests without configuring or starting httpd

    "-one-process"
        run the server in single process mode

    "-order=mode"
        run the tests in one of the modes: (repeat|random|SEED)

README.md  view on Meta::CPAN

- `-header`

    add headers to (get|post|head) request

- `-help`

    display this message

- `-http11`

    run all tests with `HTTP/1.1` (keep alive) requests

- `-no-httpd`

    run the tests without configuring or starting httpd

- `-one-process`

    run the server in single process mode

- `-order=mode`

lib/Apache2/API.pm  view on Meta::CPAN

BEGIN
{
    use strict;
    use warnings;
    use warnings::register;
    use parent qw( Module::Generic );
    use vars qw( $VERSION $DEBUG @EXPORT $USE_RFC_ERROR );
    use version;
    use Encode ();
    # use Apache2::Const qw( :common :http );
    use Apache2::Const -compile => qw( :cmd_how :common :config :conn_keepalive :context :filter_type :http :input_mode :log :methods :mpmq :options :override :platform :remotehost :satisfy :types :proxy );
    use APR::Const -compile => qw( :common :error :fopen :filepath :fprot :filetype :finfo :flock :hook :limit :lockmech :poll :read_type :shutdown_how :socket :status :table :uri );
    use Apache2::RequestRec ();
    use Apache2::RequestIO ();
    use Apache2::ServerUtil ();
    use Apache2::RequestUtil ();
    use Apache2::Response ();
    use Apache2::Log ();
    use Apache2::API::Request;
    use Apache2::API::Response;
    use Apache2::API::Status;

lib/Apache2/API.pm  view on Meta::CPAN

=item C<-header>

add headers to (get|post|head) request

=item C<-help>

display this message

=item C<-http11>

run all tests with C<HTTP/1.1> (keep alive) requests

=item C<-no-httpd>

run the tests without configuring or starting httpd

=item C<-one-process>

run the server in single process mode

=item C<-order=mode>

lib/Apache2/API/Request.pm  view on Meta::CPAN

sub auth_headers_digest { return( shift->_try( 'request', 'note_digest_auth_failure', @_ ) ); }

sub auth_name { return( shift->_try( 'request', 'auth_name', @_ ) ); }

# with mod_perl2, we need to call ap_auth_type() rather than auth_type()
sub auth_type { return( shift->_try( 'request', 'ap_auth_type', @_ ) ); }

sub authorization { return( shift->headers( 'Authorization', @_ ) ); }

# Must manually update the counter
# $r->connection->keepalives($r->connection->keepalives + 1);
# See Apache2::RequestRec
sub auto_header 
{
    my $self = shift( @_ );
    if( @_ )
    {
        my $v = shift( @_ );
        return( $self->request->assbackwards( $v ? 0 : 1 ) );
    }
    return( $self->request->assbackwards );

lib/Apache2/API/Request.pm  view on Meta::CPAN

        $ref = $j->can( exists( $equi->{ $opt } ) ? $equi->{ $opt } : $opt ) || do
        {
            warn( "Unknown JSON option '${opt}'\n" ) if( $self->_warnings_is_enabled );
            next;
        };
        $ref->( $j, $opts->{ $opt } );
    }
    return( $j );
}

sub keepalive { return( shift->_try( 'connection', 'keepalive', @_ ) ); }

sub keepalives { return( shift->_try( 'connection', 'keepalives', @_ ) ); }

sub languages
{
    my $self = shift( @_ );
    my $lang = $self->accept_language || return( [] );
    my $al = HTTP::AcceptLanguage->new( $lang );
    my( @langs ) = $al->languages;
    return( $self->new_array( \@langs ) );
}

lib/Apache2/API/Request.pm  view on Meta::CPAN

    my $filters = $req->input_filters;

    my $bool = $req->is_aborted;

    my $enabled = $req->is_perl_option_enabled;
    # running under https?
    my $secure = $req->is_secure;

    # JSON object
    my $json = $req->json;
    my $keepalive = $req->keepalive;
    my $keepalives = $req->keepalives;

    my $ok_languages = $req->languages;
    my $nbytes = $req->length;
    # APR::SockAddr object
    my $addr = $req->local_addr;
    my $host = $req->local_host;
    my $str = $req->local_ip;
    my $loc = $req->location;
    $req->log_error( "Oh no!" );

lib/Apache2/API/Request.pm  view on Meta::CPAN

Returns the authentication type by calling L<Apache2::RequestRec/auth_type>

    my $auth_type = $req->auth_type; # Basic

=head2 auto_header

Given a boolean value, this enables the auto header or not by calling the method L<Apache2::RequestRec/assbackwards>

If this is disabled, you need to make sure to manually update the counter, such as:

    $req->connection->keepalives( $req->connection->keepalives + 1 );

See L<Apache2::RequestRec> for more information on this.

=head2 basic_auth_passwd

    my( $rc, $passwd ) = $req->basic_auth_passwd;

Get the details from the basic authentication, by calling L<Apache2::Access/get_basic_auth_pw>

It returns:

lib/Apache2/API/Request.pm  view on Meta::CPAN

Returns a L<JSON> object with the C<relaxed> attribute enabled so that it allows more relaxed C<JSON> data.

You can provide an optional hash or hash reference of properties to enable or disable:

    my $J = $api->json( pretty => 1, relaxed => 1 );

Each property corresponds to one that is supported by L<JSON>

It also supports C<ordered>, C<order> and C<sort> as an alias to C<canonical>

=head2 keepalive

    $status = $c->keepalive();
    $status = $c->keepalive($new_status);

This method answers the question: Should the the connection be kept alive for another HTTP request after the current request is completed?

This sets or gets the status by calling L<Apache2::Connection/keepalive>

     use Apache2::Const -compile => qw(:conn_keepalive);
     # ...
     my $c = $req->connection;
     if ($c->keepalive == Apache2::Const::CONN_KEEPALIVE) {
         # do something
     }
     elsif ($c->keepalive == Apache2::Const::CONN_CLOSE) {
         # do something else
     }
     elsif ($c->keepalive == Apache2::Const::CONN_UNKNOWN) {
         # do yet something else
     }
     else {
         # die "unknown state";
     }

Notice that new states could be added later by Apache, so your code should make no assumptions and do things only if the desired state matches.

The method does not return true or false, but one of the states which can be compared against Apache constants (C<:conn_keepalive constants>).

See L<Apache2::Connection> for more information.

=head2 keepalives

    my $served = $req->connection->keepalives();
    my $served = $req->connection->keepalives( $new_served );

This returns an integer representing how many requests were already served over the current connection.

This method calls L<Apache2::Connection/keepalives>

This method is only relevant for keepalive connections. The core connection output filter C<ap_http_header_filter> increments this value when the response headers are sent and it decides that the connection should not be closed (see "ap_set_keepalive...

If you send your own set of HTTP headers with C<< $req->assbackwards >>, which includes the C<Keep-Alive> HTTP response header, you must make sure to increment the C<keepalives> counter.

See L<Apache2::Connection> for more information.

=head2 languages

This will check the C<Accept-Languages> HTTP headers and derive a list of priority ordered user preferred languages and return an L<array object|Module::Generic::Array>.

See also the L</preferred_language> method.

=head2 length

lib/Apache2/API/Response.pm  view on Meta::CPAN


sub is_redirect     { return( Apache2::API::Status->is_redirect( $_[1] ) ); }

sub is_error        { return( Apache2::API::Status->is_error( $_[1] ) ); }

sub is_client_error { return( Apache2::API::Status->is_client_error( $_[1] ) ); }

sub is_server_error { return( Apache2::API::Status->is_server_error( $_[1] ) ); }

# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive>
sub keep_alive { return( shift->_set_get_one( 'Keep-Alive', @_ ) ); }

# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified>
sub last_modified { return( shift->_set_get_one( 'Last-Modified', @_ ) ); }

sub last_modified_date { return( shift->headers( 'Last-Modified-Date', @_ ) ); }

# Number of bytes sent
sub length { return( shift->_try( 'request', 'bytes_sent' ) ); }

# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location>

lib/Apache2/API/Response.pm  view on Meta::CPAN

sub server_timing { return( shift->_set_get_one( 'Server-Timing', @_ ) ); }

# e.g set_content_length( 1024 )
sub set_content_length { return( shift->_try( '_request', 'set_content_length', @_ ) ); }

# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie>
sub set_cookie { return( shift->_set_get_one( 'Set-Cookie', @_ ) ); }

sub set_etag { return( shift->_try( '_request', 'set_etag', @_ ) ); }

sub set_keepalive { return( shift->_try( '_request', 'set_keepalive', @_ ) ); }

# <https://perl.apache.org/docs/2.0/api/Apache2/Response.html#toc_C_set_last_modified_>
sub set_last_modified { return( shift->_try( '_request', 'set_last_modified', @_ ) ); }

# Returns a APR::Socket
# See Apache2::Connection manual page
sub socket { return( shift->_try( 'connection', 'client_socket', @_ ) ); }

# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/SourceMap>
sub sourcemap { return( shift->_set_get_one( 'SourceMap', @_ ) ); }

lib/Apache2/API/Response.pm  view on Meta::CPAN

    my $headers = $resp->headers_out;
    $resp->internal_redirect( $uri );
    $resp->internal_redirect_handler( $uri );
    my $rv = $resp->is_info(100);
    my $rv = $resp->is_success(200);
    my $rv = $resp->is_redirect(302);
    my $rv = $resp->is_error(400);
    my $rv = $resp->is_client_error(401);
    my $rv = $resp->is_server_error(500);
    # Keep-Alive
    my $keep_alive = $resp->keep_alive;
    # Last-Modified
    my $http_date = $resp->last_modified;
    # Last-Modified-Date
    my $http_date = $resp->last_modified_date;
    # The number of bytes sent. Actually calls bytes_sent()
    my $nbytes = $resp->length;
    # Location
    my $loc = $resp->location;
    my $rv = $resp->lookup_uri( $uri );
    my $etag = $resp->make_etag( $force_weak );

lib/Apache2/API/Response.pm  view on Meta::CPAN

    $resp->send_cgi_header;
    $resp->sendfile( $filename, $offset, $len );
    $resp->sendfile( $filename );
    # Server
    my $server = $resp->server;
    my $server_timing = $resp->server_timing;
    $resp->set_content_length(1024);
    # Set-Cookie
    $resp->set_cookie( $cookie );
    $resp->set_last_modified;
    $resp->set_keepalive(1);
    my $socket = $resp->socket;
    my $sourcemap = $resp->sourcemap;
    my $status = $resp->status;
    my $status_line = $resp->status_line;
    # Strict-Transport-Security
    my $policy = $resp->strict_transport_security;
    # APR::Table object
    my $env = $resp->subprocess_env;
    # Timing-Allow-Origin
    my $origin = $resp->timing_allow_origin;

lib/Apache2/API/Response.pm  view on Meta::CPAN

Given a HTTP code integer, this will return true if the code is comprised between C<400> and less than C<600>, false otherwise.

=head2 is_client_error

Given a HTTP code integer, this will return true if the code is comprised between C<400> and less than C<500>, false otherwise.

=head2 is_server_error

Given a HTTP code integer, this will return true if the code is comprised between C<500> and less than C<600>, false otherwise.

=head2 keep_alive

Sets or gets the HTTP header field C<Keep-Alive>

See L<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive>

=head2 last_modified

Sets or gets the HTTP header field C<Last-Modified>

See L<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified>

lib/Apache2/API/Response.pm  view on Meta::CPAN

See L<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie>

=head2 set_etag

    $resp->set_etag;

Set automatically the C<E-tag> outgoing header.

It does not return any value.

=head2 set_keepalive

    $ret = $resp->set_keepalive;

Returns the keepalive status for this request, by calling L<Apache2::Response/set_keepalive>

It returns true if keepalive can be set, false otherwise.

=head2 set_last_modified

Sets the C<Last-Modified> response header field to the value of the mtime field in the request structure, rationalized to keep it from being in the future, by calling L<Apache2::Response/set_last_modified>

    $resp->set_last_modified( $mtime );

If the C<$mtime> argument is passed, C<< $resp->update_mtime >> will be first run with that argument.

=head2 socket

lib/Apache2/API/Status.pm  view on Meta::CPAN


See L<rfc7231, section 6.3.1|https://datatracker.ietf.org/doc/html/rfc7231#section-6.3.1>

This is returned to inform the request has succeeded. It can also alternatively be C<204 No Content> when there is no response body.

For example:

    HTTP/1.1 200 OK
    Content-Type: text/html; charset=utf-8
    Content-Length: 184
    Connection: keep-alive
    Cache-Control: s-maxage=300, public, max-age=0
    Content-Language: en-US
    Date: Mon, 18 Apr 2022 17:37:18 GMT
    ETag: "2e77ad1dc6ab0b53a2996dfd4653c1c3"
    Server: Apache/2.4
    Strict-Transport-Security: max-age=63072000
    X-Content-Type-Options: nosniff
    X-Frame-Options: DENY
    X-XSS-Protection: 1; mode=block
    Vary: Accept-Encoding,Cookie

t/01.api.t  view on Meta::CPAN

        $mp_host = 'www.example.org';
        our @ua_args = (
            agent           => 'Test-Apache2-API/' . $VERSION,
            cookie_jar      => {},
            default_headers => HTTP::Headers->new(
                Host            => "${mp_host}:${port}",
                Accept          => 'application/json; version=1.0; charset=utf-8, text/javascript, */*',
                Accept_Encoding => 'gzip, deflate, br',
                Accept_Language => 'en-GB,fr-FR;q=0.8,fr;q=0.6,ja;q=0.4,en;q=0.2',
            ),
            keep_alive      => 1,
        );
        Apache::TestRequest::user_agent( @ua_args, reset => 1 );
        $ua = Apache::TestRequest->new( @ua_args );
        # To get the fingerprint for the certificate in ./t/server.crt, do:
        # echo "sha1\$$(openssl x509 -noout -in ./t/server.crt -fingerprint -sha1|perl -pE 's/^.*Fingerprint=|(\w{2})(?:\:?|$)/$1/g')"
        $ua->ssl_opts(
            # SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE, 
            # SSL_verify_mode => 0x00
            # verify_hostname => 0,
            SSL_fingerprint => 'sha1$DEE8650E44870896E821AAE4A5A24382174D100E',

t/lib/Test/Apache2/API.pm  view on Meta::CPAN


In the test unit:

    use Apache::Test;
    use Apache::TestRequest;
    use HTTP::Request;

    my $hostport = Apache::TestRequest::hostport( $config ) || '';
    my( $host, $port ) = split( ':', ( $hostport ) );
    my $mp_host = 'www.example.org';
    Apache::TestRequest::user_agent(reset => 1, keep_alive => 1 );
    my $ua = Apache::TestRequest->new;
    # To get the fingerprint for the certificate in ./t/server.crt, do:
    # echo "sha1\$$(openssl x509 -noout -in ./t/server.crt -fingerprint -sha1|perl -pE 's/^.*Fingerprint=|(\w{2})(?:\:?|$)/$1/g')"
    $ua->ssl_opts(
        # SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE, 
        # SSL_verify_mode => 0x00
        # verify_hostname => 0,
        SSL_fingerprint => 'sha1$DEE8650E44870896E821AAE4A5A24382174D100E',
        # SSL_version     => 'SSLv3',
        # SSL_verfifycn_name => 'localhost',

t/lib/Test/Apache2/API/Request.pm  view on Meta::CPAN


=head1 NAME

Test::Apache2::API::Request - Apache2::API::Request Testing Class

=head1 SYNOPSIS

    my $hostport = Apache::TestRequest::hostport( $config ) || '';
    my( $host, $port ) = split( ':', ( $hostport ) );
    my $mp_host = 'www.example.org';
    Apache::TestRequest::user_agent(reset => 1, keep_alive => 1 );
    my $ua = Apache::TestRequest->new;
    # To get the fingerprint for the certificate in ./t/server.crt, do:
    # echo "sha1\$$(openssl x509 -noout -in ./t/server.crt -fingerprint -sha1|perl -pE 's/^.*Fingerprint=|(\w{2})(?:\:?|$)/$1/g')"
    $ua->ssl_opts(
        # SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE, 
        # SSL_verify_mode => 0x00
        # verify_hostname => 0,
        SSL_fingerprint => 'sha1$DEE8650E44870896E821AAE4A5A24382174D100E',
        # SSL_version     => 'SSLv3',
        # SSL_verfifycn_name => 'localhost',

t/lib/Test/Apache2/API/Response.pm  view on Meta::CPAN

sub headers_out { return( shift->_test({ method => 'headers_out', expect => 'APR::Table', type => 'isa' }) ); }

# internal_redirect
# internal_redirect_handler
# is_info
# is_success
# is_redirect
# is_error
# is_client_error
# is_server_error
# keep_alive
# last_modified
# last_modified_date
# location
# lookup_uri

# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag>
sub make_etag { return( shift->_test({ method => 'make_etag', expect => sub
{
    my $val = shift( @_ );
    # "5fd7520368c40"

t/lib/Test/Apache2/API/Response.pm  view on Meta::CPAN

# rflush
# send_cgi_header

sub sendfile { return( shift->_test({ method => 'sendfile', expect => APR::Const::SUCCESS, args => [__FILE__] }) ); }

# server
# server_timing
# set_content_length
# set_cookie
# set_etag
# set_keepalive

# 2021-11-1T167:12:10+0900
sub set_last_modified { return( shift->_test({ method => 'set_last_modified', expect => sub
{
    return(1);
}, args => [1635754330] }) ); }

sub socket { return( shift->_test({ method => 'socket', expect => 'APR::Socket', type => 'isa' }) ); }

# sourcemap

t/lib/Test/Apache2/API/Response.pm  view on Meta::CPAN


=head1 NAME

Test::Apache2::API::Response - Apache2::API::Response Testing Class

=head1 SYNOPSIS

    my $hostport = Apache::TestRequest::hostport( $config ) || '';
    my( $host, $port ) = split( ':', ( $hostport ) );
    my $mp_host = 'www.example.org';
    Apache::TestRequest::user_agent(reset => 1, keep_alive => 1 );
    my $ua = Apache::TestRequest->new;
    # To get the fingerprint for the certificate in ./t/server.crt, do:
    # echo "sha1\$$(openssl x509 -noout -in ./t/server.crt -fingerprint -sha1|perl -pE 's/^.*Fingerprint=|(\w{2})(?:\:?|$)/$1/g')"
    $ua->ssl_opts(
        # SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE, 
        # SSL_verify_mode => 0x00
        # verify_hostname => 0,
        SSL_fingerprint => 'sha1$DEE8650E44870896E821AAE4A5A24382174D100E',
        # SSL_version     => 'SSLv3',
        # SSL_verfifycn_name => 'localhost',



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