Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload a project avatar - PUT + "Header: Content-Type" #53

Open
g0tmi1k opened this issue Dec 22, 2022 · 0 comments
Open

Upload a project avatar - PUT + "Header: Content-Type" #53

g0tmi1k opened this issue Dec 22, 2022 · 0 comments

Comments

@g0tmi1k
Copy link
Contributor

g0tmi1k commented Dec 22, 2022

Goal: Using devscript's salsa, I'm trying to open new a new merge request which supports setting a project's avatar.


Requirement: Looking at GitLab's API:

To upload an avatar from your file system, use the --form argument. This causes cURL to post data using the header Content-Type: multipart/form-data. The file= parameter must point to an image file on your file system and be preceded by @.


Trace log:

salsa's lib/Devscripts/Salsa/update_repo.pm:

[...]
use GitLab::API::v4::Constants qw(:all);
[...]
        eval {
            # apply new parameters
            $self->api->edit_project($id,
                { %$configparams, $self->desc($repo->[1]) });

Looking at $self->api->edit_project, it uses GitLab::API::v4:

[...]
sub edit_project {
    my $self = shift;
    croak 'edit_project must be called with 1 to 2 arguments' if @_ < 1 or @_ > 2;
    croak 'The #1 argument ($project_id) to edit_project must be a scalar' if ref($_[0]) or (!defined $_[0]);
    croak 'The last argument (\%params) to edit_project must be a hash ref' if defined($_[1]) and ref($_[1]) ne 'HASH';
    my $params = (@_ == 2) ? pop() : undef;
    my $options = {};
    $options->{decode} = 0;
    $options->{content} = $params if defined $params;
    $self->_call_rest_client( 'PUT', 'projects/:project_id', [@_], $options );
    return;
}

The user input goes to: $options->{content}. We can't say do: $options->{headers}

Following it to $self->_call_rest_client:

[...]
sub _call_rest_client {
    my ($self, $verb, $path, $path_vars, $options) = @_;

    $options->{headers} = $self->_auth_headers();

    return $self->rest_client->request(
        $verb, $path, $path_vars, $options,
    );
}

As a result, this makes a PUT request, but doesn't have the Content-Type: multipart/form-data set in the header. There doesn't appear to be any where to be able to add custom headers in the request.


Error:
When you try and make the request without it being set:

root@debian:~# perl scripts/salsa.pl --conf-file config.conf update_safe test123 --avatar-path=./icon.png  --debug --verbose
[...]
salsa.pl info: Error PUTing https://gitlab.com/api/v4/projects/123 (HTTP 400): Bad Request {"error":"avatar is invalid"} at /root/devscripts/lib/Devscripts/Salsa/update_repo.pm line 79.

This code hasn't been committed publicly

Other people getting the same error response: #1


Possible solutions:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant