PHP : relay resource request through different server - php

I have the following situation, trying to clearify with a 'scheme'.
On a webapplication, we are showing resources comming from server3. But because server3 is a intranet endpoint, we are loading the resource through some extra steps. Each server has a Apache running to cap the incomming requests.
The infra setup has some 'restrictions':
Server 1 contains the webapplication
Server 2 is only reachable by server1, and can't host the webapplication. And acts as a 'entry' point to server 3, restricted access only for requests comming from server1 (intranet server)
Server 3 (resources that need to be shown on the webapplication) is only reachable by server 2. Server 3 is an intranet server.
As you see on the scheme above, loading a resources takes some steps. I'm wondering if there are any better ways within php to stream contents from server3 through server2 initiated on server1. Without having to transport the content on each step.
I've been looking at file_get_contents in combination with stream_context_create. But not sure if this is possible relaying the request through a server in the middle.
I've tried something like this (stripdown):
$opts = array(
'http' => array(
'timeout' => 10,
'proxy' => 'tcp://server2:port',
'request_fulluri' => true
)
);
$context = stream_context_create($opts);
$data = file_get_contents('server3/files/footer.png', false, $context);
echo $data;
Any expertise is welcome.
Thanks!

Related

Getting the clients Cookies from a PHP Ratchet WebSocket Server

I have a PHP Ratchet WebSocket server, running a custom chatroom on my website.
I would like to get the user's cookies when they connect to the server, so that I can get their session data and do something special if they are logged in / have specific permissions / etc.
In other posts (both on StackOverflow and otherwise), it is said that to get session data, you must get the client's cookies, which are supplied in their requests to the web server. The following line of code is meant to do this:
$conn->WebSocket->request->getCookies()
Where $conn is a ConnectionInterface.
My problem is, that when run this simply returns an empty array, even though the DevTools will show that there are indeed cookies.
Why might this not be returning a value?
just in case you're still searching for a solution:
1.In case your cookies only valid for a specific domain/subdomain - you should establish connection to your WebSocket server over the same address.
For example, cookies that only valid for admin.example.com won't be sent to a WebSocket server on your root domain (example.com).
2.In case your cookies only valid for a secure connection (https://), your WebSocket server should be over a secure connection too (wss://), Which is quite easy to achieve with the latest Ratchet version.
$webSock = new React\Socket\Server('0.0.0.0:8443', $loop);
$webSock = new React\Socket\SecureServer($webSock, $loop, [
'local_cert' => 'path_to_server_cert',
'local_pk' => 'path_to_private_key',
//'allow_self_signed' => TRUE,
'verify_peer' => FALSE
]);
3.With Ratchet 0.4.x, there is no longer a cookie parser.
You can only get it as a raw string and then parse it by yourself.
Get & Parse cookies with Ratchet 0.4.x :
$cookiesRaw = $conn->httpRequest->getHeader('Cookie');
if(count($cookiesRaw)) {
$cookiesArr = \GuzzleHttp\Psr7\parse_header($cookiesRaw)[0]; // Array of cookies
}

HTTP/1.1 400 Bad Request between an AWS server to another AWS server but HTTP/1.1 200 between my local server and the same AWS server

Reference
PHP App1 AWS instances
AWSApp1Live (64bit Amazon Linux 2015.03 v1.4.6 running PHP 5.5)
AWSApp1Test (64bit Amazon Linux 2015.03 v1.3.2 running PHP 5.6)
PHP App2 AWS instances
AWSApp2Live (64bit Amazon Linux 2016.09 v2.3.2 running PHP 5.6)
AWSApp2Test (64bit Amazon Linux 2015.09 v2.0.4 running PHP 5.5)
Local App1 instance
LocalApp1 (Windows 10 running XAMPP Control Panel v3.2.1)
Overview
I have two PHP applications: PHP App1 and PHP App2 which work together by communicating with eachother using internal POST requests. PHP App1 sends a request using
$query = http_build_query($data);
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded' . PHP_EOL .
'Cv-Forwarded-For: ' . $_SERVER["REMOTE_ADDR"] . PHP_EOL,
'content' => $query,
),
'ssl'=>array(
'verify_peer'=>false,
'verify_peer_name'=>false
)
));
$response = #file_get_contents(
$target = $this->api_target.$action,
$use_include_path = false,
$context
);
PHP App2 is running a RESTful API service which responds to the requests sent from PHP App1. The response is a JSON string.
Problem
I have loaded these PHP applications onto four different AWS instances as mentioned above. The following combinations of request/respone
AWSApp1Live communicating with AWSApp2Live
(HTTP/1.1 400 Bad Request)
AWSApp1Test communicating with AWSApp2Live
(HTTP/1.1 400 Bad Request)
AWSApp1Test communicating with AWSApp2Test
(HTTP/1.1 200 OK)
LocalApp1 communicating with AWSApp2Live
(HTTP/1.1 200 OK)
So as you can see, PHP App2 when loaded onto AWSApp2Test and sent a request from AWSApp1Test, it responds with (HTTP/1.1 200 OK). But when loaded onto AWSApp2Live and given the same request from either AWSApp1Live or AWSApp1Test it responds with (HTTP/1.1 400 Bad Request). The only time AWSApp2Live responds with (HTTP/1.1 200 OK) is when the request was sent from LocalApp1.
Attempts to fix so far
We thought there might be something to do with the Zlib output compression setting on the AWSApp2Live software configuration, but the response was still the same.
We've done an nslookup from the LocalApp1 server and the AWSApp2Test server for the AWSApp2Live server and both of them returned the same IP addresses to rule out any DNS issues
We SSH'd into the AWSApp1Test server and did a wget for one of the API commands on the AWSApp2Live server and we got back a JSON response which meant it is reaching the PHP application on that server.
There are no logs being generated on the AwsApp2Live server for me to see why the server is treating some requests as bad requests and others as not.
Using Postman (https://www.getpostman.com/) I was able to successfully communicate with the API on AWSApp2Live so the application is running as expected.
Any help would be greatly appreciated!
We are not sure where to look for any further clues as to what might be happening. If you need any further information please let us know. Thank you so much.
There's nothing in the documentation, but I think headers should be passed as a string only if there's a single one of them. Otherwise use an array:
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => array(
'Content-Type: application/x-www-form-urlencoded',
'Cv-Forwarded-For: ' . $_SERVER["REMOTE_ADDR"]
),
'content' => $query,
),
'ssl'=>array(
'verify_peer'=>false,
'verify_peer_name'=>false
)
));

