Subject: | zero length file uploads |
first off, thank you & I appreciate the module's existance.
if you don't already have an artifactory; it is quick to download the latest open source edition of artifactory.
http://www.jfrog.com/home/v_artifactory_opensource_download (I used 3.3.0 simply running bin/artifactory.bat)
run it; login as admin and create a 'dave-snapshot-local' repo;
install Artifactory::Client; and these 2 scripts together should upload and download itself (whatever you call main package) to dave-snapshot-local @ test/foo
Or, you know update the urls and repo names to match your test.
main script and AgentP.pm for user authentication against the "Artifactory Realm" seems to work fine, the artifact is created but 0 length.
On one machine I tested it would give me a time out response from the server. On this Strawberry v5.18.2 multi-x64 I get a created 201 response, quick but zero length file.
I know that ultimately this is a:
https://metacpan.org/pod/HTTP::Request::StreamingUpload
issue, but HTTP::Request-StreamingUpload already has a ticket which describes something that didn't resolve the issue for me.
https://rt.cpan.org/Ticket/Display.html?id=68609
Maybe it is related to:
https://metacpan.org/pod/HTTP::Request
or something else; idk. I haven't gotten out the wireshark and begun spelunking...yet.
I figure; we should at least have a ticket on Artifactory-Client to help bring attention to this issue.
Thanks.
-mrhorner
http://dave.thehorners.com/tech-talk/random-tech/522-great-lodge-of-the-royal-order-of-yaks-yak-shaving
====code===
package AgentP;
use base 'LWP::UserAgent';
sub _agent { "Mozilla/8.0" }
sub get_basic_credentials {
my ($self, $realm, $uri) = @_;
print( STDERR " - providing auth to realm \"$realm\"\n" );
return 'admin', 'password';
}
1
package main;
use Artifactory::Client;
use autodie;
use Data::Printer;
use AgentP;
my $ua=AgentP->new();
my $args = {
artifactory => 'http://localhost',
port => 8081,
repository => 'dave-snapshot-local/',
ua =>$ua
};
p $ua;
my $client = Artifactory::Client->new( $args );
p $client;
my $path = 'test/foo'; # path on artifactory
# Properties are a hashref of key-arrayref pairs. Note that value must be an arrayref even for a single element.
# This is to conform with Artifactory which treats property values as a list.
my $properties = {
one => ['two'],
baz => ['three'],
};
use File::Spec;
my $file=File::Spec->rel2abs( __FILE__ );
#my $file = 'D:\\working\\perl\\testArtifactory-Client.pl';
p $file;
$filesize=-s $file;
p $filesize;
# Name of methods are taken straight from Artifactory REST API documentation. 'Deploy Artifact' would map to
# deploy_artifact method, like below. The caller gets HTTP::Response object back.
my $resp = $client->deploy_artifact( path => $path, properties => $properties, file => $file );
p $resp;
# Custom requests can also be made via usual get / post / put / delete requests.
my $resp = $client->get( 'http://localhost:8081/artifactory/dave-snapshot-local/test/foo' );
p $resp;
=============OUTPUT FROM MY TEST (your byte count may vary)======
D:\working\perl>perl testArtifactory-Client.pl
AgentP {
Parents LWP::UserAgent
public methods (1) : get_basic_credentials
private methods (1) : _agent
internals: {
def_headers HTTP::Headers,
handlers {
response_header HTTP::Config
},
local_address undef,
max_redirect 7,
max_size undef,
no_proxy [],
protocols_allowed undef,
protocols_forbidden undef,
proxy {},
requests_redirectable [
[0] "GET",
[1] "HEAD"
],
show_progress undef,
ssl_opts {
verify_hostname 1
},
timeout 180,
use_eval 1
}
}
Artifactory::Client {
Parents Moose::Object
public methods (101) : all_builds, archive_entry_download, archive_entry_search, artifact_latest_version_search_based_on_layout, artifact_latest_version_search_based_on_properties, artifact_search, artifact_version_search, artifactory, artifacts_created_in_date_range, artifacts_not_downloaded_since, bad_checksum_search, build_artifacts_search, build_info, build_promotion, build_rename, build_runs, builds_diff, builds_for_dependency, calculate_maven_index, calculate_maven_metadata, calculate_nuget_repository_metadata, calculate_yum_repository_metadata, checksum_search, copy_item, create_directory, create_or_replace_group, create_or_replace_permission_target, create_or_replace_repository_configuration, create_or_replace_user, delete, delete_build, delete_group, delete_item, delete_item_properties, delete_permission_target, delete_repository, delete_repository_replication_configuration, delete_user, deploy_artifact, deploy_artifact_by_checksum, deploy_artifacts_from_archive, DESTROY, effective_item_permissions, execute_build_promotion, execute_plugin_code, export_system, export_system_settings_example, file_compliance_info, file_info, file_list, file_statistics, folder_info, full_system_import, gavc_search, general_configuration, get, get_group_details, get_groups, get_permission_target_details, get_permission_targets, get_repositories, get_repository_replication_configuration, get_user_details, get_users, import_repository_content, import_system_settings_example, item_last_modified, item_properties, license_search, meta, move_item, new, pattern_search, port, post, property_search, pull_push_replication, put, repository, repository_configuration, request, retrieve_all_available_plugin_info, retrieve_artifact, retrieve_build_artifacts_archive, retrieve_build_staging_strategy, retrieve_latest_artifact, retrieve_plugin_info_of_a_certain_type, save_general_configuration, scheduled_replication_status, security_configuration, set_item_properties, set_repository_replication_configuration, system_health_ping, system_info, trace_artifact_retrieval, ua, update_group, update_repository_configuration, update_repository_replication_configuration, update_user, version_and_addons_information
private methods (18) : _attach_properties, _build_ua, _get_build, _handle_item, _handle_matrix_props, _handle_non_matrix_props, _handle_plugins, _handle_prop_multivalue, _handle_repositories, _handle_repository_replication_configuration, _handle_search, _handle_search_props, _handle_security, _handle_system, _handle_system_settings, _request, _stringify_hash, _unpack_attributes
internals: {
artifactory "http://localhost",
port 8081,
repository "dave-snapshot-local/",
ua AgentP
}
}
"D:\working\perl\testArtifactory-Client.pl"
1380
- providing auth to realm "Artifactory Realm"
HTTP::Response {
Parents HTTP::Message
public methods (22) : as_string, base, clone, code, current_age, dump, error_as_HTML, filename, fresh_until, freshness_lifetime, is_error, is_fresh, is_info, is_redirect, is_success, message, new, parse, previous, redirects, request, status_line
private methods (0)
internals: {
_content "{
"repo" : "dave-snapshot-local",
"path" : "/test/foo",
"created" : "2014-08-05T23:51:30.551-04:00",
"createdBy" : "admin",
"downloadUri" : "http://localhost:8081/artifactory/dave-snapshot-local/test/foo",
"mimeType" : "application/octet-stream",
"size" : "0",
"checksums" : {
"sha1" : "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"md5" : "d41d8cd98f00b204e9800998ecf8427e"
},
"originalChecksums" : {
},
"uri" : "http://localhost:8081/artifactory/dave-snapshot-local/test/foo"
}",
_headers HTTP::Headers,
_msg "Created",
_previous HTTP::Response,
_protocol "HTTP/1.1",
_rc 201,
_request HTTP::Request
}
}
HTTP::Response {
Parents HTTP::Message
public methods (22) : as_string, base, clone, code, current_age, dump, error_as_HTML, filename, fresh_until, freshness_lifetime, is_error, is_fresh, is_info, is_redirect, is_success, message, new, parse, previous, redirects, request, status_line
private methods (0)
internals: {
_content "",
_headers HTTP::Headers,
_msg "OK",
_protocol "HTTP/1.1",
_rc 200,
_request HTTP::Request
}
}
Subject: | AgentP.pm |
package AgentP;
use base 'LWP::UserAgent';
sub _agent { "Mozilla/8.0" }
sub get_basic_credentials {
my ($self, $realm, $uri) = @_;
print( STDERR " - providing auth to realm \"$realm\"\n" );
return 'admin', 'password';
}
1
Subject: | testArtifactory-Client.pl |
use Artifactory::Client;
use autodie;
use Data::Printer;
use AgentP;
my $ua=AgentP->new();
my $args = {
artifactory => 'http://localhost',
port => 8081,
repository => 'dave-snapshot-local/',
ua =>$ua
};
p $ua;
my $client = Artifactory::Client->new( $args );
p $client;
my $path = 'test/foo'; # path on artifactory
# Properties are a hashref of key-arrayref pairs. Note that value must be an arrayref even for a single element.
# This is to conform with Artifactory which treats property values as a list.
my $properties = {
one => ['two'],
baz => ['three'],
};
use File::Spec;
my $file=File::Spec->rel2abs( __FILE__ );
#my $file = 'D:\\working\\perl\\testArtifactory-Client.pl';
p $file;
$filesize=-s $file;
p $filesize;
# Name of methods are taken straight from Artifactory REST API documentation. 'Deploy Artifact' would map to
# deploy_artifact method, like below. The caller gets HTTP::Response object back.
my $resp = $client->deploy_artifact( path => $path, properties => $properties, file => $file );
p $resp;
# Custom requests can also be made via usual get / post / put / delete requests.
my $resp = $client->get( 'http://localhost:8081/artifactory/dave-snapshot-local/test/foo' );
p $resp;