How to use PHP proxy for CORS? - php

I am trying to use a weather API which returns the data in xml format. I was using a third-party proxy server to get around CORS issues but that service is no longer running. I am using jquery/ajax to get the data like this:
function getMetarToTable(){
var stationt="KJFK";
$.ajax({
type: "GET",
url: 'proxy.php',
crossDomain: true,
data: {'stationString': stationt},
datatype: "xml",
headers: {
'X-Proxy-URL': 'https://www.aviationweather.gov/adds/dataserver_current/httpparam?datasource=metars&requestType=retrieve&format=xml&mostRecentForEachStation=constraint&hoursBeforeNow=1.25',
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('Error: ' + errorThrown);
},
success: function(xml) {
$("#metarweatherpage").html('');
$(xml).find('METAR').each(function(){
var sRawtext = $(this).find('raw_text').text();
var sStationid = $(this).find('station_id').text();
$("#metarweatherpage").append('<p><h2>'+sStationid+'</h2></p><p>'+sRawtext+'</p>');
});
},
});
};
PHP - proxy.php
<?php
if( ! isset($whitelist))
$whitelist = [];
if( ! isset($curl_maxredirs))
$curl_maxredirs = 10;
if( ! isset($curl_timeout))
$curl_timeout = 30;
// Get stuff
$headers = getallheaders();
$method = __('REQUEST_METHOD', $_SERVER);
$url = __('X-Proxy-Url', $headers);
$cookie = __('X-Proxy-Cookie', $headers);
// Check that we have a URL
if( ! $url)
http_response_code(400) and exit("X-Proxy-Url header missing");
// Check that the URL looks like an absolute URL
if( ! parse_url($url, PHP_URL_SCHEME))
http_response_code(403) and exit("Not an absolute URL: $url");
// Check referer hostname
if( ! parse_url(__('Referer', $headers), PHP_URL_HOST) == $_SERVER['HTTP_HOST'])
http_response_code(403) and exit("Invalid referer");
// Check whitelist, if not empty
if( ! empty($whitelist) and ! array_reduce($whitelist, 'whitelist', [$url, false]))
http_response_code(403) and exit("Not whitelisted: $url");
// Remove ignored headers and prepare the rest for resending
$ignore = ['Cookie', 'Host', 'X-Proxy-URL'];
$headers = array_diff_key($headers, array_flip($ignore));
if($cookie)
$headers['Cookie'] = $cookie;
foreach($headers as $key => &$value)
$value = "$key: $value";
// Init curl
$curl = curl_init();
do
{
// Set generic options
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_HEADER => TRUE,
CURLOPT_TIMEOUT => $curl_timeout,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_MAXREDIRS => $curl_maxredirs,
]);
// Method specific options
switch($method)
{
case 'HEAD':
curl_setopt($curl, CURLOPT_NOBODY, TRUE);
break;
case 'GET':
break;
case 'PUT':
case 'POST':
case 'DELETE':
default:
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($curl, CURLOPT_POSTFIELDS, file_get_contents('php://input'));
break;
}
// Perform request
ob_start();
curl_exec($curl) or http_response_code(500) and exit(curl_error($curl));
$out = ob_get_clean();
// HACK: If for any reason redirection doesn't work, do it manually...
$url = curl_getinfo($curl, CURLINFO_REDIRECT_URL);
}
while($url and --$maxredirs > 0);
// Get curl info and close handler
$info = curl_getinfo($curl);
curl_close($curl);
// Remove any existing headers
header_remove();
// Use gz, if acceptable
ob_start('ob_gzhandler');
// Output headers
$header = substr($out, 0, $info['header_size']);
array_map('header', explode("\r\n", $header));
// And finally the body
echo substr($out, $info['header_size']);
// Helper functions
function __($key, array $array, $default = null)
{
return array_key_exists($key, $array) ? $array[$key] : $default;
}
function whitelist($carry, $item)
{
static $url;
if(is_array($carry))
{
$url = parse_url($carry[0]);
$url['raw'] = $carry[0];
$carry = $carry[1];
}
// Equals the full URL
if(isset($item[0]))
return $carry or $url['raw'] == $item[0];
// Regex matches the full URL
if(isset($item['regex']))
return $carry or preg_match($item['regex'], $url['raw']);
// Select components matches same components in the URL
return $carry or $item == array_intersect_key($url, $item);
}
I get a 400 Bad Request error and the response is "X-Proxy-Url header missing".

