php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #7880 PHP_URL_FOPEN doesn't work
Submitted: 2000-11-19 15:37 UTC Modified: 2001-07-04 14:53 UTC
From: Alan at Halachmi dot net Assigned: jason (profile)
Status: Closed Package: Network related
PHP Version: 4.0.3pl1 OS: Solaris 8
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
33 + 36 = ?
Subscribe to this entry?

 
 [2000-11-19 15:37 UTC] Alan at Halachmi dot net
<?
    $url = "http://www.php.net/index.html";
    $fp = file($url);
    $if(!$fp) {
        echo "Cannot open url: $url";
    } else {
        echo "URL Opened.\n";
    }
?>

Yields:

Warning: file("http://www.php.net/index.html") - Bad file number in /home/www/htdocs/filetest.php on line 3
Cannot open url: http://www.php.net/index.html

Configure:
'./configure'
'--prefix=/opt/PHPphp/v4.0.3pl1/sparc-sun-solaris2.8'
'--exec-prefix=/opt/PHPphp/v4.0.3pl1/sparc-sun-solaris2.8'
'--localstatedir=/var/run'
'--with-apxs=/usr/local/bin/apxs'
'--with-config-file-path=/opt/PHPphp/v4.0.3pl1/sparc-sun-solaris2.8/etc'
'--enable-magic-quotes'
'--disable-pear'
'--with-gdbm'
'--with-zlib'
'--enable-ftp'
'--with-kerberos'
'--with-imap'
'--with-java=/usr/java'
'--with-ldap=/usr/local'
'--with-mysql=/usr/local'
'--enable-trans-sid'
'--enable-yp'
'--enable-memory-limit'
'--enable-track-vars'
'--enable-url-fopen-wrapper'

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2000-11-20 01:44 UTC] jason@php.net
As of 4.0.3, url_fopen is ini enabled not compile time enabled. Verify that youe php.ini contains "allow_url_fopen = On"

I have tested this across Solaris 2.6-2.8 and it works fine.
I'm marking this as bogus, reopen if you still 
have problems.

-Jason



 [2000-11-20 02:02 UTC] Alan at Halachmi dot net
I have added the following line to my php.ini file, as it was not included      
in the php.ini-dist for 4.0.3pl1:                                               
allow_url_fopen         =       On;                                             
                                                                                
This did not change the behavior or the error.  I ran a truss to ensure         
that the apxs was loaded the correct php.ini file and the correct               
libs.  From the output of truss, I am certain that the correct DSO and          
php.ini are being read.    
 [2000-11-20 02:38 UTC] jason@php.net
Sorry, I was wrong, the ini directive did not make 4.0.3pl1
Ill take a look into this.


-Jason
 [2000-11-20 03:11 UTC] Alan at Halachmi dot net
I compiled the CGI version of 4.0.3pl1 and the scripts noted in this bug DOES run in the CGI version.
 [2000-11-20 03:19 UTC] jason@php.net
Can you try trussing apache in single process mode ( truss ./httpd -X ). Request the script, and see if it actually makes a socket connect request. From your description, it most likely will not.

Also can you give me the details of your compile environment( what make and cc you are using)

Im sure you have thought of this, but is there a possibility of a corrupt build? Have you tried removing config.cache, reconfiguring, and rerunning?

Check your php_config.h to verify that
#define PHP_URL_FOPEN 1 exists.

If all of these check out try building a seperate tree as a standalone cgi, run ./php < test-furl.php and see if you get the same results. 

-Jason
 [2000-11-20 03:35 UTC] jason@php.net
I just noticed your update about the cgi version working. When you build php 4.0.3pl1 for apxs, can you verify
the define statement I listed above exists in php_config.h? I just want to rule out the possibility of a build problem. The other information I requested would be helpful as well

-Jason
 [2000-11-20 04:07 UTC] Alan at Halachmi dot net
1)
truss -feal -o /tmp/output /usr/local/bin/httpd -X                              
[ Attached as output.tar.gz - Look for filetest.php ] 

2)
#gcc -v                                                                         
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.2/specs     
gcc version 2.95.2 19991024 (release)                                           
                                                                                
#uname -a                                                                       
SunOS egotist 5.8 Generic_108528-01 sun4u sparc SUNW,Ultra-5_10

