1package HTTP::Tiny::UNIX;
2
3use 5.010001;
4use strict;
5use warnings;
6
7our $DATE = '2018-05-08'; # DATE
8our $VERSION = '0.051'; # VERSION
9
10# issue: port must be numeric to avoid warning
11# put everything in path_query
12
13use parent qw(HTTP::Tiny);
14
15use IO::Socket::UNIX;
16
17sub _split_url {
18    my ($self, $url) = @_;
19
20    if ($url =~ m<\A[^:/?#]+://>) {
21        $self->{_unix} = 0;
22        return $self->SUPER::_split_url($url);
23    }
24
25    my ($scheme, $sock_path, $path_query) =
26        $url =~ m<\A(\w+):(.+?)/(/[^#]*)>
27            or die "Cannot parse HTTP-over-Unix URL: '$url'\n";
28
29    # a hack
30    $self->{_unix} = 1;
31    $self->{_path_query} = $path_query;
32
33    $scheme = lc $scheme;
34    die "Only http scheme is supported\n" unless $scheme eq 'http';
35
36    #return ($scheme, $host,      $port, $path_query, $auth);
37    return  ($scheme, $sock_path, -1,    $path_query, '');
38}
39
40sub _open_handle {
41    my ($self, $request, $scheme, $host, $port) = @_;
42
43    return $self->SUPER::_open_handle($request, $scheme, $host, $port)
44        unless $self->{_unix};
45
46    my $handle = HTTP::Tiny::Handle::UNIX->new(
47        timeout => $self->{timeout},
48    );
49
50    $handle->connect($scheme, $host, $port, $self);
51}
52
53package
54    HTTP::Tiny::Handle::UNIX;
55
56use parent -norequire, 'HTTP::Tiny::Handle';
57
58use IO::Socket;
59
60sub connect {
61    my ($self, $scheme, $host, $port, $tiny) = @_;
62
63    # on Unix, we use $host for path and leave port at -1 (unused)
64    my $path = $host;
65
66    local($^W) = 0;
67    my $sock = IO::Socket::UNIX->new(
68        Peer    => $path,
69        Type    => SOCK_STREAM,
70        Timeout => $self->{timeout},
71        Host    => 'localhost',
72    );
73
74    unless ($sock) {
75        $@ =~ s/^.*?: //;
76        die "Can't open Unix socket $path\: $@";
77    }
78
79    eval { $sock->blocking(0); };
80
81    $self->{fh} = $sock;
82
83    $self->{scheme} = $scheme;
84    $self->{host} = $host;
85    $self->{port} = $port;
86    $self->{_unix} = 1;
87    # this is a hack, we inject this so we can get HTTP::Tiny::UNIX object from
88    # HTTP::Tiny::Handle::UNIX, to get path
89    $self->{_tiny} = $tiny;
90    $self;
91}
92
93sub write_request_header {
94    my ($self, $method, $request_uri, $headers, $header_case) = @_;
95
96    return $self->SUPER::write_request_header(@_)
97        unless $self->{_unix};
98
99    return $self->write_header_lines($headers, $header_case, "$method $self->{_tiny}{_path_query} HTTP/1.1\x0D\x0A");
100}
101
1021;
103# ABSTRACT: A subclass of HTTP::Tiny to connect to HTTP server over Unix socket
104
105__END__
106
107=pod
108
109=encoding UTF-8
110
111=head1 NAME
112
113HTTP::Tiny::UNIX - A subclass of HTTP::Tiny to connect to HTTP server over Unix socket
114
115=head1 VERSION
116
117This document describes version 0.051 of HTTP::Tiny::UNIX (from Perl distribution HTTP-Tiny-UNIX), released on 2018-05-08.
118
119=head1 SYNOPSIS
120
121 use HTTP::Tiny::UNIX;
122
123 my $response = HTTP::Tiny::UNIX->new->get('http:/path/to/unix.sock//uri/path');
124
125 die "Failed!\n" unless $response->{success};
126 print "$response->{status} $response->{reason}\n";
127
128 while (my ($k, $v) = each %{$response->{headers}}) {
129     for (ref $v eq 'ARRAY' ? @$v : $v) {
130         print "$k: $_\n";
131     }
132 }
133
134 print $response->{content} if length $response->{content};
135
136=head1 DESCRIPTION
137
138This is a subclass of L<HTTP::Tiny> to connect to HTTP server over Unix socket.
139URL syntax is C<"http:"> + I<path to unix socket> + C<"/"> + I<uri path>. For
140example: C<http:/var/run/apid.sock//api/v1/matches>. URL not matching this
141pattern will be passed to HTTP::Tiny.
142
143Proxy is currently not supported.
144
145=head1 HOMEPAGE
146
147Please visit the project's homepage at L<https://metacpan.org/release/HTTP-Tiny-UNIX>.
148
149=head1 SOURCE
150
151Source repository is at L<https://github.com/perlancar/perl-HTTP-Tiny-UNIX>.
152
153=head1 BUGS
154
155Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=HTTP-Tiny-UNIX>
156
157When submitting a bug or request, please include a test-file or a
158patch to an existing test-file that illustrates the bug or desired
159feature.
160
161=head1 SEE ALSO
162
163L<HTTP::Tiny>
164
165To use L<LWP> to connect over Unix sockets, see
166L<LWP::Protocol::http::SocketUnixAlt>.
167
168=head1 AUTHOR
169
170perlancar <perlancar@cpan.org>
171
172=head1 COPYRIGHT AND LICENSE
173
174This software is copyright (c) 2018, 2014 by perlancar@cpan.org.
175
176This is free software; you can redistribute it and/or modify it under
177the same terms as the Perl 5 programming language system itself.
178
179=cut
180