Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 139ae60d

Von Sven Schöling vor fast 4 Jahren hinzugefügt

  • ID 139ae60da570988695ae79b2a9f610b26b71d330
  • Vorgänger 4270e942
  • Nachfolger bce93dd4

SL::Response - neues response objekt

Unterschiede anzeigen:

SL/Response.pm
1
package SL::Response;
2

  
3
use strict;
4
use parent qw(Rose::Object);
5
use Carp;
6
use SL::MoreCommon qw(listify);
7

  
8
use Rose::Object::MakeMethods::Generic (
9
  scalar                  => [ qw(status location content_type) ],
10
  'scalar --get_set_init' => [ qw(cookie) ],
11
);
12

  
13
my %status_codes = (
14
  200 => 'OK',
15
  201 => 'Created',
16
  202 => 'Accepted',
17
  302 => 'Found',
18
  303 => 'See Other',
19
  307 => 'Temporary Redirect',
20
  401 => 'Unauthorized',
21
  403 => 'Forbidden',
22
  404 => 'Not Found',
23
  418 => "I'm a teapot",
24
);
25

  
26
my %supported_generic_header_fields = (
27
  charset             => 'Charset',
28
  content_length      => 'Content-Length',
29
  transfer_encoding   => 'Transfer-Encoding',
30
  connection          => 'Connection',
31
);
32

  
33
my %cookie_args = (
34
  domain    => 1,
35
  path      => 1,
36
  expires   => 1,
37
  "max-age" => 1,
38
  secure    => 0,
39
  HttpOnly  => 0,
40
);
41

  
42
my $crlf = "\015\012";
43

  
44
sub header {
45
  my ($self, %header) = @_;
46

  
47
  my @header;
48

  
49
  # these three must come first
50
  my $content_type = delete $header{content_type} // $self->content_type;
51
  push @header, "Content-Type: $content_type" if defined $content_type;
52

  
53
  my $status = delete $header{status} // $self->status;
54
  croak "Unsupported HTTP Status: $status" if defined $status && !$status_codes{$status};
55
  push @header, "Status: $status $status_codes{$status}" if defined $status;
56

  
57
  my $location = delete $header{location} // $self->location;
58
  push @header, "Location: $location" if defined $location;
59

  
60
  # handle more than one cookie
61
  my @cookies = (listify(delete $header{cookie}), listify($self->cookie));
62
  push @header, "Set-Cookie: $_" for @cookies;
63

  
64
  # content-disposition has some weird syntax from RFC1806
65
  my $attachment = delete $header{attachment};
66
  push @header, qq|Content-Disposition: attachment; filename="$attachment"| if defined $attachment;
67

  
68
  # process the rest
69
  for my $field (keys %header) {
70
    my $keyword = $supported_generic_header_fields{$field} or croak "unknown header '$field'";
71
    push @header, "$keyword: $header{$field}";
72
  }
73

  
74
  return join $crlf, @header, '', '';
75
}
76

  
77
sub redirect {
78
  my ($self, $url, %params) = @_;
79
  $self->header(%params, status => 302, location => $url);
80
}
81

  
82
sub add_cookie {
83
  my ($self, $name, $value, %args) = @_;
84

  
85
  # we don't care that cookies can have more than one value. if you need it, implement it.
86
  # we also don't care that technically you have to url encode cookies. simply don't put unicode in cookies.
87

  
88
  my @cookie = "$name=$value";
89

  
90
  for (keys %args) {
91
    my $need_argument = $cookie_args{$_};
92
    croak "unknown cookie argument '$_'" unless defined $need_argument;
93
    push @cookie, $need_argument ? "$_=$args{$_}" : (($_) x !!$args{$_});
94
  }
95

  
96
  push @{ $self->{cookie} //= [] }, join '; ', @cookie;
97
}
98

  
99
sub init_cookie { [] }
100

  
101
1;
102

  
103
__END__
104

  
105
=encoding utf-8
106

  
107
=head1 NAME
108

  
109
SL::Response - reponse helper and aggregator
110

  
111
=head1 SYNOPSIS
112

  
113
  use SL::Response;
114
  my $r = SL::Respone->new
115

  
116
  $r->add_cookie("name", "value", secure => 1, path => $path);
117
  $r->redirect($url);
118
  $r->header(
119
    content_type => 'text/html',
120
    charset      => 'UTF-8',
121
    ...
122
  );
123

  
124
  $r->content_type('text/json');
125
  $r->status(502);
126
  $r->header;
127

  
128
=head1 DESCRIPTION
129

  
130
Introduced mainly to get rid of L<CGI.pm>. Also meant to abstract response
131
header generation, and one day maybe be able to handle all STDOUT printing.
132
After that we can add more bindings to PSGI or a standalone server.
133

  
134
=head1 ATTRIBUTES
135

  
136
=over 4
137

  
138
=item * C<status>
139

  
140
=item * C<location>
141

  
142
=item * C<content_type>
143

  
144
These three are used for the upcoming response and can be set beforehand.
145

  
146
=item * C<cookie>
147

  
148
Aggregator for cookies. Returns an arrayref. Should be filled with
149
L</add_cookie>. Aggregated cookies will be added to all generated headers,
150
including redirects.
151

  
152
=back
153

  
154
=head1 METHODS
155

  
156
=over 4
157

  
158
=item * C<header PARAMS>
159

  
160
Generates a header and returns it as octet stream.
161

  
162
Known arguments:
163

  
164
=over 4
165

  
166
=item * C<content_type>
167

  
168
Corresponds to C<Content-Type>
169

  
170
=item * C<status>
171

  
172
Corresponds to C<Status>
173

  
174
=item * C<location>
175

  
176
Corresponds to C<Location>
177

  
178
=item * C<cookie>
179

  
180
Corresponds to C<Set-Cookie>. Can be arrayref or single value but must contain
181
valid arguments for the HTTP C<Set-Cookie> header. If cookies have been added
182
to the response object before, both will be added.
183

  
184
=item * C<attachment>
185

  
186
Corresponds to C<Content-Disposition: attachemnt>. The argument will be added as the filename.
187

  
188
=item * C<charset>
189

  
190
Corresponds to C<Charset>
191

  
192
=item * C<content_length>
193

  
194
Corresponds to C<Content-Length>
195

  
196
=item * C<transfer_encoding>
197

  
198
Corresponds to C<Transfer-Encoding>
199

  
200
=item * C<connection>
201

  
202
Corresponds to C<Connection>
203

  
204
=back
205

  
206
=item * C<redirect URL PARAMS>
207

  
208
Calls header with status code 302 and the location specified by the C<url>
209
parameter.
210

  
211
=item * C<add_cookie PARAMS>
212

  
213
=back
214

  
215
=head1 BUGS
216

  
217
None yet :)
218

  
219
=head1 AUTHOR
220

  
221
Sven Schöling E<lt>s.schoeling@googlemail.comE<gt>
222

  
223
=cut

Auch abrufbar als: Unified diff