All port server listener with php

I am trying to set a simple client-server system for a mobile app.
Server side is written in PHP.
This server should handle requests from the app (a client) such as exchanging data in the form of json objects.
So i need my server to listen to requests and respond.
All the examples i found include the 'Socket' functions (socket_create(), socket_bind() etc.), and somewhere i need to specify the port i'm listening on.
My question is - the app sends the request to some url - http://example.com (or something like that).
Obviously in the client code i am not specifying the port i am sending the request to, so do i need to listen on all ports? How can i achieve this?
Usually PHP is used in combination with a web server (for example Apache or nginx), which handles the low-level socket communication, so that you can concentrate only on the business logic of your system.
This way, your server code can be as simple as:
<?php
echo json_encode(array(
'status' => 'OK',
'user' => array(
'id' => 6,
'username' => 'foo',
),
));
FYI: Web servers by default use port 80 for the http protocol and port 443 for https. So, when the port number is not specified, then the default values are used. For example http://example.com is the same as http://example.com:80.

PHP locally hosted, connecting to external resources through a proxy server

I'm trying to do some locally hosted facebook development but I'm on a university network, and therefore all outgoing connections from my computer need to pass through our proxy server. The main problem I'm having is that I can't seem to find any documentation for setting up apache to USE a proxy server, rather than to ACT as a proxy server.
Upon thinking about this however, perhaps when I do a "cURL" request or an fopen, that apache does not perform the retrieving of data, and it is instead the PHP drivers that do this. Older versions allowed you to setup a global proxy in the PHP.ini file, but not in PHP 5.
I have to use code to actually physically set the defaults and cannot find any config files where I can set them permanently. For example, this sets up streams so fopen can function:
$r_default_context = stream_context_get_default
(
array
(
'http' => array
( // All HTTP requests are passed through the local NTLM proxy server on port 8080.
'proxy' => 'tcp://proxy.munged.edu:8080',
'request_fulluri' => True,
),
)
);
but this will not set everything which is required as to use cURL, I have to do this:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_PROXY, "http://proxy.munged.edu:8080");
curl_setopt($ch, CURLOPT_PROXYPORT, 8080);
Is there anyone who knows how to set all things that require outgoing connections to use this proxy as I don't won't code that's specific to this computer (because my plan was to work on my code locally and then upload it to some webspace when it's done: the change/upload/refresh cycle is ALOT more time consuming than just that change/refresh cycle)
edit:
just to clarify, i have been including all this in a file called "proxyconfig.php" then checking for it's existance, and include()-ing it at the top. if there's no way to set up the defaults in config files, having the methods to set up all the things that the facebook.php page used for their API requires would be awesom.
Your method is correct, assuming that the application is in iframe mode (FBML applications require Facebook being able to callback to your server).
If the issue is wanting to be able to develop locally and deploy to a remote site with minimal modification to your files, I'd recommend extending BaseFacebook as a new class called LocalBaseFacebook and changing CURL_OPTS to:
public static $CURL_OPTS = array(
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_USERAGENT => 'facebook-php-3.0',
CURLOPT_PROXY => 'http://proxy.munged.edu:8080',
CURLOPT_PROXYPORT => 8080
);
When deploying out, make a switch when instantiating the Facebook class based on hostname or some uniquely identifying property / configuration (you could even use a $_GET variable such as ?is_local=1) and attach that to the end of your Canvas URL.

file_get_contents behind a isa proxy under apache

I am developing a script which deal with accessing remote site data. For this purpose i am using file_get_contents() function. it was working fine in home but no connectivity in office.
then after googling i found using proxy header with file_get_contents()
my script is as follow which i got from stackoverflow's thread file_get_contents()
$auth = base64_encode('mywindowlogin:password');
$opts = array('http' => array('proxy' => 'tcp://172.20.10.130:8080', 'request_fulluri' => true,'header' => "Proxy-Authorization: Basic $auth",));
$context = stream_context_create($opts);
$data = file_get_contents('http://www.lesco.gov.pk/', false, $context);
echo $data;
this OUTPUT with an ERROR
[function.file-get-contents]: failed to open stream: HTTP request failed!
HTTP/1.1 407 Proxy Authentication Required ( The ISA Server requires
authorization to fulfill the request. Access to the Web P in
D:\php\docs\url.php on line 7
Real question Comes here that in office they are using ISA Proxy server and i am using PHP on apache
do i need to use Window login as
userid or something esle?
i am doing something wrong while passing
userid and password for proxy authorization? OR
What i am doing is not the right way of doing it?
please suggest me how or what to do make file_get_contents working through proxy server.
thanks in advance

Categories