/
PSGI.pm
127 lines (89 loc) · 2.41 KB
/
PSGI.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
# Copyright (C) 2008-2009, Sebastian Riedel.
package Mojo::Server::PSGI;
use strict;
use warnings;
use base 'Mojo::Server';
use bytes;
use constant CHUNK_SIZE => $ENV{MOJO_CHUNK_SIZE} || 4096;
# Things aren't as happy as they used to be down here at the unemployment
# office.
# Joblessness is no longer just for philosophy majors.
# Useful people are starting to feel the pinch.
sub run {
my ($self, $env) = @_;
my $tx = $self->build_tx_cb->($self);
my $req = $tx->req;
# Environment
$req->parse($env);
# Store connection information
$tx->remote_address($env->{REMOTE_ADDR});
$tx->local_port($env->{SERVER_PORT});
# Request body
while (!$req->is_finished) {
my $read = $env->{'psgi.input'}->read(my $buffer, CHUNK_SIZE, 0);
last if $read == 0;
$req->parse($buffer);
}
# Handle
$self->handler_cb->($self, $tx);
my $res = $tx->res;
# Status
my $status = $res->code;
# Response headers
$res->fix_headers;
my $headers = $res->content->headers;
my @headers;
for my $name (@{$headers->names}) {
for my $value ($headers->header($name)) {
push @headers, $name => $value;
}
}
# Response body
my $body = Mojo::Server::PSGI::Handle->new(res => $res);
return [$status, \@headers, $body];
}
package Mojo::Server::PSGI::Handle;
use strict;
use warnings;
use base 'Mojo::Base';
__PACKAGE__->attr(offset => 0);
__PACKAGE__->attr('res');
sub close { }
sub getline {
my $self = shift;
# Blocking read
my $offset = $self->offset;
while (1) {
my $chunk = $self->res->get_body_chunk($offset);
# No content yet, try again
unless (defined $chunk) {
sleep 1;
next;
}
# End of content
last unless length $chunk;
# Content
$offset += length $chunk;
$self->offset($offset);
return $chunk;
}
return;
}
1;
__END__
=head1 NAME
Mojo::Server::PSGI - PSGI Server
=head1 SYNOPSIS
# myapp.psgi
use Mojo::Server::PSGI;
my $psgi = Mojo::Server::PSGI->new->app_class('MyApp');
my $app = sub { $psgi->run(@_) };
=head1 DESCRIPTION
L<Mojo::Server::PSGI> allows L<Mojo> applications to run on all PSGI
compatible servers.
=head1 METHODS
L<Mojo::Server::PSGI> inherits all methods from L<Mojo::Server> and
implements the following new ones.
=head2 C<run>
$psgi->run;
=cut