Gepok

 view release on metacpan or  search on metacpan

lib/Gepok.pm  view on Meta::CPAN

# run PSGI app, send PSGI response to client as HTTP response, and return it
sub _handle_psgi {
    my ($self, $req, $sock) = @_;

    my $env = $self->_prepare_env($req, $sock);

    # cache first before socket closes
    $self->{_sock_peerhost} = $env->{REMOTE_ADDR};

    my $res = Plack::Util::run_app($self->_app, $env);

    # trap i/o error when sending response
    eval {
        if (ref($res) eq 'CODE') {
            $res->(sub { $self->_finalize_response($env, $_[0], $sock) });
        } else {
            $self->_finalize_response($env, $res, $sock);
        }
    };

    $res;
}

# prepare PSGI env
sub _prepare_env {
    my ($self, $req, $sock) = @_;

    my $httpd   = ${*$sock}{httpd_daemon};
    my $is_unix = $httpd->isa('HTTP::Daemon::UNIX');
    my $is_ssl  = $httpd->isa('HTTP::Daemon::SSL');
    my $uri = $req->uri->as_string;
    my ($qs, $pi);
    if ($uri =~ /(.*)\?(.*)/) {
        $pi = $1;
        $qs = $2;
    } else {
        $pi = $uri;
        $qs = "";
    }
    $pi = uri_unescape($pi);

    #warn "uri=$uri, qs=$qs\n";
    my $env = {
        REQUEST_METHOD  => $req->method,
        SCRIPT_NAME     => '',
        PATH_INFO       => $pi,
        REQUEST_URI     => $uri,
        QUERY_STRING    => $qs,
        SERVER_PORT     => $is_unix ? 0 : $httpd->sockport,
        SERVER_NAME     => $is_unix ? $httpd->hostpath : $httpd->sockhost,
        SERVER_PROTOCOL => 'HTTP/1.1',
        REMOTE_ADDR     => $is_unix ? '127.0.0.1' : $sock->peerhost,

        'psgi.version'         => [ 1, 1 ],
        'psgi.input'           => IO::Scalar->new(\($req->{_content})),
        'psgi.errors'          => *STDERR,
        'psgi.url_scheme'      => $is_ssl ? 'https' : 'http',
        'psgi.run_once'        => Plack::Util::FALSE,
        'psgi.multithread'     => Plack::Util::FALSE,
        'psgi.multiprocess'    => Plack::Util::TRUE,
        'psgi.streaming'       => Plack::Util::TRUE,
        'psgi.nonblocking'     => Plack::Util::FALSE,
        'psgix.input.buffered' => Plack::Util::TRUE,
        'psgix.io'             => $sock,
        'psgix.input.buffered' => Plack::Util::TRUE,
        'psgix.harakiri'       => Plack::Util::TRUE,

        # additional/server-specific
        'gepok'                     => 1,
        'gepok.connect_time'        => $self->{_connect_time},
        'gepok.start_request_time'  => $self->{_start_req_time},
        'gepok.finish_request_time' => $self->{_finish_req_time},
        'gepok.client_protocol'     => $self->{_client_proto},
        'gepok.socket'              => $sock,
        'gepok.httpd_socket'        => $httpd,
    };
    $env->{HTTPS} = 'on' if $is_ssl;
    if ($is_unix) {
        $env->{'gepok.unix_socket'} = 1;
    } else {
        #
    }

    # HTTP_ vars
    my $rh = $req->headers;
    for my $hn ($rh->header_field_names) {
        my $key = uc($hn); $key =~ s/[^A-Z0-9]/_/g;
        $key = "HTTP_$key" unless $key =~ /\A(?:CONTENT_(?:TYPE|LENGTH))\z/;
        $env->{$key} = join(", ", $rh->header($hn));
    }

    $env;
}

sub _set_label_serving {
    my ($self, $sock) = @_;
    # sock can be undef when client timed out
    return unless $sock;

    my $httpd = ${*$sock}{httpd_daemon};
    my $is_unix = $httpd->isa('HTTP::Daemon::UNIX');

    if ($is_unix) {
        my $sock_path = $httpd->hostpath;
        my ($pid, $uid, $gid) = $httpd->peercred;
        log_trace("Unix socket info: path=$sock_path, ".
                        "pid=$pid, uid=$uid, gid=$gid");
        $self->_daemon->set_label("serving unix (pid=$pid, uid=$uid, ".
                                      "path=$sock_path)");
    } else {
        my $is_ssl = $httpd->isa('HTTP::Daemon::SSL') ? 1:0;
        my $server_port = $sock->sockport;
        my $remote_ip   = $sock->peerhost // "127.0.0.1";
        my $remote_port = $sock->peerport;
        if (log_is_trace) {
            log_trace(join("",
                             "TCP socket info: https=$is_ssl, ",
                             "server_port=$server_port, ",
                             "remote_ip=$remote_ip, ",
                             "remote_port=$remote_port"));
        }



( run in 0.617 second using v1.01-cache-2.11-cpan-140bd7fdf52 )