Using a proxy server with fopen - php

I'm trying to use fopen to read a remote file from another website. I want to use a proxy to do this, and as far as I know I can do:
$context = stream_context_create(array(
'http' => array(
'proxy' => 'tcp://192.168.10.10:80' // The proxy server address and port
),
));
$file = fopen($url, 'r', false, $context)
but is there a way to authenticate using a username and password for that proxy? Or am I limited to having to use public proxies?
Also, the proxy definition is tcp://192.168.10.10:80. If I wanted to use a HTTP proxy, am I free to just change it to http://192.168.10.10:80?
Thanks.

You can use the Proxy-Authorization in the $context if the proxy requires authentication.Example from PHP.Net:
$opts= array(
'http' => array(
'proxy' => 'tcp://proxyip:8080',
'header' => array(
"Proxy-Authorization: Basic $auth"
)
)
);
$context = stream_context_create($opts);
Also,I think you cannot change tcp to http in tcp://192.168.10.10:80 since what the proxy does is establishing a TCP connection to another server on behalf of a client then route all the traffic back and forth between the client and the server.Obviously it concerns with TCP(sometimes UDP) instead of HTTP.Http proxies just "understand" the traffic delivered by HTTP protocol.

Related

cURL connection refused

I'm trying to simply read the Philips Hue lights information from my home with the following code:
$fp = fopen(dirname(__FILE__).'/errorlog.txt', 'a');
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://119.119.20.20:2827/api/Js82jH2lao-pAiws89S9A-k9hHsukw72/lights',
CURLOPT_VERBOSE => true,
CURLOPT_STDERR => $fp
));
$resp = curl_exec($ch);
curl_close($ch);
print_r($resp);
It returns nothing. Looking at errorlog.txt it says:
* About to connect() to 119.119.20.20 port 2827 (#0)
* Trying 119.119.20.20... * Connection refused
* couldn't connect to host
* Closing connection #0
I'm able to read the data and change light settings through a site like hurl.it which tells me I've setup my router correctly. allow_url_fopen on my server is on. I'm using curl because I want to do a PUT request as well. I don't want to use a library for simply turning on and off an light.
How can I make this work?
Edit to clarify: I'm using an external server to host the php, which communicates to my Philips Hue bridge at home. You can assume I forwarded my port correctly. No VPN.
My guess is it's a users/permissions issue.
Does www-data/http user have permission to use curl on your server? All php scripts will be executed as that user so without correct permissions curl will fail giving this error.
Which user created the php script? Have you changed file permissions to allow other users correct privileges?
Having said all that, you stated that you don't want to use a library for something so simple, why even bother with curl? file_get_contents can PUT, POST etc out of the box.
Get status from bridge as associative array:
$result = json_decode(file_get_contents('http://119.119.20.20:2827/api/Js82jH2lao-pAiws89S9A-k9hHsukw72/lights'), true);
Turn off all lights with a PUT request:
$data = '{"on":false}';
$result = file_get_contents('http://119.119.20.20:2827/api/Js82jH2lao-pAiws89S9A-k9hHsukw72/groups/0/action', null, stream_context_create(array(
'http' => array(
'method' => 'PUT',
'header' => 'Content-Type: application/json' . "\r\n"
. 'Content-Length: ' . strlen($data) . "\r\n",
'content' => $data
),
)));
Just tried it on my Hue setup. Works for me.

Sending User Agent header through URLFetch API on GAE

I'm sending a request to my API like so:
$context = stream_context_create(
array(
'ssl' => array('verify_peer' => false, 'allow_self_signed' => true),
'http' => array('method' => 'GET', 'header' => "Authorization:Basic " . base64_encode($token.':'))
)
);
$resp = file_get_contents('https://api.site.com/test', false, $context);
if(!preg_match("/200 OK/", $http_response_header[0])) http_response_code(400);
else echo $resp;
However, I am trying to let api.site.com to know what my HTTP_USER_AGENT is that's making the request.
What's the best way to accomplish this?
Add the User-Agent header along side your Authorization:Basic in the stream context options under the http key. See http://php.net/manual/en/context.http.php for details
Edit: Google App engine information
Headers identifying request source
The following headers indicate the app ID of the requesting app:
User-Agent. This header can be modified but App Engine will append an identifier string to allow servers to identify App Engine requests. The appended string has the format "AppEngine-Google; (+http://code.google.com/appengine; appid: APPID)", where APPID is your app's identifier.
X-Appengine-Inbound-Appid. This header cannot be modified, and is added automatically if the request is sent via the URL Fetch service when the follow redirects parameter is set to False.

PHP SoapClient with BasicAuth

I have a PHP script trying to connect to a WSDL.
I need to allow self signed AND give basic auth details.
Using SOAP UI, when I connect to the WSDL I am prompted for username / password.
I got this working.
I also found out that each request also requires basic auth (so on the request screen, I have to select Auth, then basic, enter same credentials as I used on the prompt).
How to I do this auth in PHP
As I said, I can connect, not a problem, I seem to kill the service or timeout if I try to make a request
<?php
$context = stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
));
$data = array(
'columnA' => 'dataA',
'columnB' => 'dataB',
'columnC' => 'dataC');
$url = 'https://111.111.111.111:1234/dir/file';
$login = 'username';
$pwd = 'password';
$client = new soapClient(null, array(
'location' => $url,
'uri' => '',
'login' => $login,
'password' => $pwd,
'stream_context' => $context
));
echo "\n\r---connected---\n\r";
$result = $client ->requestName($data);
print_r($result);
?>
My output is
---connected---
Then it seems to hang.
I have tried wrapping it round a try catch and I had the same result.
Any suggestions??
From the Manual soapclient support the http basic auth.
For HTTP authentication, the login and password options can be used to
supply credentials. For making an HTTP connection through a proxy
server, the options proxy_host, proxy_port, proxy_login and
proxy_password are also available. For HTTPS client certificate
authentication use local_cert and passphrase options. An
authentication may be supplied in the authentication option. The
authentication method may be either SOAP_AUTHENTICATION_BASIC
(default) or SOAP_AUTHENTICATION_DIGEST.
$wsdl = "http://example/services/Service?wsdl";
$option = array(
"trace"=>1,
"login"=>"admin",
"password"=>"admin",
);
$client = new SoapClient($wsdl,$option);
But when I initiate the soapclient, it will throw this error
Exception: Unauthorized
I also have tried to put the auth in the url, like
$wsdl = "http://admin:admin#example/services/Service?wsdl";
But it also doesn't works.
Finally I solved it by add authentication to the option. The manual says the authentication default value is the basic auth, but only when I explicitly set it, it can work.
$option = array(
"trace"=>1,
"login"=>"admin",
"password"=>"admin",
"authentication"=>SOAP_AUTHENTICATION_BASIC
);
Try url encoding your username and password inside the url that you are using:
$url = 'http://'.urlencode('yourLogin').':'.urlencode('yourPassword').'#111.111.111.111:1234/dir/file';
Also I don't see you make use of the wsdl in your code example. You can always download a copy of the wsdl locally and then reference that local copy. You can download the wsdl anyway you want (with php, curl, manually).

