Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 54 additions & 19 deletions lib/HTTP/DAV.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1007,33 +1007,68 @@ sub _put {
else {
my $content = "";
my $fail = 0;
my $length = 0;

# Content was passed in as a scalar ref
if ($content_ptr) {
$content = $$local;
$length = length($content);
}

# Content is a local file presumably
else {
if ( !CORE::open( F, $local ) ) {
$self->err( 'ERR_GENERIC',
"Couldn't open local file $local: $!" );
$fail = 1;
$length = -s $local if -e $local;
my $fh;
if (! CORE::open($fh, "<", $local)) {
$self->err('ERR_GENERIC', "Couldn't open local file $local: $!");
return;
}
else {
binmode F;
while (my $line = <F>) { $content .= $line; }
close F;

binmode($fh);

# Setting the content to a simple subroutine will
# let it upload the file one piece at a time.
# HTTP::Request provides this functionality.
$content = sub {
my $buffer;
my $num_bytes = read($fh, $buffer, 4096);
if ($num_bytes) {
return $buffer;
}
else {
close($fh);
}
};

# Since we set the content to be a subroutine,
# we need to set the content length here since the
# downstream code will no longer have access to the file name
$custom_headers = {} unless $custom_headers;
$custom_headers->{'Content-Length'} = $length;

# Simple check to see if the file is XML
# In HTTP::DAV::Comms::do_http_request(), the
# content is checked against a regular expression.
# But it cannot do this when the file is being streamed.
# So, we'll check the beginning of the file since that is
# where the "<?xml" tag would be present.
my $file_header;
my $bytes = read($fh, $file_header, 4096);
seek($fh, 0, 0);
if ($bytes && $file_header =~ /<\?xml/i) {
$custom_headers->{'Content-Type'} = 'text/xml';
}
}
my $resource = $self->new_resource( -uri => $target );
my $response = $resource->put($content, $custom_headers);

if ( !$fail ) {
my $resource = $self->new_resource( -uri => $target );
my $response = $resource->put($content,$custom_headers);
if ( $response->is_success ) {
$self->ok( "put $target (" . length($content) . " bytes)",
$target );
}
else {
$self->err( 'ERR_RESP_FAIL',
"put failed " . $response->message(), $target );
}
if ($response->is_success) {
$self->ok("put $target ($length bytes)", $target);
}
else {
$self->err('ERR_RESP_FAIL',
"put failed " . $response->message(), $target
);
}
}
}
Expand Down
29 changes: 17 additions & 12 deletions lib/HTTP/DAV/Comms.pm
Original file line number Diff line number Diff line change
Expand Up @@ -160,21 +160,26 @@ sub do_http_request {
#$headers->header("Host", $url_obj->host);
$headers->header( "Host", $url_obj->host_port );

my $length = ($content) ? length($content) : 0;
$headers->header( "Content-Length", $length );
# If the content is a subroutine, don't try to use it to determine
# the length or type of the file. We will have set the length earlier
if (ref($content) !~ m{CODE}) {

#print "HTTP HEADERS\n" . $self->get_headers->as_string . "\n\n";
my $length = ($content) ? length($content) : 0;
$headers->header("Content-Length", $length);

# It would be good if, at this stage, we could prefill the
# username and password values to prevent the client having
# to submit 2 requests, submit->401, submit->200
# This is the same kind of username, password remembering
# functionality that a browser performs.
#@userpass = $self->{_user_agent}->get_basic_credentials(undef, $url);
#print "HTTP HEADERS\n" . $self->get_headers->as_string . "\n\n";

# Add a Content-type of text/xml if the body has <?xml in it
if ( $content && $content =~ /<\?xml/i ) {
$headers->header( "Content-Type", "text/xml" );
# It would be good if, at this stage, we could prefill the
# username and password values to prevent the client having
# to submit 2 requests, submit->401, submit->200
# This is the same kind of username, password remembering
# functionality that a browser performs.
#@userpass = $self->{_user_agent}->get_basic_credentials(undef, $url);

# Add a Content-type of text/xml if the body has <?xml in it
if ($content && $content =~ /<\?xml/i) {
$headers->header("Content-Type" => "text/xml");
}
}

####
Expand Down