What's the best way to make a webservices in joomla? - php

Hi guys today I have a interesting question.
What's the best way to make a webservices in joomla?
I'm trying to make a web services in joomla and I have following problem:
in the controller of the view: components/com_webservice/view/view.json.php
<?php
defined('_JEXEC') or die('Restricted access');
jimport('joomla.application.component.view');
class WebServicesViewServices extends JViewLegacy {
private $data;
function __construct($config = array()) {
JLoader::import('models.services', JPATH_COMPONENT);
$model = new WebServicesModelServices();
if ($model->errors) {
echo json_encode($model->errors);
jexit();
}else{
$this->data = array('iphone' => '5s','iphone' => '6','iphone' => '6s','iphone' => '6s plus');
}
parent::__construct($config);
}
function display($tpl = null) {
echo json_encode($this->data);
}
}
?>
The problem is, if I execute: curl http://wsn.jserver/index.php?option=com_services&format=json
to consume this services, this response me
* Connected to wsn.jserver (127.0.0.1) port 80 (#0)
> GET /index.php?option=com_jserver HTTP/1.1
> Host: wsn.jserver
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 303 See other
< Date: Fri, 23 Oct 2015 02:40:37 GMT
< Server: Apache/2.4.16 (Unix) PHP/5.5.30
< X-Powered-By: PHP/5.5.30
< Set-Cookie: 4dbb8abeb5e7919ee73c8545901d5f62=d6ksd6e93t99q7hsk8cf10hq35; path=/; HttpOnly
< Set-Cookie: e909c2d7067ea37437cf97fe11d91bd0=DO
< Location: http://wsn.jserver/index.php?lang=es
< Content-Length: 0
< Content-Type: text/html; charset=utf-8
<
* Connection #0 to host wsn.jserver left intact
How can I do that this work?
what is the best way to make webservices in joomla?

Have you checked the JoomlaTools Framework? From the linked page:
Designed around the HTTP protocol. Each component automatically provides a level 3 JSON REST API out of the box, no extra coding required.

Solved!
I've found the problem.
The problem is because joomla to do a redirect to select language by default.
In my case, I've been duplicate the plugin languagefilter and validated that no be the option="com_services"
then when I execute the command "curl -v http://wsn.jserver/index.php?option=com_webervices" the response is:
* Trying 127.0.0.1...
* Connected to wsn.pawad (127.0.0.1) port 80 (#0)
> GET /index.php?option=com_pawaservices HTTP/1.1
> Host: wsn.jserver
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Fri, 23 Oct 2015 18:48:09 GMT
< Server: Apache/2.4.16 (Unix) PHP/5.5.30
< X-Powered-By: PHP/5.5.30
< Set-Cookie: 4dbb8abeb5e7919ee73c8545901d5f62=6a8m8cdte288k3jp2kvefmfe07; path=/; HttpOnly
< Content-Length: 16
< Content-Type: text/html
<
* Connection #0 to host wsn.pawad left intact
{"iphone":"5s", "iphone":"6", "iphone":"6s", "iphone":"6s plus"}
In conclusion, the problem is because joomla to do a redirect. to solved this problem you can hack the plugin languagefilter: plugins/system/languagefilter/languagefilter.php or create a new plugin.

Related

Having Curl post request error to Laravel app [Somethin Went Wrong* Closing connection 0]

Hey guys having a hard time with cURL. I've setup a laravel app with the followin controller
controller.php
public function authenticate(Request $request){
$credentials = $request->only('email','password');
if(Auth::attempt($credentials)){
return 'Auth Passed';
}
else{
return 'Somethin Went Wrong';
}
and it works completely fine with postman
but my cURL cli post request just don't work
curl --cookie cookies.txt -vX POST http://localhost:8000/login/auth \
-H "Content-Type:application/json" \
-H "Accept:application/json" \
-H "X-CSRF-TOKEN:gC2Kkq50HIcoRJ2d2yzKf6cPOhqVJaQRYSyDh2GJ" \
-d "{"email":"email#gmail.com","password":"pass"}"
The Connection just closes without processing the request with the following error
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000 (#0)
> POST /login/auth HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.79.1
> Cookie: laravel_session=eyJpdiI6IitseTV2bm45OUMwcTQ2R25hMEdtQlE9PSIsInZhbHVlIjoia2twVmRUTTFNMEFTekxaL2gyUmNhbGE1YTZZMm5LeVZxWU5lMDdrTE9uQzkwKzVvTGVtdU9SaEh1c1BncDViSStmb0luZEs1TnNUTDVhQXRNWTE1UVpUV1ZiWWs3bHVYYmFPWmZheFJIMTBOc0VJRDZrZ3RGTWFLbHc3YnZHUksiLCJtYWMiOiJmYTMyZjY4ZjJjODQyOTgxZGYzODlkZjZkYjllZjliZmYxZjBjMDIzYWVhOTU3MDMzNDAwNjAwZDgyODE1ZjYzIiwidGFnIjoiIn0%3D; XSRF-TOKEN=eyJpdiI6IjB0c1hGVXhxSjBQdzNPR3Z5UUI4eGc9PSIsInZhbHVlIjoiZ0RQbEc0TXJuT1RFTy9GZFVJWi9qUUpHeXdxUGQyZEwxeGVHZis2cDBhdnVnVWQ5VVNEckkydDU3TG42S3ZqdFM4ZWNXcnYxOXZCTGc1V2FjaDNwL2U5SlU0cU5UWjRWQytOTkR2dlBucjk5REx4NHNsTlNUMXExYXUzbStJcVciLCJtYWMiOiJkMWE5MTNmMmE4Mzc3MTZmNTY2N2Y5OTYyMTUzMDE4MzI3MWE0NzE1YjMzOGFiOWZiZmNmZGI2YmI5MmI3OThlIiwidGFnIjoiIn0%3D
> Content-Type:application/json
> Accept:application/json
> X-CSRF-TOKEN:gC2Kkq50HIcoRJ2d2yzKf6cPOhqVJaQRYSyDh2GJ
> Content-Length: 38
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Host: localhost:8000
< Date: Thu, 19 May 2022 15:24:55 GMT
< Connection: close
< X-Powered-By: PHP/7.4.16
< Content-Type: text/html; charset=UTF-8
< Cache-Control: no-cache, private
< Date: Thu, 19 May 2022 15:24:55 GMT
* Replaced cookie XSRF-TOKEN="eyJpdiI6Ii8vZUtnS2tVTUlHY3ludEdMaHMydnc9PSIsInZhbHVlIjoiR2d1NkZGNWIxRDRLY2YwNmtUWlhCaS9FU2pLaDVyYVVvNGZBWlJGUUhuOEltakdvMnJnY3FaMERRYnNmTGJOQVM4WFRiSGdNK1FMdDZOUXh5WGpGQ3N5cXVYSXkyM21UNkk0QVFCZFVReFB1UXE1dkhKVm1EbnQyYVBuU2lyaTciLCJtYWMiOiI5MjVlMGI3NzcwOWE0OTU5ZWFhZWFmMWE3OGI0ZDA5ODNkYWViNjI5MjMzNjYwYzhkNDRkYzk1NDlkNTliMTU3IiwidGFnIjoiIn0%3D" for domain localhost, path /, expire 1652981095
< Set-Cookie: XSRF-TOKEN=eyJpdiI6Ii8vZUtnS2tVTUlHY3ludEdMaHMydnc9PSIsInZhbHVlIjoiR2d1NkZGNWIxRDRLY2YwNmtUWlhCaS9FU2pLaDVyYVVvNGZBWlJGUUhuOEltakdvMnJnY3FaMERRYnNmTGJOQVM4WFRiSGdNK1FMdDZOUXh5WGpGQ3N5cXVYSXkyM21UNkk0QVFCZFVReFB1UXE1dkhKVm1EbnQyYVBuU2lyaTciLCJtYWMiOiI5MjVlMGI3NzcwOWE0OTU5ZWFhZWFmMWE3OGI0ZDA5ODNkYWViNjI5MjMzNjYwYzhkNDRkYzk1NDlkNTliMTU3IiwidGFnIjoiIn0%3D; expires=Thu, 19-May-2022 17:24:55 GMT; Max-Age=7200; path=/; samesite=lax
* Replaced cookie laravel_session="eyJpdiI6Im45K3dlV0g5aWNDVGdNNkNHajRnMUE9PSIsInZhbHVlIjoiUXdjMVdNV0hvU3VmWHBpS2N3QnhJMmUxdWNua09RTjdrSk9mWW10MjE2dzYrd3c0Z3Y1amc0OXhUV0RqNWxiREQxV0VwcEhrUGxGcXlKVjdzc0paUHNNbGZNNFQxc2RTbm1IMi8reStNZTNaMjJCdElXT0RmYmtUVDhSNm9QdTYiLCJtYWMiOiJlZDExOTY3YzEyNmZhZjA3MzJhNDJlZmMwZTEyODQ4YTAxNjdkYjcxNmU1ZTg1YWQyOTZjMjRkZTY2YTYzN2JiIiwidGFnIjoiIn0%3D" for domain localhost, path /, expire 1652981096
< Set-Cookie: laravel_session=eyJpdiI6Im45K3dlV0g5aWNDVGdNNkNHajRnMUE9PSIsInZhbHVlIjoiUXdjMVdNV0hvU3VmWHBpS2N3QnhJMmUxdWNua09RTjdrSk9mWW10MjE2dzYrd3c0Z3Y1amc0OXhUV0RqNWxiREQxV0VwcEhrUGxGcXlKVjdzc0paUHNNbGZNNFQxc2RTbm1IMi8reStNZTNaMjJCdElXT0RmYmtUVDhSNm9QdTYiLCJtYWMiOiJlZDExOTY3YzEyNmZhZjA3MzJhNDJlZmMwZTEyODQ4YTAxNjdkYjcxNmU1ZTg1YWQyOTZjMjRkZTY2YTYzN2JiIiwidGFnIjoiIn0%3D; expires=Thu, 19-May-2022 17:24:55 GMT; Max-Age=7200; path=/; httponly; samesite=lax
<
Somethin Went Wrong* Closing connection 0

Authenticating to webservice with Kerberos from PHP in IIS

I am writing a PHP webapplication that has to connect to a webservice using Kerberos 5 authentication (Active Directory). My PHP website is hosted on IIS 7.5 with PHP 5.5. The application pool is running under the account that is authorized in Active Directory and for the target webservice.
I tried every example code that I could find on this site and other sites but to no avail.
This is the PHP code I am using now:
$url = 'http://mywebservice/login/kerberos';
$ch = curl_init();
$options = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_VERBOSE => true,
CURLOPT_HTTPAUTH => CURLAUTH_GSSNEGOTIATE,
CURLOPT_HTTPHEADER => ['Authorization: Negotiate'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => 'myuser',
CURLOPT_URL => $url,
CURLOPT_HEADER => 1
];
curl_setopt_array( $ch, $options);
$result = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($result, 0, $header_size);
$body = substr($result, $header_size);
print $result;
This gives me the following message:
HTTP/1.1 302 Found Date: Fri, 21 Oct 2016 14:49:15 GMT X-Robots-Tag: noindex,nofollow WWW-Authenticate: Location: http://mywebservice/login?login_fail Content-Length: 0
When I remove the CURLOPT_HTTPHEADER => ['Authorization: Negotiate'] l get an Internal Server error from the curl module.
When I use curl commandLine I get the following result:
curl --negotiate http://mywebservice/login/kerberos -umyuser#mydomain --verbose -c "c:\cookie.txt" -b "c:\cookie.txt"
Enter host password for user 'myuser#mydomain':
* Trying (192.168.1.1...
* Connected to mywebservice (192.168.1.1) port 80 (#0)
> GET /login/kerberos HTTP/1.1
> User-Agent: curl/7.41.0
> Host: mywebservice
> Accept: */*
> Cookie: JSESSIONID_PUBLIC=X(MASKED)XXXXXXXXXXXXXXXXX
>
< HTTP/1.1 401 Unauthorized
< Date: Fri, 21 Oct 2016 14:52:46 GMT
< X-Robots-Tag: noindex,nofollow
< WWW-Authenticate: Negotiate
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Last-Modified: Thu, 20 Oct 2016 14:52:46 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< P3P: CP=CAO PSA OUR
< Content-Type: text/html; charset=UTF-8
< Content-Length: 3643
<
* Ignoring the response-body
* Connection #0 to host mywebservice left intact
* Issue another request to this URL: 'http://mywebservice/login/kerberos'
* Found bundle for host mywebservice: 0xXXXXXXX
* Re-using existing connection! (#0) with host mywebservice
* Connected to mywebservice (192.168.1.1) port 80 (#0)
* Server auth using Negotiate with user 'myuser#mydomain'
> GET /login/kerberos HTTP/1.1
> Authorization: Negotiate X(MASKED)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXD
w==
> User-Agent: curl/7.41.0
> Host: mywebservice
> Accept: */*
> Cookie: JSESSIONID_PUBLIC=X(MASKED)XXXXXXXXXXXXXXXXX
>
< HTTP/1.1 302 Found
< Date: Fri, 21 Oct 2016 14:52:46 GMT
< X-Robots-Tag: noindex,nofollow
< WWW-Authenticate:
< Location: http://mywebservice/?login_fail
< Content-Length: 0
<
* Connection #0 to host mywebservice left intact
When I test with the KerberosAuthenticationTester tool (http://blog.michelbarneveld.nl/michel/archive/2009/12/05/kerberos-authentication-tester.aspx) it authenticates me right away when I pass the url and credentials.
I assume that it is not working because I am missing the krb5 library. I could not find it as a DLL so I tried recompiling it with the PHP source in Visual Studio. This is not working for me as well, I am missing the config.w32 file. If necessary I can elaborate on that but first I want to know if this is really needed.
I also installed MIT Kerberos but this did not help aswell.
Is it correct that I need the krb5 DLL, or am I on the wrong track? If I need this DLL, where can I get it or how can I compile it? If there is another solution I would be very happy to hear it.
Thanks everyone for taking your time for me and replying!

xml download - blocked

I am trying to download xml file from one polish website. For first days it worked but then I could download this file to my server (but I can open and download it on my computer). In file on my server in which there should be xml content is html content telling me that I have been blocked.
I was trying to contact with webmaster from website from which I want to get xml and he told me that I am not blocked by IP address. So the question is what I should sent in headers or what to download this file?
My code to download xml file is below and here is the xml which I want to download: http://www.polskatimes.pl/rss/fakty_kraj.xml
$headers[] = "User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13";
$headers[] = "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
$headers[] = "Accept-Language:pl-PL,pl;q=0.8";
$headers[] = "Accept-Encoding:gzip,deflate,sdch";
$headers[] = "Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.7";
$headers[] = "Keep-Alive:115";
$headers[] = "Connection:keep-alive";
$headers[] = "Cache-Control:max-age=0";
$xml_data = file_get_contents($xml,false,stream_context_create(
array("http" => array('header' => $headers)))); // your file is in the string "$xml" now.
file_put_contents($xml_md5, $xml_data); // now your xml file is saved.
Request the URL in verbose mode (-v):
* About to connect() to www.polskatimes.pl port 80 (#0)
* Trying 195.8.99.38... connected
* Connectede to www.polskatimes.pl (195.8.99.38) port 80 (#0)
> GET /rss/fakty_kraj.xml HTTP/1.1
> User-Agent: curl/7.21.0 (x86_64-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.15 libssh2/1.2.6
> Host: www.polskatimes.pl
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx
< Date: Thu, 18 Apr 2013 10:40:15 GMT
< Content-Type: text/html; charset=utf8
< Transfer-Encoding: chunked
< Connection: close
< Vary: Accept-Encoding
< Expires: Thu, 18 Apr 2013 10:40:15 GMT
< Cache-Control: max-age=0
(html page with message that I am temporary blocked)
* Closing connection #0
To inspect what happens behind the scene (and which headers you actually need or not) you need to analyze a little. That is nothing magic, you can do it on the commandline with a software called curl. It is available for many (even all?) computer platforms.
First step most often is to request the URL in verbose mode (-v):
$ curl -v http://www.polskatimes.pl/rss/fakty_kraj.xml
* About to connect() to www.polskatimes.pl port 80 (#0)
* Trying 195.8.99.38... connected
* Connected to www.polskatimes.pl (195.8.99.38) port 80 (#0)
> GET /rss/fakty_kraj.xml HTTP/1.1
> User-Agent: curl/7.21.1 (i686-pc-mingw32) libcurl/7.21.1 OpenSSL/0.9.8r zlib/1.2.3
> Host: www.polskatimes.pl
> Accept: */*
>
< HTTP/1.1 302 Found
< Date: Wed, 17 Apr 2013 17:39:51 GMT
< Server: Apache
< Set-Cookie: sprawdz_cookie=1; expires=Thu, 17-Apr-2014 17:39:51 GMT
< Location: http://www.polskatimes.pl/rss/fakty_kraj.xml?cookie=1
< Vary: Accept-Encoding
< Content-Length: 0
< Connection: close
< Content-Type: text/html; charset=iso-8859-2
<
* Closing connection #0
That shows you the request (prefixed with >) and response (prefixed with <) headers and the response body (empty in this case). As you can see the status is 302 Found which means as 3xx a redirect and the location header tells where to:
Location: http://www.polskatimes.pl/rss/fakty_kraj.xml?cookie=1
As the query parameter suggests, this is a cookie-check. The cookie itself is set as well:
Set-Cookie: sprawdz_cookie=1; expires=Thu, 17-Apr-2014 17:39:51 GMT
So in the next step we will replay the last command but this time setting the cookie which can be done with the -b argument:
$ curl -v -b prawdz_cookie=1 http://www.polskatimes.pl/rss/fakty_kraj.xml
* About to connect() to www.polskatimes.pl port 80 (#0)
* Trying 195.8.99.38... connected
* Connected to www.polskatimes.pl (195.8.99.38) port 80 (#0)
> GET /rss/fakty_kraj.xml HTTP/1.1
> User-Agent: curl/7.21.1 (i686-pc-mingw32) libcurl/7.21.1 OpenSSL/0.9.8r zlib/1.2.3
> Host: www.polskatimes.pl
> Accept: */*
> Cookie: prawdz_cookie=1
>
< HTTP/1.1 200 OK
< Date: Wed, 17 Apr 2013 17:43:52 GMT
< Server: Apache
< Set-Cookie: sesja_gratka=e38fa0eb93705c8de7ae906198494439; expires=Wed, 24-Apr-2013 17:43:52 GMT; path=/; domain=polskatimes.pl
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< Vary: Accept-Encoding
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: text/xml; charset=utf-8
<
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title><![CDATA[Fakty - Kraj]]></title>
<link>http://www.polskatimes.pl/fakty/kraj/</link>
<atom:link href="http://www.polskatimes.pl/rss/fakty_kraj.xml" rel="self" type="application/rss+xml"/>
<description><![CDATA[Materiały z działu Kraj]]></description>
... (cutted)
So this is immediately successful. And now the real good part: You know that you need to set the cookie for the request and curl shows you already all headers it used:
> GET /rss/fakty_kraj.xml HTTP/1.1
> User-Agent: curl/7.21.1 (i686-pc-mingw32) libcurl/7.21.1 OpenSSL/0.9.8r zlib/1.2.3
> Host: www.polskatimes.pl
> Accept: */*
> Cookie: prawdz_cookie=1
Most of them you do not need to care about with file_get_contents, the first line as well as the Host: and the Accept: line.
The User-Agent: header does not look like it really plays a role as curl is accepted.
So all what is left is the Cookie: header. Let's try in PHP:
$ php -r "echo file_get_contents('http://www.polskatimes.pl/rss/fakty_kraj.xml', null,
stream_context_create(['http'=>['header'=>['Cookie: prawdz_cookie=1']]]));"
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title><![CDATA[Fakty - Kraj]]></title>
<link>http://www.polskatimes.pl/fakty/kraj/</link>
<atom:link href="http://www.polskatimes.pl/rss/fakty_kraj.xml" rel="self"
type="application/rss+xml"/>
... (cutted)
And this is the direct test that only the Set-Cookie: prawdz_cookie=1 header is needed.

PHP: header() and include/include_once/require/require_once

I am calling header('Location: http://foo.com/foo/'); in a file after calling include() with files which contain function calls (no output). Whenever I call include() I the PHP header() redirect does not work. This only happens on the server. This happens no matter which PHP file I include. (Local files are uploaded to the server during development.)
Well actually I'm getting a blank character just before the DOCTYPE declaration,
which is very bad! I get exactly one blank character whether I include one or two files.
Neil#NEILCOMPUTER /c/wamp/www/workspace/worknet
$ curl --verbose http://timescapezonecom.ipage.com/worknet/foo.php
* About to connect() to timescapezonecom.ipage.com port 80 (#0)
* Trying 66.96.147.110... connected
* Connected to timescapezonecom.ipage.com (66.96.147.110) port 80 (#0)
> GET /worknet/foo.php HTTP/1.1
> User-Agent: curl/7.21.1 (i686-pc-mingw32) libcurl/7.21.1 OpenSSL/0.9.8k zlib/1.2.3
> Host: timescapezonecom.ipage.com
> Accept: */*
>
< HTTP/1.1 302 Found
< Date: Sun, 08 Jul 2012 23:19:12 GMT
< Content-Type: text/html; charset=iso-8859-1
< Content-Length: 206
< Connection: close
< Server: Nginx / Varnish
< X-Powered-By: PHP/5.2.17
< Set-Cookie: PHPSESSID=0310603f03176770c3feb46ea93d9fd3; path=/
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< Location: http://www.google.com
<
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved here.</p>
</body></html>
* Closing connection #0
On the other hand when I include no files in foo.php I get a zero just before
the doctype, which I also find strange:
Neil#NEILCOMPUTER /c/wamp/www/workspace/worknet
$ curl --verbose http://timescapezonecom.ipage.com/worknet/foo.php
* About to connect() to timescapezonecom.ipage.com port 80 (#0)
* Trying 66.96.147.110... connected
* Connected to timescapezonecom.ipage.com (66.96.147.110) port 80 (#0)
> GET /worknet/foo.php HTTP/1.1
> User-Agent: curl/7.21.1 (i686-pc-mingw32) libcurl/7.21.1 OpenSSL/0.9.8k zlib/1.2.3
> Host: timescapezonecom.ipage.com
> Accept: */*
>
< HTTP/1.1 302 Found
< Date: Sun, 08 Jul 2012 23:25:28 GMT
< Content-Type: text/html; charset=iso-8859-1
< Content-Length: 206
< Connection: close
< Server: Nginx / Varnish
< X-Powered-By: PHP/5.2.17
< Set-Cookie: PHPSESSID=98c60264dbcdd024d91bae25db848186; path=/
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< Location: http://www.google.com
<
0<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved here.</p>
</body></html>
* Closing connection #0
Here is the file foo.php:
<?php
session_start();
// I added the require just to make sure nothing is being printed there
// (an error for example)
// require_once('include/connect.php');
// require_once('include/util.php');
header("Location: " . "http://www.google.com");
exit;
?>
I'd really like to know where the 0 at the beginning of the file is coming from.
It is highly recommended to not use php's closing tag for non-template files.
<?php //VERY first line, no whit space
// code
// NO ?> *anywhere*
Often it's a newline after the ?> which causes your error.

PHP: Validating URL with Curl

$fileSource = "http://google.com";
$ch = curl_init($fileSource);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($retcode != 200) {
$error .= "The source specified is not a valid URL.";
}
curl_close($ch);
Here's my issue. When I use the above and set $fileSource = "http://google.com"; it does not work, whereas if I set it to $fileSource = "http://www.google.com/"; it works.
What's the issue?
One permanently redirects (301) to the www. domain, while the other one just replies OK (200).
Why are you only considering only the 200 status code as valid? Let CURL handle that for you:
curl_setopt($ch, CURLOPT_FAILONERROR, true);
From the manual:
TRUE to fail silently if the HTTP code returned is greater than or
equal to 400. The default behavior is to return the page normally,
ignoring the code.
Try explicitly telling curl to follow redirects
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
If that doesn't work you may need to spoof a user agent on some sites.
Also, if they are using JS redirects your out of luck.
What you're seeing is actually a result of a 301 redirect. Here's what I got back using a verbose curl from the command line
curl -vvvvvv http://google.com
* About to connect() to google.com port 80 (#0)
* Trying 173.194.43.34...
* connected
* Connected to google.com (173.194.43.34) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.25.0 (x86_64-apple-darwin11.3.0) libcurl/7.25.0 OpenSSL/1.0.1b zlib/1.2.6 libidn/1.22
> Host: google.com
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Location: http://www.google.com/
< Content-Type: text/html; charset=UTF-8
< Date: Fri, 04 May 2012 04:03:59 GMT
< Expires: Sun, 03 Jun 2012 04:03:59 GMT
< Cache-Control: public, max-age=2592000
< Server: gws
< Content-Length: 219
< X-XSS-Protection: 1; mode=block
< X-Frame-Options: SAMEORIGIN
<
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
here.
</BODY></HTML>
* Connection #0 to host google.com left intact
* Closing connection #0
However, if you do a curl on the actual www.google.com suggested in the 301 redirect, you'll get the following.
curl -vvvvvv http://www.google.com
* About to connect() to www.google.com port 80 (#0)
* Trying 74.125.228.19...
* connected
* Connected to www.google.com (74.125.228.19) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.25.0 (x86_64-apple-darwin11.3.0) libcurl/7.25.0 OpenSSL/1.0.1b zlib/1.2.6 libidn/1.22
> Host: www.google.com
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Fri, 04 May 2012 04:05:25 GMT
< Expires: -1
< Cache-Control: private, max-age=0
< Content-Type: text/html; charset=ISO-8859-1
I've truncated the remainder of google's response just to show the primary difference in the 200 OK vs 301 REDIRECT

Categories