Bit late to the party, but it's pretty obvious what's going on.
PHP array indices act as hash tables, so they are case sensitive.
In your client side js you set the request header as 'X-Proxy-URL':, however, in your server-side php you check for 'X-Proxy-Url', notice the URL vs Url part.

Related

HTTP Requests made with file_get_contents() share the same session data?

I've got a problem...
I've a MVC-like framework and the redirect mechanism allows me too get snippets of HTML code generated by PHP on a remote host.
I'm getting these snippets by using the file_get_contents() function, with allow_url_fopen turned on.
The problem is the fact I use session data inside these code fragments and the session data is being lost every time. I'm assuming this new request is not sharing the same session data and therefore I need a way to get these fragments without losing my session data.
Any suggestions?
If the files your accessing are on the same server as the calling file then you might as well use include(); like #user574632's answer.
But if not, to keep the session you will need to handle the cookies the server sends;
Sessions are cookie based, server sets the session cookie your browser picks it up and uses it for all subsequent requests.
By default file_get_contents wont handle cookies, so your need to grab the header from the server by accessing $http_response_header array and then match with regex the Set-Cookie: header then store that and on following requests use the cookie and create a stream context with the cookie added to the header and pass that to fgc:
<?php
function get_cookies() {
//check cookies folder - or make it
if(!file_exists('./cookies/')){
mkdir('./cookies/', 0755, true);
}
$return = null;
foreach(glob("./cookies/*.txt") as $file) {
$return .= file_get_contents($file).';';
}
return $return;
}
function save_cookies($http_response_header) {
print_r($http_response_header);
foreach($http_response_header as $header) {
if(substr($header, 0, 10) == 'Set-Cookie'){
if(preg_match('#Set-Cookie: (([^=]+)=[^;]+)#i', $header, $matches)) {
$fp = fopen('./cookies/'.$matches[2].'.txt', 'w');
fwrite($fp, $matches[1]);
fclose($fp);
}
}
}
}
$opts = array('http' =>
array('header'=>'Cookie: '.get_cookies()."\r\n")
);
$context = stream_context_create($opts);
$contents = file_get_contents('http://mywebsite.com/snippets/', false, $context);
save_cookies($http_response_header);
echo $contents;
?>
Alternatively you should use curl instead its faster and handles cookies fine.
So something like the following, use curl and then revert to fgc if curl is not present, all wrapped up with cookie support in a class, so the 3 functions are contained:
<?php
//example usage
echo new curl_get_contents('http://example.com/page_that_needs_sessions');
class curl_get_contents{
public $result;
function __construct($url){
$this->curl_rev_fgc($url);
}
function __toString(){
return $this->result;
}
private function get_cookies() {
$return = null;
foreach(glob("./cookies/*.txt") as $file) {
$return .= file_get_contents($file).';';
}
return $return;
}
private function save_cookies($http_response_header) {
foreach($http_response_header as $header) {
if(substr($header, 0, 10) == 'Set-Cookie'){
if(preg_match('#Set-Cookie: (([^=]+)=[^;]+)#i', $header, $matches)) {
$fp = fopen('./'.$matches[2].'.txt', 'w');
fwrite($fp, $matches[1]);
fclose($fp);
}
}
}
}
private function curl_rev_fgc($url){
//check cookies folder - or make it
if(!file_exists('./cookies')){
mkdir('./cookies/', 0755, true);
}
$usragent = 'Mozilla/5.0 (compatible; Yourbot/0.1; +https://yoursite/bot.html)';
//Check curl is installed or revert to file_get_contents()
$curl = function_exists('curl_init') ? true : false;
if($curl){
$opts = array(
'http' => array(
'method' => "GET",
'header' => 'Cookie: '.$this->get_cookies().'\r\n', // cookie in fgc support
'user_agent' => $usragent)
);
$context = stream_context_create($opts);
$result = #file_get_contents($url, false, $context);
$this->save_cookies($http_response_header);
if(empty($result)){
$this->result = 'Error fetching: '.htmlentities($url);
}else{
$this->result = $result;
}
return;
}
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
curl_setopt($curl, CURLOPT_USERAGENT, $usragent);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
if(!file_exists('./cookies/curl.txt')){
file_put_contents('./cookies/curl.txt',null);
}
curl_setopt($curl, CURLOPT_COOKIEFILE, './cookies/curl.txt');
curl_setopt($curl, CURLOPT_COOKIEJAR, './cookies/curl.txt');
$result = curl_exec($curl);
if(empty($result)){
$this->result = 'Error fetching: '.htmlentities($url);
}else{
$this->result = $result;
}
curl_close($curl);
return;
}
}
?>
Use include instead. If you need to read the output into a variable to display later/elsewhere in the code, as suggested in the comments, use the output buffer:
ob_start();
include('path/to/file.php');
$included = ob_get_clean();
//nothing has been output to the browser yet
//later on
echo $included;

