php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #63766 sftp upload CURLOPT_URL errors with code 79 with directory path
Submitted: 2012-12-14 06:55 UTC Modified: 2012-12-18 16:06 UTC
From: mattsch at gmail dot com Assigned:
Status: Not a bug Package: cURL related
PHP Version: 5.4.9 OS: Gentoo
Private report: No CVE-ID: None
 [2012-12-14 06:55 UTC] mattsch at gmail dot com
Description:
------------
When specifying a url in CURLOPT_URL with a directory path only using the sftp protocol, the upload will always fail with error code 79 (An unspecified error occurred during the SSH session).  If you change the CURLOPT_URL to be the same path but add a filename at the end of the directory path, the upload will succeed.


emerge -pv php:5.4

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild   R   ~] dev-lang/php-5.4.9:5.4  USE="apache2 bcmath bzip2 calendar cjk cli crypt ctype curl curlwrappers exif fileinfo filter ftp gd gdbm gmp hash iconv ipv6 json ldap mhash mysql mysqli mysqlnd nls pcntl pdo phar posix readline session simplexml snmp soap sockets spell sqlite ssl sysvipc threads tidy tokenizer truetype unicode wddx xml xmlwriter xpm xsl zip zlib -berkdb -cdb -cgi -debug -doc -embed -enchant -firebird -flatfile -fpm (-frontbase) -imap -inifile -intl -iodbc -kerberos (-kolab) -ldap-sasl -libedit -mssql -oci8-instant-client -odbc -pic -postgres -qdbm -recode (-selinux) -sharedmem (-sybase-ct) -xmlreader -xmlrpc" 0 kB

emerge -pv curl

These are the packages that would be merged, in order:

Calculating dependencies  e -      ... done!
[ebuild   R   ~] net-misc/curl-7.28.1  USE="idn ipv6 nonblocking ssh ssl threads -adns -kerberos -ldap -metalink -rtmp -static-libs {-test}" CURL_SSL="openssl -axtls -cyassl -gnutls -nss -polarssl" 0 kB


emerge -pv libssh2

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild   R   ~] net-libs/libssh2-1.4.3  USE="zlib -gcrypt -static-libs {-test}" 0 kB


curl -V
curl 7.28.1 (x86_64-pc-linux-gnu) libcurl/7.28.1 OpenSSL/1.0.0j zlib/1.2.7 libidn/1.25 libssh2/1.4.3
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp 
Features: AsynchDNS IDN IPv6 Largefile NTLM NTLM_WB SSL libz



Test script:
---------------
<?php
function upload($url)
{
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_UPLOAD, 1);
        curl_setopt($ch, CURLOPT_INFILE, fopen('/tmp/foo', 'r'));
        curl_setopt($ch, CURLOPT_INFILESIZE, filesize('/tmp/foo'));
        curl_setopt($ch, CURLOPT_USERPWD, 'user:password');
        curl_exec($ch);
        echo curl_errno($ch) . "\n";
}
// prints 79 -- should print 0
upload('sftp://domain.tld:/tmp');
// prints 0
upload('sftp://domain.tld:/tmp/foo');

Expected result:
----------------
0
0


Actual result:
--------------
79
0

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-12-14 08:39 UTC] pajoye@php.net
-Status: Open +Status: Not a bug
 [2012-12-14 08:39 UTC] pajoye@php.net
CURL cannot upload directory (aka recursively). 

However it can create missing directories in a path if necessary using the create 
dir option.
 [2012-12-14 22:47 UTC] mattsch at gmail dot com
This is a bug.  I am not trying to upload anything recursively.  I am simply trying to upload one file to a directory.  When I don't specify the target filename on the url, I expect that the target file created on the remote server is the same name as the filename that I am uploading.
 [2012-12-14 22:50 UTC] mattsch at gmail dot com
"foo" designates a file and not a directory.  Perhaps my test script should have been more clear by using a file extension like .txt or something.  The file I am trying to upload is being uploaded to a directory that already exists on the remote server.
 [2012-12-17 01:23 UTC] aharvey@php.net
-Status: Not a bug +Status: Open
 [2012-12-17 01:23 UTC] aharvey@php.net
Reopened per previous comments, although I wonder if this might be a libcurl issue rather than a PHP one.
 [2012-12-17 12:17 UTC] bagder@php.net
This is not a libcurl bug. If you think about it for a while, libcurl doesn't 
know the 'foo' name, it is only given the (bad) URL and it cannot but to fail in 
this case.

I'm also convinced you can see the same problem with other protocols than SFTP 
for the same reason.
 [2012-12-17 14:48 UTC] mattsch at gmail dot com
Could you elaborate as to why this would be a bad url?  The documentation on the curl website seems to indicate that you can specify a url without a filename at the end but then the examples are not specific to upload:

http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTURL
 [2012-12-18 07:11 UTC] bagder@php.net
The CURLOPT_URL option is of course to generically set a URL to work with. 
libcurl accepts whatever URL you set and will try to work on it once you ask 
curl to perform on it.

A URL that ends with a slash is treated as a directory by libcurl when you're 
downloading something from it. It will then (depending on protocol) ask for a 
directory listing instead of trying to fetch a file with that name.

libcurl assumes the users knows what (s)he is doing and will try to perform the 
requested operation on the given URL. Uploading to a directory name is probably 
going to fail on most systems.
 [2012-12-18 07:20 UTC] pajoye@php.net
-Status: Open +Status: Not a bug
 [2012-12-18 07:20 UTC] pajoye@php.net
See previous comments
 [2012-12-18 15:49 UTC] mattsch at gmail dot com
That does not explain why it fails when you try to upload to a directory.  So what you're saying is this is not a bug because it's not possible to do this with curl and you must always specify a url with a filename to upload a file?  And if that's the case, why is it not possible to upload a file to a directory?
 [2012-12-18 15:55 UTC] mattsch at gmail dot com
In addition, if I modify the test script and it with a slash at the end, it also fails in the same way:

upload('sftp://domain.tld:/tmp/');
 [2012-12-18 16:06 UTC] mattsch at gmail dot com
Also the same thing happens when using scp://.  What I don't understand is if I were to upload the file on the command line with scp without specifying a filename but rather just a destination directory, the file would upload.  So why can't I expect curl to do the same when using the same protocol?
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Tue Oct 22 13:01:29 2019 UTC