Jump to content

Sending a file using cURL


NotionCommotion

Recommended Posts

A client uploads a file to a server, and the server receives the following.  The server uses a session to verify that the user is logged on, and if so, gets the users secret key, puts it in a header using CURLOPT_HTTPHEADER, and sends the file to another server using cURL.

 

I've never sent a file using cURL.  Anything special?  Guess I can leave the file in its temp location and not use move_uploaded_file(), right?  Should I delete it after it is sent?  My current cURL method is below.  Any recommendations on how it can accommodate files?


Accept    application/json, text/javascript, */*; q=0.01
Accept-Encoding    gzip, deflate
Accept-Language    en-US,en;q=0.5
Content-Length    31299
Content-Type    multipart/form-data; boundary=---------------------------159893106321761
Host    dd.example.com
Referer    http://dd.example.com/resources
User-Agent    Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0
X-Requested-With    XMLHttpRequest

-----------------------------159893106321761 Content-Disposition: form-data; name="resources[]"; filename="aboutus.png" Content-Type: image/png PNG IHDR8
bla bla bla
Ö®ÿùæÔ^_×w8IEND®B` -----------------------------159893106321761--

    private function CallAPI($method, $url, $data, array $headers=[], $options=[], $debug=false)
    {
        $options=$options+[    //Don't use array_merge since it reorders!
            CURLOPT_RETURNTRANSFER => true,     // return web page
            CURLOPT_HEADER         => false,    // don't return headers
            CURLOPT_FOLLOWLOCATION => true,     // follow redirects
            CURLOPT_ENCODING       => "",       // handle all encodings
            CURLOPT_USERAGENT      => "unknown",// who am i
            CURLOPT_AUTOREFERER    => true,     // set referrer on redirect
            CURLOPT_CONNECTTIMEOUT => 120,      // timeout on connect
            CURLOPT_TIMEOUT        => 120,      // timeout on response
            CURLOPT_MAXREDIRS      => 10,       // stop after 10 redirects
            CURLOPT_SSL_VERIFYPEER => false     // Disabled SSL Cert checks.  FIX!!!!!!!!!
        ];
        //Optional authentication
        if (isset($options[CURLOPT_USERPWD])) {$options[CURLOPT_HTTPAUTH]=CURLAUTH_BASIC;}
        switch (strtolower($method)) {
            case "get":
                if ($data) {$url = sprintf("%s?%s", $url, http_build_query($data));}
                break;
            case "post":
                $options[CURLOPT_POST]=1;
                if ($data) {$options[CURLOPT_POSTFIELDS]=$data;}
                break;
            case "put":
                //$options[CURLOPT_PUT]=1;
                $options[CURLOPT_CUSTOMREQUEST]="PUT";
                if ($data) {$options[CURLOPT_POSTFIELDS]=http_build_query($data);}
                break;
            case "delete":
                //$options[CURLOPT_DELETE]=1;
                $options[CURLOPT_CUSTOMREQUEST]="DELETE";
                if ($data) {$options[CURLOPT_POSTFIELDS]=http_build_query($data);}
                break;
            default:trigger_error("Invalid HTTP method.", E_USER_ERROR);
        }
        //$this->logger->addInfo("$method $url ".json_encode($data));
        $options[CURLOPT_URL]=$url;
        $ch      = curl_init();
        curl_setopt_array( $ch, $options );
        if($headers) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }
        $content = curl_exec( $ch );
        if(!$debug){$results=$content;}
        else {
            $results  = curl_getinfo( $ch );
            $results['errno']   = curl_errno( $ch );
            $results['errmsg']  = curl_error( $ch );
            $results['content'] = $content;
        }
        curl_close( $ch );
        return $results;
    }
Edited by NotionCommotion
Link to comment
Share on other sites

 

 

Nice.  I don't even need to modify my method.

 

I am getting an empty array reply, so I evidently am not doing this correctly.  Know where I am going astray?

 

Thanks

<?php
function CallAPI($method, $url, $data, array $headers=[], $options=[], $debug=false)
{
    $options=$options+[    //Don't use array_merge since it reorders!
        CURLOPT_RETURNTRANSFER => true,     // return web page
        CURLOPT_HEADER         => false,    // don't return headers
        CURLOPT_FOLLOWLOCATION => true,     // follow redirects
        CURLOPT_ENCODING       => "",       // handle all encodings
        CURLOPT_USERAGENT      => "unknown",// who am i
        CURLOPT_AUTOREFERER    => true,     // set referrer on redirect
        CURLOPT_CONNECTTIMEOUT => 120,      // timeout on connect
        CURLOPT_TIMEOUT        => 120,      // timeout on response
        CURLOPT_MAXREDIRS      => 10,       // stop after 10 redirects
        CURLOPT_SSL_VERIFYPEER => false     // Disabled SSL Cert checks.  FIX!!!!!!!!!
    ];
    //Optional authentication
    if (isset($options[CURLOPT_USERPWD])) {$options[CURLOPT_HTTPAUTH]=CURLAUTH_BASIC;}
    switch (strtolower($method)) {
        case "get":
            if ($data) {$url = sprintf("%s?%s", $url, http_build_query($data));}
            break;
        case "post":
            $options[CURLOPT_POST]=1;
            if ($data) {$options[CURLOPT_POSTFIELDS]=$data;}
            break;
        case "put":
            //$options[CURLOPT_PUT]=1;
            $options[CURLOPT_CUSTOMREQUEST]="PUT";
            if ($data) {$options[CURLOPT_POSTFIELDS]=http_build_query($data);}
            break;
        case "delete":
            //$options[CURLOPT_DELETE]=1;
            $options[CURLOPT_CUSTOMREQUEST]="DELETE";
            if ($data) {$options[CURLOPT_POSTFIELDS]=http_build_query($data);}
            break;
        default:trigger_error("Invalid HTTP method.", E_USER_ERROR);
    }
    $options[CURLOPT_URL]=$url;
    $ch      = curl_init();
    curl_setopt_array( $ch, $options );
    if($headers) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }
    $content = curl_exec( $ch );
    if(!$debug){$results=$content;}
    else {
        $results  = curl_getinfo( $ch );
        $results['errno']   = curl_errno( $ch );
        $results['errmsg']  = curl_error( $ch );
        $results['content'] = $content;
    }
    curl_close( $ch );
    return $results;
}


if($_SERVER['REQUEST_METHOD']=='POST') {
    $data=[];
    foreach($_FILES as $name=>$file) {
        $data[] = [$name =>  new CURLFile($file['tmp_name'],$file['type'],$file['name'])];
    }
    $rs=CallAPI('post', 'http://example.com/fileuploader.php', $data,['X-SECRET-KEY: 1234']);
    foreach($_FILES as $file) {
        unlink($file['tmp_name']);
    }    
    echo('<pre>'.print_r($rs,1).'</pre>');
}
?>

<! DOCTYPE html>
<html>
<body>
    <form method="post" enctype="multipart/form-data">
        <input type="file" name="file">
        <input type="submit" value="Upload">
    </form>
</body>

fileuploader.php

<?php
header('Content-Type: application/json');
echo(json_encode($_FILES));
Link to comment
Share on other sites

I am obviously doing something wrong because this works.

<?php

// Create a cURL handle
$ch = curl_init('http://example.com/fileuploader.php');

// Create a CURLFile object
$cfile = new CURLFile('arrow.gif','image/gif','test_name');

// Assign POST data
$data = array('test_file' => $cfile);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

// Execute the handle
curl_exec($ch);

 

Edited by NotionCommotion
Link to comment
Share on other sites

Should I bother deleting old tmp_name files?

 

Also, should http method post only be used?

 

No need to delete as per http://php.net/manual/en/features.file-upload.post-method.php, " The file will be deleted from the temporary directory at the end of the request if it has not been moved away or renamed."

 

The only time PUT might make sense is replacing an existing file with a new one, and it is probably not worth the trouble.

Edited by NotionCommotion
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.