PHP PROXY having tough time for "POST" Data but able to use GET

http://benalman.com/code/projects/php-simple-proxy/examples/simple/
I am exactly following above Blog for Using PHP Proxy setting for Cross Domain. I am using XHR. I am able to successful to use GET method. But While using POST I am getting error CODE 200 and Empty XML in reply object.
However when i am using the simple XHR Code without phpproxy with below setting of google. chrome.exe --disable-web-security. I am successful for GET and POST both.
I am sure i am wrong somewhere in XHR.Send(Mydata). But if i was wrong in this method than i could not have been able to send success full post method.
Please help. I am novice in PHP i am sure i am missing something in PHP code that would enable me to post successfull. Below is crux of PHP code.
$enable_jsonp = true;
$enable_native = false;
$valid_url_regex = '/.*/';
$url = $_GET['url'];
if (!$url)
{
// Passed url not specified.
$contents = 'ERROR: url not specified';
$status = array(
'http_code' => 'ERROR'
);
}
else if (!preg_match($valid_url_regex, $url)) {
// Passed url doesn't match $valid_url_regex.
$contents = 'ERROR: invalid url';
$status = array(
'http_code' => 'ERROR'
);
}
else
{
$ch = curl_init($url);
if (strtolower($_SERVER['REQUEST_METHOD']) == 'post')
{
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST);
}
if ($_GET['send_cookies'])
{
$cookie = array();
foreach ($_COOKIE as $key => $value)
{
$cookie[] = $key . '=' . $value;
}
if ($_GET['send_session'])
{
$cookie[] = SID;
}
$cookie = implode('; ', $cookie);
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
}
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, $_GET['user_agent'] ? $_GET['user_agent'] : $_SERVER['HTTP_USER_AGENT']);
list($header, $contents) = preg_split('/([\r\n][\r\n])\\1/', curl_exec($ch), 2);
$status = curl_getinfo($ch);
curl_close($ch);
}
// Split header text into an array.
$header_text = preg_split('/[\r\n]+/', $header);
if ($_GET['mode'] == 'native')
{
if (!$enable_native)
{
$contents = 'ERROR: invalid mode';
$status = array(
'http_code' => 'ERROR'
);
}
// Propagate headers to response.
foreach ($header_text as $header)
{
if (preg_match('/^(?:Content-Type|Content-Language|Set-Cookie):/i', $header))
{
header($header);
}
}
print $contents;
}
else
{
// $data will be serialized into JSON data.
$data = array();
// Propagate all HTTP headers into the JSON data object.
if ($_GET['full_headers'])
{
$data['headers'] = array();
foreach ($header_text as $header)
{
preg_match('/^(.+?):\s+(.*)$/', $header, $matches);
if ($matches)
{
$data['headers'][$matches[1]] = $matches[2];
}
}
}
// Propagate all cURL request / response info to the JSON data object.
if ($_GET['full_status'])
{
$data['status'] = $status;
}
else
{
$data['status'] = array();
$data['status']['http_code'] = $status['http_code'];
}
// Set the JSON data object contents, decoding it from JSON if possible.
$decoded_json = json_decode($contents);
$data['contents'] = $decoded_json ? $decoded_json : $contents;
// Generate appropriate content-type header.
$is_xhr = strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
header('Content-type: application/' . ($is_xhr ? 'json' : 'x-javascript'));
// Get JSONP callback.
$jsonp_callback = $enable_jsonp && isset($_GET['callback']) ? $_GET['callback'] : null;
// Generate JSON/JSONP string`enter code here`
$json = json_encode($data);
print $jsonp_callback ? "$jsonp_callback($json)" : $json;
}