3)I've recompiled almost half a dozen times... I've razed the directory and       
tar zxvf'ed twice.  I'm pretty sure it's a good binary.                         
                                                                                
php-de>Check your php_config.h to verify that                                   
php-de>#define PHP_URL_FOPEN 1 exists.                                          
                                                                                
--- snip ---                                                                    
#define DEFAULT_SHORT_OPEN_TAG 1                                                
                                                                                
/*   */                                                                         
#define DEFAULT_SHORT_OPEN_TAG 1                                                
                                                                                
/*   */                                                                         
#define PHP_URL_FOPEN 1                                                         
                                                                      
/*   */                                                                         
#define PHP_URL_FOPEN 1                                                         
                                                                                
/* Whether you have dmalloc */   
/* #undef HAVE_DMALLOC */  
--- snip ---

4)
Yup... Worked that way.  (under cgi php)
 [2000-11-20 04:40 UTC] Alan at Halachmi dot net
More interesting information... It appears that the outbound connection is never actually made...
This is from a truss of an fopen on www.php.net:
14354/1:        resolvepath("/home/pkw/devilnet/v1.0/dev/htdocs/filetest.php", "/home/pkw/devilnet/v1.0/dev/htdocs/filetest.php", 1024) = 47
14354/1:        ioctl(6, TCGETA, 0xFFBEE33C)                    Err#25 ENOTTY
14354/1:        fstat64(6, 0xFFBECBD0)                          = 0
14354/1:            d=0x02200007 i=275213 m=0100644 l=1  u=1001  g=4     sz=283
14354/1:                at = Nov 20 04:21:57 EST 2000  [ 974712117 ]
14354/1:                mt = Nov 20 03:55:45 EST 2000  [ 974710545 ]
14354/1:                ct = Nov 20 03:55:45 EST 2000  [ 974710545 ]
14354/1:            bsz=8192  blks=2     fs=ufs
14354/1:        ioctl(6, TCGETA, 0xFFBECB5C)                    Err#25 ENOTTY
14354/1:        read(6, " < ?\n\t $ u r l   =   "".., 8192)     = 283
14354/1:        read(6, 0x00303264, 8192)                       = 0
14354/1:        ioctl(6, TCGETA, 0xFFBECC34)                    Err#25 ENOTTY
14354/1:        llseek(6, 0, SEEK_CUR)                          = 283
14354/1:        close(6)                                        = 0
14354/1:        so_socket(2, 1, 0, "", 1)                       = 6
14354/1:        connect(6, 0x001378B8, 16, 1)                   = 0
14354/1:                AF_INET  name = 127.0.0.1  port = 53
14354/1:        send(6, "96 g01\0\001\0\0\0\0\0\0".., 29, 0)    = 29
14354/1:        poll(0xFFBE97F8, 1, 5000)                       = 1
14354/1:                fd=6  ev=POLLRDNORM rev=POLLRDNORM
14354/1:        recvfrom(6, "96 g8180\001\0\0\001\0\0".., 1024, 0, 0xFFBE9A00, 0xFFBE9950) = 93
14354/1:                AF_INET  from = 127.0.0.1  port = 53
14354/1:        close(6)                                        = 0
14354/1:        open("/etc/hosts", O_RDONLY)                    = 6
14354/1:        fcntl(6, F_SETFD, 0x00000001)                   = 0
14354/1:        fstat64(6, 0xFFBEAFC0)                          = 0
14354/1:            d=0x02200000 i=10689 m=0100444 l=1  u=0     g=3     sz=152
14354/1:                at = Nov 20 04:21:57 EST 2000  [ 974712117 ]
14354/1:                mt = Sep 16 16:58:39 EDT 2000  [ 969137919 ]
14354/1:                ct = Sep 17 14:25:15 EDT 2000  [ 969215115 ]
14354/1:            bsz=8192  blks=2     fs=ufs
14354/1:        ioctl(6, TCGETA, 0xFFBEAF4C)                    Err#25 ENOTTY
14354/1:        read(6, " #\n #   I n t e r n e t".., 8192)     = 152
14354/1:        read(6, 0x002FF254, 8192)                       = 0
14354/1:        llseek(6, 0, SEEK_CUR)                          = 152
14354/1:        close(6)                                        = 0
14354/1:        shutdown(-1, 0, 1)                              Err#9 EBADF
14354/1:        close(-1)                                       Err#9 EBADF
14354/1:        alarm(300)                                      = 300
14354/1:        alarm(0)                                        = 300
14354/1:        chdir("/")                                      = 0
14354/1:        umask(022)                                      = 022
14354/1:        alarm(0)                                        = 0
14354/1:        poll(0xFFBEF808, 1, 0)                          = 0
14354/1:                fd=5  ev=POLLRDNORM rev=0
14354/1:        write(5, " H T T P / 1 . 1   2 0 0".., 354)     = 354
14354/1:        time()                                          = 974712422
14354/1:        open("/usr/share/lib/zoneinfo/US/Eastern", O_RDONLY) = 6
14354/1:        read(6, " T Z i f\0\0\0\0\0\0\0\0".., 8192)     = 1250
14354/1:        close(6)                                        = 0
14354/1:        write(55, " 1 5 2 . 1 6 . 2 4 8 . 1".., 84)     = 84
14354/1:        alarm(30)                                       = 0
14354/1:        shutdown(5, 1, 1)                               = 0
14354/1:        poll(0xFFBEF680, 1, 2000)                       = 1
14354/1:                fd=5  ev=POLLRDNORM rev=POLLRDNORM
14354/1:        read(5, 0xFFBEF7B8, 512)                        = 0
14354/1:        close(5)

--> No connection made to www.php.net
Now... Watch what happens if I substitute the DNS name for the IP:

14377/1:     resolvepath("/home/pkw/devilnet/v1.0/dev/htdocs/filetest.php", "/home/pkw/devilnet/v1.0/dev/htdocs/filetest.php", 1024) = 47
14377/1:        ioctl(6, TCGETA, 0xFFBEE33C)                    Err#25 ENOTTY
14377/1:        fstat64(6, 0xFFBECBD0)                          = 0
14377/1:            d=0x02200007 i=275213 m=0100644 l=1  u=1001  g=4     sz=287
14377/1:                at = Nov 20 04:31:36 EST 2000  [ 974712696 ]
14377/1:                mt = Nov 20 04:31:30 EST 2000  [ 974712690 ]
14377/1:                ct = Nov 20 04:31:30 EST 2000  [ 974712690 ]
14377/1:            bsz=8192  blks=2     fs=ufs
14377/1:        ioctl(6, TCGETA, 0xFFBECB5C)                    Err#25 ENOTTY
14377/1:        read(6, " < ?\n\t $ u r l   =   "".., 8192)     = 287
14377/1:        read(6, 0x00303264, 8192)                       = 0
14377/1:        ioctl(6, TCGETA, 0xFFBECC34)                    Err#25 ENOTTY
14377/1:        llseek(6, 0, SEEK_CUR)                          = 287
14377/1:        close(6)                                        = 0
14377/1:        shutdown(-1, 0, 1)                              Err#9 EBADF
14377/1:        close(-1)                                       Err#9 EBADF
14377/1:        alarm(300)                                      = 300
14377/1:        alarm(0)                                        = 300
14377/1:        chdir("/")                                      = 0
14377/1:        umask(022)                                      = 022
14377/1:        alarm(0)                                        = 0
14377/1:        poll(0xFFBEF808, 1, 0)                          = 0
14377/1:                fd=5  ev=POLLRDNORM rev=0
14377/1:        write(5, " H T T P / 1 . 1   2 0 0".., 362)     = 362
14377/1:        time()                                          = 974712713
14377/1:        open("/usr/share/lib/zoneinfo/US/Eastern", O_RDONLY) = 6
14377/1:        read(6, " T Z i f\0\0\0\0\0\0\0\0".., 8192)     = 1250
14377/1:        close(6)                                        = 0
14377/1:        write(55, " 1 5 2 . 1 6 . 2 4 8 . 1".., 84)     = 84
14377/1:        alarm(30)                                       = 0
14377/1:        shutdown(5, 1, 1)                               = 0
14377/1:        poll(0xFFBEF680, 1, 2000)                       = 1
14377/1:                fd=5  ev=POLLRDNORM rev=POLLRDNORM
14377/1:        read(5, 0xFFBEF7B8, 512)                        = 0
14377/1:        close(5)                                        = 0
14377/1:        alarm(0)                                        = 30

--> Note: There still is no outbound connection, even though DNS was taken out of the picture.

 [2000-11-20 07:01 UTC] hholzgra@php.net
   $url = "http://www.php.net/index.html";
   $fp = file($url);

is simply wrong usage, try 

   $url = "http://www.php.net/index.html";
   $fp = fopen($url,"r");
   $file_contents = file($fp);

instead

  
 [2000-11-20 09:54 UTC] jason@php.net
Actually he is using the correct usage. File takes a string calls fopen-wrappers to open a fp, and then returns an array

Alan, I will see If I can reproduce your findings

-Jason

 [2000-11-20 10:22 UTC] hholzgra@php.net
ooops, looks like this was to early in the morning :(

but it might still be of interest what the output and
error messages look like if you take your code snippet
and just replace the '$fp=file($url)' line with '$fp=fopen($url,"r")'

it seems like file() fails to open the URL but still tries 
to read from the file handle that is not valid in this case,
so that 'bad file number' is reported instead of the real cause
if failure ...

PS: i don't think this is realy related to it, but www.php.net/index.html
does not exist. trying to GET it will result in a 404 status and an 
error page showing some search results, you should try
www.php.net/index.php instead, just to be sure ...
 [2000-11-20 11:45 UTC] jason@php.net
Ya you should be looking up index.php as hholzgra suggests,
but in looking at your truss output, It is behaving as if url wrappers was compiled out.

Can you try this test?

1. Lets verify the source is compiled correctly. 
add --enable-debug to your php configure. 
a. Remake and make sure that gcc is being called with -g. b. do a gdb httpd
c. run -X
d. hit ctrl-c (it might take a while to catch)
e. break php_fopen_wrapper
f. cont
g. open your test-script while its waiting
h. it should break when it trys to make the file request
i. hit n to step to the next line of code
j. see if it ever hits  if(!(options & IGNORE_URL)){
k. if url wrappers is not compiled you would get
   if (options & USE_PATH........ instead









 [2000-12-30 19:55 UTC] sniper@php.net
No feedback. Reopen if this really doesn't work with correct url.

--Jani
 [2000-12-30 20:52 UTC] Alan at Halachmi dot net
Ok - I seem to have tracked this down.  I added debug statements throughout
PHP to see exactly where it was failing, and found that it is happening in:
php_network_getaddresses in main/network.c.  Basically, in
php_fopen_url_wrap_http in ext/standard/http_fopen_wrapper.c, I modified the
function to let me know where it was bailing:

*socketd = php_hostconnect(resource->host, resource->port, SOCK_STREAM, 0);
    if (*socketd == -1) {
        php_error(E_WARNING, "php_hostconnect failed");
        SOCK_FCLOSE(*socketd);
        *socketd = 0;
        free_url(resource);
        return NULL;
    }

It does get to that php_error message, and so after looking through
php_hostconnect, I found that our problem was a failed lookup in
php_network_getaddresses.  Here is my slightly modified code that prints out
an error message when getaddrinfo fails:
static int php_network_getaddresses(const char *host, struct sockaddr
***sal)
{
  int err;
  struct sockaddr **sap;

  if (host != NULL) {
#ifdef HAVE_GETADDRINFO
    struct addrinfo hints, *res, *sai;
    int n;

    memset( &hints, '\0', sizeof(hints) );
    hints.ai_family = AF_UNSPEC;
    if ((err = getaddrinfo(host, NULL, &hints, &res))) {
      php_error(E_WARNING, "getaddrinfo failed for host: %s with error: %d",
host, err);
      php_error(E_WARNING, gai_strerror(err));
      return -1;
    }
I took a look at php 4.0.2 (which is working fine for us), and saw that it
doesn't use getaddrinfo for hostname lookups, it uses the gethostbyname
function.

I'm not familiar enough with the getaddrinfo call to tell you if it is
failing because of a bug in Solaris, a problem in our system configuration,
or if it is a problem with the php source.

I have created two testpages that are failing for us, one with a numeric IP
address and another with a hostname that must be resolved.  You can view
them here:

Use of the "file" function on a numeric address:
http://pkw.devilnet.duke.edu/testweather.php

Use of the "file" function on a hostname that must be resolved:
http://dev.dspconline.org/scripts/update_weather.php

I hope this helps.
 [2001-01-22 22:19 UTC] jimw@php.net
reclassifying.
 [2001-07-04 14:53 UTC] jason@php.net
Never able to reproduce, try  4.0.6 and reopen if still a problem.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 23:01:28 2024 UTC