File Coverage

blib/lib/PAGI/Middleware/Session/State/Callback.pm
Criterion Covered Total %
statement 19 23 82.6
branch 6 8 75.0
condition n/a
subroutine 6 7 85.7
pod 4 4 100.0
total 35 42 83.3


line stmt bran cond sub pod time code
1             package PAGI::Middleware::Session::State::Callback;
2              
3 1     1   155512 use strict;
  1         2  
  1         27  
4 1     1   4 use warnings;
  1         1  
  1         40  
5 1     1   369 use parent 'PAGI::Middleware::Session::State';
  1         246  
  1         6  
6              
7             =head1 NAME
8              
9             PAGI::Middleware::Session::State::Callback - Custom coderef-based session ID transport
10              
11             =head1 SYNOPSIS
12              
13             use PAGI::Middleware::Session::State::Callback;
14              
15             my $state = PAGI::Middleware::Session::State::Callback->new(
16             extract => sub {
17             my ($scope) = @_;
18             # Return session ID or undef
19             return $scope->{headers}[0][1];
20             },
21             inject => sub {
22             my ($headers, $id, $options) = @_;
23             push @$headers, ['X-Session-ID', $id];
24             },
25             );
26              
27             # Extract session ID from request
28             my $id = $state->extract($scope);
29              
30             =head1 DESCRIPTION
31              
32             Implements the L interface using custom
33             coderefs for session ID extraction and injection. This allows callers to
34             define arbitrary session ID transport without writing a subclass.
35              
36             =head1 CONFIGURATION
37              
38             =over 4
39              
40             =item * extract (required)
41              
42             A coderef that receives C<($scope)> and returns the session ID or undef.
43              
44             =item * inject (optional)
45              
46             A coderef that receives C<(\@headers, $id, \%options)> and modifies the
47             response headers. Defaults to a no-op if not provided.
48              
49             =item * clear (optional)
50              
51             A coderef that receives C<(\@headers)> and clears the client-side
52             session state. Called when a session is destroyed. Defaults to a
53             no-op if not provided.
54              
55             =back
56              
57             =cut
58              
59             sub new {
60 10     10 1 180817 my ($class, %options) = @_;
61              
62             die "extract is required for $class"
63 10 100       31 unless defined $options{extract};
64             die "extract must be a CODE ref for $class"
65 9 100       58 unless ref($options{extract}) eq 'CODE';
66              
67 6         22 return $class->SUPER::new(%options);
68             }
69              
70             =head2 extract
71              
72             my $session_id = $state->extract($scope);
73              
74             Calls the configured C coderef with C<$scope> and returns
75             its result.
76              
77             =cut
78              
79             sub extract {
80 3     3 1 19 my ($self, $scope) = @_;
81              
82 3         9 return $self->{extract}->($scope);
83             }
84              
85             =head2 inject
86              
87             $state->inject(\@headers, $id, \%options);
88              
89             Calls the configured C coderef with C<(\@headers, $id, \%options)>
90             if one was provided. Otherwise does nothing.
91              
92             =cut
93              
94             sub inject {
95 3     3 1 23 my ($self, $headers, $id, $options) = @_;
96              
97 3 100       6 if ($self->{inject}) {
98 2         5 $self->{inject}->($headers, $id, $options);
99             }
100              
101 3         8 return;
102             }
103              
104             =head2 clear
105              
106             $state->clear(\@headers);
107              
108             Calls the configured C coderef with C<(\@headers)> if one was
109             provided. Otherwise does nothing.
110              
111             =cut
112              
113             sub clear {
114 0     0 1   my ($self, $headers) = @_;
115              
116 0 0         if ($self->{clear}) {
117 0           return $self->{clear}->($headers);
118             }
119              
120 0           return;
121             }
122              
123             1;
124              
125             __END__