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