HTTP response code after redirect

There is a redirect to server for information and once response comes from server, I want to check HTTP code to throw an exception if there is any code starting with 4XX. For that I need to know how can I get only HTTP code from header? Also here redirection to server is involved so I afraid curl will not be useful to me.
So far I have tried this solution but it's very slow and creates script time out in my case. I don't want to increase script time out period and wait longer just to get an HTTP code.
Thanks in advance for any suggestion.
Your method with get_headers and requesting the first response line will return the status code of the redirect (if any) and more importantly, it will do a GET request which will transfer the whole file.
You need only a HEAD request and then to parse the headers and return the last status code. Following is a code example that does this, it's using $http_response_header instead of get_headers, but the format of the array is the same:
$url = 'http://example.com/';
$options['http'] = array(
'method' => "HEAD",
'ignore_errors' => 1,
);
$context = stream_context_create($options);
$body = file_get_contents($url, NULL, $context);
$responses = parse_http_response_header($http_response_header);
$code = $responses[0]['status']['code']; // last status code
echo "Status code (after all redirects): $code<br>\n";
$number = count($responses);
$redirects = $number - 1;
echo "Number of responses: $number ($redirects Redirect(s))<br>\n";
if ($redirects)
{
$from = $url;
foreach (array_reverse($responses) as $response)
{
if (!isset($response['fields']['LOCATION']))
break;
$location = $response['fields']['LOCATION'];
$code = $response['status']['code'];
echo " * $from -- $code --> $location<br>\n";
$from = $location;
}
echo "<br>\n";
}
/**
* parse_http_response_header
*
* #param array $headers as in $http_response_header
* #return array status and headers grouped by response, last first
*/
function parse_http_response_header(array $headers)
{
$responses = array();
$buffer = NULL;
foreach ($headers as $header)
{
if ('HTTP/' === substr($header, 0, 5))
{
// add buffer on top of all responses
if ($buffer) array_unshift($responses, $buffer);
$buffer = array();
list($version, $code, $phrase) = explode(' ', $header, 3) + array('', FALSE, '');
$buffer['status'] = array(
'line' => $header,
'version' => $version,
'code' => (int) $code,
'phrase' => $phrase
);
$fields = &$buffer['fields'];
$fields = array();
continue;
}
list($name, $value) = explode(': ', $header, 2) + array('', '');
// header-names are case insensitive
$name = strtoupper($name);
// values of multiple fields with the same name are normalized into
// a comma separated list (HTTP/1.0+1.1)
if (isset($fields[$name]))
{
$value = $fields[$name].','.$value;
}
$fields[$name] = $value;
}
unset($fields); // remove reference
array_unshift($responses, $buffer);
return $responses;
}
For more information see: HEAD first with PHP Streams, at the end it contains example code how you can do the HEAD request with get_headers as well.
Related: How can one check to see if a remote file exists using PHP?
Something like:
$ch = curl_init();
$httpcode = curl_getinfo ($ch, CURLINFO_HTTP_CODE );
You should try the HttpEngine Class.
Hope this helps.
--
EDIT
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, $your_agent_variable);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, $your_referer);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$output = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpcode ...)
The solution you found looks good. If the server is not able to send you the http headers in time your problem is that the other server is broken or under very heavy load.

PHP: Check if URL redirects?

