forked from stash/Feersum
/
Connection.pm
129 lines (94 loc) · 3.57 KB
/
Connection.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package Feersum::Connection;
use strict;
sub new {
Carp::croak "Cannot instantiate Feersum::Connection directly";
}
sub send_response {
# my ($self, $msg, $hdrs, $body) = @_;
$_[0]->start_response($_[1], $_[2], 0);
$_[0]->write_whole_body(ref($_[3]) ? $_[3] : \$_[3]);
}
sub initiate_streaming {
my $self = shift;
my $streamer = shift;
Carp::croak "Feersum: Expected coderef"
unless ref($streamer) eq 'CODE';
@_ = (sub {
$self->start_response($_[0],$_[1],1);
return $self->write_handle;
});
goto &$streamer;
}
sub _initiate_streaming_psgi {
my ($self, $streamer) = @_;
@_ = (sub {
my $strm = shift;
if ($#$strm == 2) {
$self->start_response($strm->[0],$strm->[1],0);
$self->write_whole_body(ref($strm->[2]) ? $strm->[2] : \$strm->[2]);
}
elsif ($#$strm == 1) {
$self->start_response($strm->[0],$strm->[1],1);
return $self->write_handle;
}
else {
die "streaming responder expected array";
}
return;
});
goto &$streamer;
}
1;
__END__
=head1 NAME
Feersum::Connection - HTTP connection encapsulation
=head1 SYNOPSIS
Feersum->endjinn->request_handler(sub {
my $req = shift; # this is a Feersum::Connection object
my %env;
$req->env(\%env);
$req->start_response(200, ['Content-Type' => 'text/plain'], 0);
$req->write_whole_body(\"Ergrates FTW.");
});
=head1 DESCRIPTION
Encapsulates an HTTP connection to Feersum. It's roughly analagous to an
C<Apache::Request> or C<Apache2::Connection> object, but differs significantly
in functionality. Until Keep-Alive functionality is supported (if ever) this
means that a connection is B<also> a request.
=head1 METHODS
=over 4
=item C<< $o->start_response($code, \@headers, $streaming) >>
Begin responding.
If C<$streaming> is false, a partial HTTP response is sent. The partial
response is missing the Content-Length header, which will be sent when
C<write_whole_body> is called.
If C<$streaming> is true, a full HTTP header section is sent with
"Transfer-Encoding: chunked" instead of a Content-Length. The C<write_handle>
method or the C<write_whole_body> method should be used to complete the
response.
=item C<< $o->write_whole_body($data) >>
=item C<< $o->write_whole_body(\$data) >>
=item C<< $o->write_whole_body(\@chunks) >>
Emits the parameter(s) as the response body and closes the request.
References to scalars are supported (and are much faster than passing arround
scalars).
=item C<< $o->send_response($code, \@headers, ....) >>
Convenience macro. Is equivalent to start_response with a streaming parameter
of 0 followed by a call to write_whole_body.
=item C<< $w = $o->write_handle; >>
Returns a L<Feersum::Connection::Handle> in Writer mode for this request.
Must only be used when the connection has been put into streaming mode.
=item C<< $o->initiate_streaming(sub { .... }) >>
For support of the C<psgi.streaming> feature, takes a sub (which is
immediately called). The sub is, in turn, passed a code reference. The code
reference will return a Writer object when called with C<< $code, \@header >>
parameters. See L<Feersum> for examples.
=back
=head1 AUTHOR
Jeremy Stashewsky, C<< stash@cpan.org >>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2010 by Jeremy Stashewsky & Socialtext Inc.
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.7 or,
at your option, any later version of Perl 5 you may have available.
=cut