Perl Upload Script - Bad Request (400)

jukebox

Core license
License owner
Joined
Apr 2, 2016
Messages
14
Points
53
Hi,

I'm trying to create a simple perl upload script to interact with the Chevereto API.

I get the following errors:

Script Errors:
HTTP POST error code: 400
HTTP POST error message: Bad Request

Apache Error Log:
[Sun Apr 03 15:42:36.407725 2016] [:error] [pid 19919] [client 10.1.1.118:39702] PHP Warning: Missing boundary in multipart/form-data POST data in Unknown on line 0
[Sun Apr 03 15:42:36.419811 2016] [:error] [pid 19919] [client 10.1.1.118:39702] Invalid API v1 key.

I've tried different combinations of content-type without luck...

Any ideas?

Code:
#!/usr/bin/perl
use strict;
use LWP::UserAgent;
use MIME::Base64;
use JSON;

my $ua = LWP::UserAgent->new;
my $server_endpoint = "http://photos.mysite.com/api/1/upload";
my $server_api_key = "xxxx";
my $img = "/mnt/mysite/IMGP0013.JPG";

#convert the image to base64
open (my $image, $img) or die "$!";
        binmode $image;
        my $raw_string = do{ local $/ = undef; <$image>; };
        my $encoded = encode_base64( $raw_string );
close ($img);

# set custom HTTP request header fields
my $req = HTTP::Request->new(POST => $server_endpoint);
$req->header('content-type' => 'application/json');
$req->header('content-type' => 'multipart/form-data');

# add POST data to HTTP request body
my %post_hash = ( key => $server_api_key, source => $encoded, format => "json" );
my $post_data = to_json( \%post_hash );
$req->content($post_data);

my $resp = $ua->request($req);
if ($resp->is_success) {
    my $message = $resp->decoded_content;
    print "Received reply: $message\n";
}
else {
    print "HTTP POST error code: ", $resp->code, "\n";
    print "HTTP POST error message: ", $resp->message, "\n";
}
 

SirMoo

Founder license
Beta tester
Joined
Dec 2, 2013
Messages
350
Points
90
I mean... it says your key is invalid... did you put in the right api key?
 

jukebox

Core license
License owner
Joined
Apr 2, 2016
Messages
14
Points
53
Yes, I am using the correct key - I thought that was odd as well....
 

SirMoo

Founder license
Beta tester
Joined
Dec 2, 2013
Messages
350
Points
90
For the sake of me being stupid to perl... lets try a suggestion on other places...

What happens when you remove

$req->header('content-type' => 'multipart/form-data');
 

jukebox

Core license
License owner
Joined
Apr 2, 2016
Messages
14
Points
53
Thanks SirMoo., but I've figured out the problem.

It seem's that the API is expecting the parameters in the URI and not in the POST body (which is a little strange? - not sure?). Wonder if this tidbit can be added to the documentation.

Thanks
 

jukebox

Core license
License owner
Joined
Apr 2, 2016
Messages
14
Points
53
I'm also wondering if this will have an impact trying to base64 encode a file -- it's likely not going to fit into the URI right?
 

Rodolfo

Chevereto Developer
Chevereto Staff
Joined
Oct 7, 2008
Messages
15,459
Points
237
Location
Chevereto HQ
Website
rodolfoberrios.com
The base64 method should be used when you are limited to _GET requests. That the whole point of it. There's no data compression or anything, is just a way to send data.

Everybody else, not limited to only _GET requests, should send the image "as is", as a _FILES object.
 

jukebox

Core license
License owner
Joined
Apr 2, 2016
Messages
14
Points
53
Hi Rodolfo - I am trying to use POST not GET?

1) When I use POST body only, I get the following errors:
Apache: 192.168.1.108 - - [03/Apr/2016:21:07:06 +1000] "POST /api/1/upload HTTP/1.1" 400 531 "-" "libwww-perl/6.08"
Chevereto: [Sun Apr 03 21:07:06.455259 2016] [:error] [pid 9869] [client 192.168.1.108:39878] Invalid API v1 key.

-- It seems to be returning Invalid API v1 key .... because no data is being interpreted...

2) When I use POST with URI and short source, it works:
Apache: 192.168.1.108 - - [03/Apr/2016:21:25:43 +1000] "POST /api/1/upload/?key=xxxx&source=http%3A%2F%2Fphotos.mysite.com%2F128.jpg&format=json HTTP/1.1" 200 2630 "-" "libwww-perl/6.08"

3) When you use POST with URI and base64 source: 414
Apache: 192.168.1.108 - - [03/Apr/2016:21:35:22 +1000] "POST /api/1/upload/?key=xxxx&source=<base64 snip>" 414 0 "-" "-"
Perl Client: HTTP POST error code: 414, HTTP POST error message: Request-URI Too Long

Can you help explain the _FILES object and how this should be used in POST body data?

Thanks
 

Rodolfo

Chevereto Developer
Chevereto Staff
Joined
Oct 7, 2008
Messages
15,459
Points
237
Location
Chevereto HQ
Website
rodolfoberrios.com
You are doing it wrong in 3. The request url is just /api/v1/<action>. The other parameters are sent in the post request, not as part of the uri.
 

jukebox

Core license
License owner
Joined
Apr 2, 2016
Messages
14
Points
53
Hi Rodolfo - this is exactly what is happening in scenario one, but I keep getting "Invalid Key" because the api script is not reading the request (? I think). I also can't get (1) to work when I use a curl client.

Do you have a php/bash script that I can use to test?

Can I test my script on the demo environment?
 

jukebox

Core license
License owner
Joined
Apr 2, 2016
Messages
14
Points
53
OK - I figured it out now as you must use form url-encoded! Working now :)

Can post the perl code if anyone else interested.
 
  • Like
Reactions: Rodolfo