Question

I have 2 servers. The main server acts as a web service for the server2 and server2 is talking to the clients.

servers

Server2 runs a php script that gets some data from the client, then sends it to the main server and then reads the content of a certain page on the Main Server (which was generated according to the data of the client) and also reads the http headers that comes back from the main server in order to get a cookie value.

Server 2 Code:

some code ...

$postdata = http_build_query(
    array(
        'var1' => 'value1',
        'var2' => $_POST["var2"],
        'var3' => $_POST["var3"]
    )
);
$opts = array('http' =>
    array(
        'method'  => 'POST',
        'header'  => 'Content-type: application/x-www-form-urlencoded',
        'content' => $postdata
    )
);

$context = stream_context_create($opts);
file_get_contents("http://www.mainserver.com", false, $context);
$cookieContent = getCookieContent($http_response_header);
SetCookie('myCookie', $cookieContent, $loginTime, '/', $url, false);

more code ....

The main server doesn't run a php script but it writes the cookie value as expected. The cookie value is unique and being generated according to the client's details that were passed by server2.

So, basically, server2 acts as "proxy" (or reverse proxy) and should set the unique cookie value he gets from the main server for each client.

My question is:

Does my logic works? I know it works for 1 client, but what happens when multiple clients access the same script on server2? How the main server knows to return the answer with the correct unique value to the correct php instance on server2?

In other words, is there any chance that a client will send a request to server2 and server2 will return an answer with a unique value that belongs to a different client?

Was it helpful?

Solution

Yes, it does work, because PHP on Server 2 processes the script independently for each request from a client. In turn, each of the execution instances of the PHP script receive their own HTTP request from stream_context_create(), most probably even in different TCP connections. There is no way the values for $context get accidentally swapped between execution instances and a client receives a response originally intended for another client.

Your problem doesn't even require the existence of a »Main server«. When you're writing a PHP script, critical information about how the requests are handled by it, is hidden from you, which is why you might be confused. But this is a good thing:

  1. If you abstract away the details about how PHP is invoked, your webserver has many (configurable) choices on how to handle requests from concurrent clients: It could e.g. use multiple threads, multiple processes, serialize all the executions, use a threadpool. You wouldn't want to rewrite your PHP code, just because your Webserver has to use threads instead of processes. If you write your PHP code well, you can use the same PHP code in different contexts, e.g. call it from the command line.

  2. You are getting certain basic guarantees, like that no client will accidentally get a response intended for some other client.

However, if you want your »Main server« to know, that it is serving different clients, you have to inform it accordingly. This could work with passing on cookies (in your case, you pass on cookies from the »Main server« to the client, but passing on cookies from the clients to the »Main server« is missing).

OTHER TIPS

It seems you want to implement your own reverse-proxy system then.

Basically your proxy (server2 in your example) will need to memorize all what is needed to

  • pass a client request to the server,
  • answer the client once the server has generated the wanted page
  • handle the case where the server does not answer (i.e. request timeouts)

In a simple client-server exchange, the server will use the HTTP headers sent by the client to produce an immediate reply, so these headers do not need to be memorized.

In a proxy architecture, the proxy will not reply immediately (it will ask the server for the actual reply instead).

During the time needed for the server to produce the reply, the proxy has to memorize the reference of the original client's request, to

  • use it to recreate the final reply once the server finally produces it,
  • handle request cancellation from the client side

It means the proxy will have to handle two two-ways communication channels asynchronously, while a simple server can handle the requests synchronously.

What your example shows is the uplink from the proxy to the server.

In this uplink, the proxy must provide transparently all the informations passed by the client and add some indication of how the server shall pass back the completed request to him.

The $context variable of your example should contain the HTTP headers as passed by the client, plus some backlink to the proxy, that the server will use to direct its response to the proxy instead of the client.

In turn, the server will process the request just as if it had been sent directly by the client. However, once the request is processed, it will use the backlink to answer the proxy.

The proxy will get a response from the server, and use the memorized request context to decide what to do with the result. The client might have dropped the request in the mean time, in which case the result will simply be ignored. Otherwise, it will use the request context to pass the response to the client.

All this being said, the unique ID delivered by the server is not necessary, since the server will never talk to the client directly. What matters is that the proxy and the server can identify clearly which request they are working on.

In short, the only thing required is a request identifier between the server and the proxy.

You can still generate a unique ID for each client based on cookies or IP address or any other means, but that will not be different from, say, session handling in a proxy-less client-server architecture.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top