PHP stream_context_create with proxy

I'm currently developing an web application which uses an XML Interface located on a different server, that I have to access via a proxy.
So I tried to set the proxy in a stream_context_create array, but it doesn't seem to work.
$set = array(
'http' => array(
'method' => 'GET',
'header' => sprintf(
'Proxy-Authorization: Basic %s',
base64_encode(Constants::XML_AUTH)
),
'protocol_version' => '1.1',
'proxy' => '89.122.180.178:46565'
)
);
$stream = stream_context_create($set);
I'm not quite sure what I'm doing wrong.
If I comment out the proxy key i get a 403 Forbidden Response as it should be.
If I comment in the proxy key I receive a 400 Bad Request Response.
I'm not quite sure what I'm doing wrong. Can you help me out? I never did a communication through a proxy before with PHP.
My guess is that the proxy declaration is missing the protocol. An URI has to be specified (according to the doc), that contains the protocol (scheme).
So this could work: 'proxy' => 'tcp://89.122.180.178:46565'. It might be necessary to remove 'protocol_version' since this may not be required for tcp.
Does that work for you? (or have you already solved it? ... ;-)

Zend_Http_Client Requests failing with Fiddler Proxy

I've written a simple spider to test various things with Fiddler. The script makes a few requests with Zend_Http_Client->request() using the same instance of the Zend_Http_Client class ($client in the example below).
When using Fiddler and Zend_Http_Client, only the first Zend_Http_Client->request() works; subsequent requests fail with "Unable to read response, or response is empty". Here's my Zend_Http_Client configuration with Fiddler:
$config = array(
'adapter' => 'Zend_Http_Client_Adapter_Proxy',
'proxy_host' => '127.0.0.1',
'proxy_port' => 8888,
'timeout' => 60,
'useragent' => 'Local Site Spider Test',
'keepalive' => true,
'sslusecontext' => true
);
$client = new Zend_Http_Client('http://www.site.com/', $config);
Here's a simplified example of what would fail, using $client from above:
$response = $client->request();
echo $response->getHeadersAsString();
$client->setUri('http://www.site.com/file.html');
$response = $client->request();
echo $response->getHeadersAsString();
The spider itself works 100% as intended when not using a proxy, so the code itself is fine. Fiddler is also working, capturing all requests from all processes (tested with WinInet as well as various browsers).

Categories