]> CyberLeo.Net >> Repos - Github/YOURLS.git/blob - includes/functions-http.php
Fix end of line
[Github/YOURLS.git] / includes / functions-http.php
1 <?php
2 // TODO: improve this.
3 // yourls_get_http_transport: use static vars
4 // yourls_get_remote_content: return array( content, status, code )
5
6 /**
7  * Determine best transport for GET request. Return 'curl', 'fopen', 'fsockopen' or false if nothing works
8  *
9  * Order of preference: curl, fopen, fsockopen.
10  *
11  */
12 function yourls_get_http_transport( $url ) {
13
14         $transports = array();
15         
16         $scheme = parse_url( $url, PHP_URL_SCHEME );
17         $is_ssl = ( $scheme == 'https' || $scheme == 'ssl' );
18
19         // Test transports by order of preference, best first
20
21         // curl
22         if( function_exists( 'curl_init' ) && function_exists( 'curl_exec' ) )
23                 $transports[]= 'curl';
24
25         // fopen. Doesn't work with https?
26         if( !$is_ssl && function_exists( 'fopen' ) && ini_get( 'allow_url_fopen' ) )
27                 $transports[]= 'fopen';
28                 
29         // fsock
30         if( function_exists( 'fsockopen' ) )
31                 $transports[]= 'fsockopen';
32         
33         $best = ( $transports ? array_shift( $transports ) : false );
34         
35         return yourls_apply_filter( 'get_http_transport', $best, $transports );
36 }
37
38 /**
39  * Get remote content via a GET request using best transport available
40  *
41  * Returns $content (might be an error message) or false if no transport available
42  *
43  */
44 function yourls_get_remote_content( $url,  $maxlen = 4096, $timeout = 5 ) {
45         $url = yourls_sanitize_url( $url );
46
47         $transport = yourls_get_http_transport( $url );
48         if( $transport ) {
49                 $content = call_user_func( 'yourls_get_remote_content_'.$transport, $url, $maxlen, $timeout );
50         } else {
51                 $content = false;
52         }
53         
54         return yourls_apply_filter( 'get_remote_content', $content, $url, $maxlen, $timeout );
55 }
56
57 /**
58  * Get remote content using curl. Needs sanitized $url. Returns $content or false
59  *
60  */
61 function yourls_get_remote_content_curl( $url, $maxlen = 4096, $timeout = 5 ) {
62         
63     $ch = curl_init();
64         curl_setopt( $ch, CURLOPT_URL, $url );
65     curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, $timeout );
66     curl_setopt( $ch, CURLOPT_TIMEOUT, $timeout );
67     curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
68     curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1 ); // follow redirects...
69     curl_setopt( $ch, CURLOPT_MAXREDIRS, 3 ); // ... but not more than 3
70     curl_setopt( $ch, CURLOPT_USERAGENT, yourls_http_user_agent() );
71     curl_setopt( $ch, CURLOPT_RANGE, "0-{$maxlen}" ); // Get no more than $maxlen
72     curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 ); // dont check SSL certificates
73         curl_setopt( $ch, CURLOPT_HEADER, 0 );
74
75     $response = curl_exec( $ch );
76         
77         if( !$response || curl_error( $ch ) ) {
78                 //$response = 'Error: '.curl_error( $ch );
79                 return false;
80         }
81
82         curl_close( $ch );
83
84         return substr( $response, 0, $maxlen ); // substr in case CURLOPT_RANGE not supported
85 }
86
87 /**
88  * Get remote content using fopen. Needs sanitized $url. Returns $content or false
89  *
90  */
91 function yourls_get_remote_content_fopen( $url, $maxlen = 4096, $timeout = 5 ) {
92         $content = false;
93         
94         $initial_timeout = @ini_set( 'default_socket_timeout', $timeout );
95         $initial_user_agent = @ini_set( 'user_agent', yourls_http_user_agent() );
96
97         // Basic error reporting shortcut
98         set_error_handler( create_function('$code, $string', 'global $ydb; $ydb->fopen_error = $string;') );
99         
100         $fp = fopen( $url, 'r');
101         if( $fp !== false ) {
102                 $buffer = min( $maxlen, 4096 );
103                 while ( !feof( $fp ) && !( strlen( $content ) >= $maxlen ) ) {
104                         $content .= fread( $fp, $buffer );
105                 }
106                 fclose( $fp );
107         }
108
109         if( $initial_timeout !== false )
110                 @ini_set( 'default_socket_timeout', $initial_timeout ); 
111         if( $initial_user_agent !== false )
112                 @ini_set( 'user_agent', $initial_user_agent );
113                 
114
115         restore_error_handler();
116         
117         if( !$content ) {
118                 //global $ydb;
119                 //$content = 'Error: '.strip_tags( $ydb->fopen_error );
120                 return false;
121         }
122         
123         return $content;
124 }
125
126 /**
127  * Get remote content using fsockopen. Needs sanitized $url. Returns $content or false
128  *
129  */
130 function yourls_get_remote_content_fsockopen( $url, $maxlen = 4096, $timeout = 5 ) {
131         // get the host name and url path
132         $parsed_url = parse_url( $url );
133
134         $host = $parsed_url['host'];
135         if ( isset( $parsed_url['path'] ) ) {
136                 $path = $parsed_url['path'];
137         } else {
138                 $path = '/'; // the url is pointing to the host like http://www.mysite.com
139         }
140
141         if ( isset( $parsed_url['query'] ) ) {
142                 $path .= '?' . $parsed_url['query'];
143         }
144
145         if ( isset( $parsed_url['port'] ) ) {
146                 $port = $parsed_url['port'];
147         } else {
148                 $port = '80';   
149         }
150
151         $response = false;
152
153         // connect to the remote server
154         $fp = @fsockopen( $host, $port, $errno, $errstr, $timeout );
155         var_dump( $errno, $errstr );
156         if( $fp !== false ) {
157                 // send some fake headers to mimick a standard browser
158                 fputs($fp, "GET $path HTTP/1.0\r\n" .
159                         "Host: $host\r\n" . 
160                         "User-Agent: " . yourls_http_user_agent() . "\r\n" .
161                         "Accept: */*\r\n" .
162                         "Accept-Language: en-us,en;q=0.5\r\n" .
163                         "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" .
164                         "Keep-Alive: 300\r\n" .
165                         "Connection: keep-alive\r\n" .
166                         "Referer: http://$host\r\n\r\n");
167
168                 // retrieve the response from the remote server
169                 $buffer = min( $maxlen, 4096 );
170                 while ( !feof( $fp ) && !( strlen( $response ) >= $maxlen ) ) { // get more or less $maxlen bytes (between $maxlen and ($maxlen + ($maxlen-1)) actually)
171                         $response .= fread( $fp, $buffer );
172                 }
173
174                 fclose( $fp );
175         } else {
176                 //$response = trim( "Error: #$errno. $errstr" );
177                 return false;
178         }
179
180         // return the file content
181         return $response;
182 }
183
184 /**
185  * Return funky user agent string
186  *
187  */
188 function yourls_http_user_agent() {
189         return yourls_apply_filter( 'http_user_agent', 'YOURLS v'.YOURLS_VERSION.' +http://yourls.org/ (running on '.YOURLS_SITE.')' );
190 }