our
$VERSION
=
'0.001'
;
sub
configure {
my
(
$self
,
%args
) =
@_
;
foreach
(
qw(user pass path host http)
) {
$self
->{
$_
} =
delete
$args
{
$_
}
if
exists
$args
{
$_
};
}
return
$self
;
}
sub
http {
my
$self
=
shift
;
if
(
@_
) {
shift
->{http} =
shift
;
return
$self
}
unless
(
$self
->{http}) {
my
$ua
=
$self
->ua_factory;
$self
->add_child(
$ua
);
Scalar::Util::weaken(
$self
->{http} =
$ua
);
}
return
$self
->{http};
}
sub
ua_factory {
my
(
$self
) =
@_
;
$self
->{ua_factory}->()
if
$self
->{ua_factory};
Net::Async::HTTP->new(
decode_content
=> 0,
fail_on_error
=> 1,
max_connections_per_host
=> 4,
stall_timeout
=> 60,
)
}
sub
path {
shift
->{path} }
sub
propfind {
my
$self
=
shift
;
my
%args
=
@_
;
my
$uri
=
$self
->uri_from_path(File::Spec->catdir((
$self
->path // ()),
$args
{path}) .
'/'
) or
die
"Invalid URL?"
;
my
$body
=
<<"EOF";
<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:allprop/>
</D:propfind>
EOF
my
$req
= HTTP::Request->new(
PROPFIND
=>
$uri
->path, [
'Host'
=>
$uri
->host,
'Depth'
=> 1,
'Content-Type'
=>
'text/xml'
], encode_utf8(
$body
)
);
$req
->protocol(
'HTTP/1.1'
);
$req
->authorization_basic(
$self
->user,
$self
->pass)
if
defined
(
$self
->user);
$self
->http->do_request(
request
=>
$req
,
host
=>
$uri
->host,
port
=>
$uri
->scheme || 80,
SSL
=>
$uri
->scheme eq
'https'
? 1 : 0,
on_header
=>
sub
{
my
$response
=
shift
;
my
$result
= Net::Async::HTTP::DAV::Response->new(
%args
,
path
=>
$uri
->path
);
weaken
$response
;
return
sub
{
$result
->parse_chunk(
$_
[0])
if
@_
;
$response
};
},
);
}
sub
getinfo {
my
$self
=
shift
;
my
%args
=
@_
;
my
$uri
=
$self
->uri_from_path(
$args
{path} //
$self
->{path}) or
die
"Invalid URL?"
;
my
$body
=
<<"EOF";
<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:allprop/>
</D:propfind>
EOF
my
$req
= HTTP::Request->new(
PROPFIND
=>
$uri
->path, [
'Host'
=>
$uri
->host,
'Depth'
=> 0,
'Content-Type'
=>
'text/xml'
], encode_utf8(
$body
)
);
$req
->protocol(
'HTTP/1.1'
);
$req
->authorization_basic(
$self
->user,
$self
->pass)
if
$self
->user;
$self
->http->do_request(
request
=>
$req
,
host
=>
$uri
->host,
port
=>
$uri
->scheme || 80,
SSL
=>
$uri
->scheme eq
'https'
? 1 : 0,
on_header
=>
sub
{
my
$response
=
shift
;
my
$result
= Net::Async::HTTP::DAV::Response->new(
%args
,
path
=>
$uri
->path,
on_item
=>
sub
{
my
$item
=
shift
;
$args
{on_size}->(
$item
->{size});
}
);
return
sub
{
$result
->parse_chunk(
$_
[0])
if
@_
;
};
},
on_error
=>
sub
{
my
(
$message
) =
@_
;
die
"Failed - $message\n"
;
}
);
return
$self
;
}
sub
head {
my
$self
=
shift
;
my
%args
=
@_
;
my
$uri
=
$self
->uri_from_path(
$args
{path} //
$self
->{path}) or
die
"Invalid URL?"
;
my
$req
= HTTP::Request->new(
HEAD
=>
$uri
->path, [
'Host'
=>
$uri
->host,
]
);
$req
->protocol(
'HTTP/1.1'
);
$req
->authorization_basic(
$self
->user,
$self
->pass)
if
$self
->user;
$self
->http->do_request(
request
=>
$req
,
host
=>
$uri
->host,
port
=>
$uri
->scheme || 80,
SSL
=>
$uri
->scheme eq
'https'
? 1 : 0,
on_response
=>
sub
{
my
$response
=
shift
;
},
on_error
=>
sub
{
my
(
$message
) =
@_
;
die
"Failed - $message\n"
;
}
);
return
$self
;
}
sub
get {
my
$self
=
shift
;
my
%args
=
@_
;
my
$uri
=
$self
->uri_from_path(
$args
{path} //
$self
->{path}) or
die
"Invalid URL?"
;
my
$req
= HTTP::Request->new(
GET
=>
$uri
->path, [
'Host'
=>
$uri
->host,
]
);
$req
->protocol(
'HTTP/1.1'
);
$req
->authorization_basic(
$self
->user,
$self
->pass)
if
$self
->user;
$self
->http->do_request(
request
=>
$req
,
host
=>
$uri
->host,
port
=>
$uri
->scheme || 80,
SSL
=>
$uri
->scheme eq
'https'
? 1 : 0,
on_header
=>
sub
{
my
$response
=
shift
;
return
$args
{on_header}->(
$response
);
},
on_error
=>
sub
{
my
(
$message
) =
@_
;
die
"Failed - $message\n"
;
}
);
return
$self
;
}
sub
put {
my
$self
=
shift
;
my
%args
=
@_
;
my
$handler
=
delete
$args
{response_body};
my
$uri
=
$self
->uri_from_path(
$args
{path} //
$self
->{path});
my
$req
= HTTP::Request->new(
PUT
=>
$uri
->path, [
'Host'
=>
$uri
->host,
'Content-Type'
=>
'application/octetstream'
,
],
defined
$args
{content} ?
$args
{content} : ()
);
$req
->protocol(
'HTTP/1.1'
);
$req
->authorization_basic(
$self
->{user},
$self
->{pass});
$req
->content_length(
$args
{size})
unless
defined
$args
{content};
my
$fh
;
$self
->http->do_request(
request
=>
$req
,
host
=>
$uri
->host,
port
=>
$uri
->scheme || 80,
SSL
=>
$uri
->scheme eq
'https'
? 1 : 0,
(
defined
$args
{content})
? ()
: (
request_body
=>
$handler
||
sub
{
my
(
$stream
) =
@_
;
warn
$stream
;
return
''
;
my
$read
=
sysread
$fh
,
my
$buffer
, 32768;
warn
$!
unless
defined
$read
;
return
$buffer
if
$read
;
return
;
}),
on_error
=>
sub
{
my
(
$message
) =
@_
;
die
"Failed - $message\n"
;
},
on_response
=>
$args
{on_response} ||
sub
{
my
(
$response
) =
@_
;
my
$msg
=
$response
->message;
$msg
=~ s/\s+/ /ig;
$msg
=~ s/(?:^\s+)|(?:\s+$)//g;
warn
$response
->code .
" - $msg\n"
;
}
);
}
sub
host {
shift
->{host} }
sub
user {
shift
->{user} }
sub
pass {
shift
->{pass} }
sub
uri_from_path {
my
$self
=
shift
;
my
$path
=
shift
//
'/'
;
$path
=
"/$path"
unless
substr
(
$path
, 0, 1) eq
'/'
;
$path
=~ s{/+}{/}g;
return
URI->new(
'http://'
.
$self
->host .
$path
) ||
die
"Invalid URL?"
;
}
1;