I have implemented a function that runs on each page that I want to restrict from non-logged in users. The function automatically redirects the visitor to the login page in the case of he or she is not logged in.
I would like to make a PHP function that is run from a exernal server and iterates through a number of set URLs (array with URLs that is for each protected site) to see if they are redirected or not. Thereby I could easily make sure if protection is up and running on every page.
How could this be done?
Thanks.
$urls = array(
'http://www.apple.com/imac',
'http://www.google.com/'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
foreach($urls as $url) {
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
// line endings is the wonkiest piece of this whole thing
$out = str_replace("\r", "", $out);
// only look at the headers
$headers_end = strpos($out, "\n\n");
if( $headers_end !== false ) {
$out = substr($out, 0, $headers_end);
}
$headers = explode("\n", $out);
foreach($headers as $header) {
if( substr($header, 0, 10) == "Location: " ) {
$target = substr($header, 10);
echo "[$url] redirects to [$target]<br>";
continue 2;
}
}
echo "[$url] does not redirect<br>";
}
I use curl and only take headers, after I compare my url and url from header curl:
$url="http://google.com";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, '60'); // in seconds
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$res = curl_exec($ch);
if(curl_getinfo($ch)['url'] == $url){
echo "not redirect";
}else {
echo "redirect";
}
You could always try adding:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
since 302 means it moved, allow the curl call to follow it and return whatever the moved url returns.
Getting the headers with get_headers() and checking if Location is set is much simpler.
$urls = [
"https://example-1.com",
"https://example-2.com"
];
foreach ($urls as $key => $url) {
$is_redirect = does_url_redirect($url) ? 'yes' : 'no';
echo $url . ' is redirected: ' . $is_redirect . PHP_EOL;
}
function does_url_redirect($url){
$headers = get_headers($url, 1);
if (!empty($headers['Location'])) {
return true;
} else {
return false;
}
}
I'm not sure whether this really makes sense as a security check.
If you are worried about files getting called directly without your "is the user logged in?" checks being run, you could do what many big PHP projects do: In the central include file (where the security check is being done) define a constant BOOTSTRAP_LOADED or whatever, and in every file, check for whether that constant is set.
Testing is great and security testing is even better, but I'm not sure what kind of flaw you are looking to uncover with this? To me, this idea feels like a waste of time that will not bring any real additional security.
Just make sure your script die() s after the header("Location:...") redirect. That is essential to stop additional content from being displayed after the header command (a missing die() wouldn't be caught by your idea by the way, as the redirect header would still be issued...)
If you really want to do this, you could also use a tool like wget and feed it a list of URLs. Have it fetch the results into a directory, and check (e.g. by looking at the file sizes that should be identical) whether every page contains the login dialog. Just to add another option...
Do you want to check the HTTP code to see if it's a redirect?
$params = array('http' => array(
'method' => 'HEAD',
'ignore_errors' => true
));
$context = stream_context_create($params);
foreach(array('http://google.com', 'http://stackoverflow.com') as $url) {
$fp = fopen($url, 'rb', false, $context);
$result = stream_get_contents($fp);
if ($result === false) {
throw new Exception("Could not read data from {$url}");
} else if (! strstr($http_response_header[0], '301')) {
// Do something here
}
}
I hope it will help you:
function checkRedirect($url)
{
$headers = get_headers($url);
if ($headers) {
if (isset($headers[0])) {
if ($headers[0] == 'HTTP/1.1 302 Found') {
//this is the URL where it's redirecting
return str_replace("Location: ", "", $headers[9]);
}
}
}
return false;
}
$isRedirect = checkRedirect($url);
if(!$isRedirect )
{
echo "URL Not Redirected";
}else{
echo "URL Redirected to: ".$isRedirect;
}
You can use session,if the session array is not set ,the url redirected to a login page.
.
I modified Adam Backstrom answer and implemented chiborg suggestion. (Download only HEAD). It have one thing more: It will check if redirection is in a page of the same server or is out. Example: terra.com.br redirects to terra.com.br/portal. PHP will considerate it like redirect, and it is correct. But i only wanted to list that url that redirect to another URL. My English is not good, so, if someone found something really difficult to understand and can edit this, you're welcome.
function RedirectURL() {
$urls = array('http://www.terra.com.br/','http://www.areiaebrita.com.br/');
foreach ($urls as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// chiborg suggestion
curl_setopt($ch, CURLOPT_NOBODY, true);
// ================================
// READ URL
// ================================
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
// line endings is the wonkiest piece of this whole thing
$out = str_replace("\r", "", $out);
echo $out;
$headers = explode("\n", $out);
foreach($headers as $header) {
if(substr(strtolower($header), 0, 9) == "location:") {
// read URL to check if redirect to somepage on the server or another one.
// terra.com.br redirect to terra.com.br/portal. it is valid.
// but areiaebrita.com.br redirect to bwnet.com.br, and this is invalid.
// what we want is to check if the address continues being terra.com.br or changes. if changes, prints on page.
// if contains http, we will check if changes url or not.
// some servers, to redirect to a folder available on it, redirect only citting the folder. Example: net11.com.br redirect only to /heiden
// only execute if have http on location
if ( strpos(strtolower($header), "http") !== false) {
$address = explode("/", $header);
print_r($address);
// $address['0'] = http
// $address['1'] =
// $address['2'] = www.terra.com.br
// $address['3'] = portal
echo "url (address from array) = " . $url . "<br>";
echo "address[2] = " . $address['2'] . "<br><br>";
// url: terra.com.br
// address['2'] = www.terra.com.br
// check if string terra.com.br is still available in www.terra.com.br. It indicates that server did not redirect to some page away from here.
if(strpos(strtolower($address['2']), strtolower($url)) !== false) {
echo "URL NOT REDIRECT";
} else {
// not the same. (areiaebrita)
echo "SORRY, URL REDIRECT WAS FOUND: " . $url;
}
}
}
}
}
}
function unshorten_url($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
$real_url = $url;//default.. (if no redirect)
if (preg_match("/location: (.*)/i", $out, $redirect))
$real_url = $redirect[1];
if (strstr($real_url, "bit.ly"))//the redirect is another shortened url
$real_url = unshorten_url($real_url);
return $real_url;
}
I have just made a function that checks if a URL exists or not
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
function url_exists($url, $ch) {
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
// line endings is the wonkiest piece of this whole thing
$out = str_replace("\r", "", $out);
// only look at the headers
$headers_end = strpos($out, "\n\n");
if( $headers_end !== false ) {
$out = substr($out, 0, $headers_end);
}
//echo $out."====<br>";
$headers = explode("\n", $out);
//echo "<pre>";
//print_r($headers);
foreach($headers as $header) {
//echo $header."---<br>";
if( strpos($header, 'HTTP/1.1 200 OK') !== false ) {
return true;
break;
}
}
}
Now I have used an array of URLs to check if a URL exists as following:
$my_url_array = array('http://howtocode.pk/result', 'http://google.com/jobssss', 'https://howtocode.pk/javascript-tutorial/', 'https://www.google.com/');
for($j = 0; $j < count($my_url_array); $j++){
if(url_exists($my_url_array[$j], $ch)){
echo 'This URL "'.$my_url_array[$j].'" exists. <br>';
}
}
I can't understand your question.
You have an array with URLs and you want to know if user is from one of the listed URLs?
If I'm right in understanding your quest:
$urls = array('http://url1.com','http://url2.ru','http://url3.org');
if(in_array($_SERVER['HTTP_REFERER'],$urls))
{
echo 'FROM ARRAY';
} else {
echo 'NOT FROM ARR';
}

What is the fastest way to determine if a URL exists in PHP?

I need to create a function that returns if a URL is reachable or valid.
I am currently using something like the following to determine a valid url:
static public function urlExists($url)
{
$fp = #fopen($url, 'r');
if($fp)
{
return true;
}
return false;
}
It seems like there would be something faster, maybe something that just fetched the page header or something.
You can use curl as follows:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true); // set to HEAD request
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // don't output the response
curl_exec($ch);
$valid = curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200;
curl_close($ch);
You could check http status code.
Here is a code you could use to check that an url returns 2xx or 3xx http code to ensure the url works.
<?php
$url = "http://stackoverflow.com/questions/1122845";
function urlOK($url)
{
$url_data = parse_url ($url);
if (!$url_data) return FALSE;
$errno="";
$errstr="";
$fp=0;
$fp=fsockopen($url_data['host'],80,$errno,$errstr,30);
if($fp===0) return FALSE;
$path ='';
if (isset( $url_data['path'])) $path .= $url_data['path'];
if (isset( $url_data['query'])) $path .= '?' .$url_data['query'];
$out="GET /$path HTTP/1.1\r\n";
$out.="Host: {$url_data['host']}\r\n";
$out.="Connection: Close\r\n\r\n";
fwrite($fp,$out);
$content=fgets($fp);
$code=trim(substr($content,9,4)); //get http code
fclose($fp);
// if http code is 2xx or 3xx url should work
return ($code[0] == 2 || $code[0] == 3) ? TRUE : FALSE;
}
echo $url;
if (urlOK($url)) echo " is a working URL";
else echo " is a bad URL";
?>
Hope this helps!
You'll likely be limited to sending some kind of HTTP request. Then you can check HTTP status codes.
Be sure to send only a "HEAD" request, which doesn't pull back all the content. That ought to be sufficient and lightweight enough.

Categories