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