I need to convert EPP (session based protocol - https://www.rfc-editor.org/rfc/rfc5734) to an HTTP request/response based protocol (JSON). The JSON part has already been coded and is working with a few clients.
I've looked at nginx using websockets but websockets appear too high level for the raw EPP protocol.
I need to solve the following process:
nginx to terminate an SSL TCP connection
read off the EPP request (XML) - preferably in PHP
convert to JSON and send it to an HTTP server
read the result
convert to XML and send it back to the EPP connection
Are there any recommended technologies within nginx to achieve this? I can code the PHP socket server without too much hassle.
So you are building an EPP server? Welcome to the EPP world, from someone being in it since its birth or even before :-)
EPP is a "simple" protocol using XML over TLS (typically, there are some instances over HTTPS and during drafting period they were other proposals like over SMTP or BXXP).
So, as a server you need something being able to handle TLS termination, and read XML. This is possible in any language, and is not rocket science. Of course the devil lies in the details. And you do not provide enough details/context to see exactly what constraints you may have or specific problem.
So you may be a little off topic here because writing a simple server handling TLS and reading XML would need to be shown here as code if you want people to help you.
Please make sure to read RFC 5734 multiple times about specific transport considerations. You need of course to remember that it is a stateful protocol so if you "forward" the requests internally over a stateless protocol you will need to carry some sort of authentication.
You do not need websockets, in fact I do not understand why you speak about them. You just need TLS termination, not HTTPS one.
Have a look at HAProxy too, it is a popular handler of things like that.
But again, based on your specific (unknown) constraints (specially number of clients, volume of queries, SLAs needed, etc.), something as simple as stunnel may be enough.
Note that you have mod_epp for Apache. Maybe not very live anymore but could give you ideas. It allows to use any CGI program under Apache when the server receives in fact EPP frames and not HTTP ones.
As a side note, besides security (but that should be covered by RFC5734), I would recommend you to be careful about encodings, XML namespaces, and avoid using multiple serialisation mechanisms in the same stream (JSON inside XML is a bad idea as is XML inside JSON, but I do not know exqctly how your "convert" part works).
Related
I have a question regarding the titled question. So, I'm attempting to create a program which passes data/requests for data between a program in C++ and a PHP site running off of an Apache web server.
I've been researching Socket communications, but I'm not understanding the concept. I understand how to create a socket in PHP, and another in c++, and I have them running using a test application. But only individually, not talking to each other OR talking to my web server (the PHP is not on the server at the moment, it is on a different server). So how does this work? From my understanding, you need one to be listening to a port number, and the other one to send something to that command.
Ideally, I would prefer not to use any libraries to help me achieve this. I know this question has been asked many times before, but I'm still getting nowhere.
Could someone provide an explanation of how the above works, or links to a question on here/elsewhere that may be of help? Or if there is a better method of doing this than using sockets? They will be talking to each other a lot, and speed maybe an issue.
Edit, further explanation:
Web server: I'm running an Apache web server. The PHP script is located on this server.
C++ Location: While testing, my c++ application is stored on the same Raspberry Pi that the web server is running on. In the real application, my C++ application will still be stored on the same device (but it won't be a Raspberry Pi - still Linux based though).
Communication: The PHP script will need to be triggered to do things by the C++ script, and vice versa. They will need to both need to pass data (common data structures, but they could be fairly large) each way (so both need to be able to send and receive data).
I think the easiest way is:
1) PHP -> C++ : tcp
2) C++ -> PHP : http
Will try to explain.
1) To take something from C++ app PHP connects to that app using stream_socket_client function. C++ app is listening on host and port using socket, bind and listen functions. As soon as connection arrives C++ app accept it and then in a separate std::thread serves it (recv to get request, send to send response). How to socket.
2) As PHP is working under Apache Web Server, I think the easiest way is use of libcurl library to make HTTP request from C++ app. How to curl.
Another approach could be SOAP or REST Web Services. On both sides, you could provide a SOAP Web Service to exchange data or to call remote functions. On C++-side, you could use Apache Axis to provide a SOAP Server. On PHP side, you can use the build-in SOAPServer class (http://php.net/manual/de/class.soapserver.php).
With SOAP you simply would exchange XML-based messages between both applications over HTTP / HTTPS. With this approch, both applications can trigger each other and exchange data.
Adding to the answer of Ben Schnarr, I think probably the most elegant and easy solution would be to make the C++ program a client for web services implemented in the PHP code. Using sockets directly would force you to have an additional protocol over it to represent the data being transmitted (unless the data is trivially simple, like a stream of ASCII text), which would be a bit like reinventing the wheel.
I'm partial to REST+JSON, because they are simple to implement and use, and very powerful. In contrast, SOAP is quite complex, heavy in resources, and brittle, especially if you use it with C++. One popular implementation I've already used, for instance, would force you to recompile your code every time you change the layout of any of the messages, even if the server is adding a field that the client won't use.
On the PHP side, it's quite easy - it already has all the infrastructure you need. On the C++ program, the minimum you'll need would be an HTTP client library and a JSON codec. I use libcurl for the first (by far the most popular) and jsoncpp for the latter, but there are other options for both. More recently, some libraries appeared with the whole package, but I hadn't had the chance to use them yet. Some examples:
restclient
REST SDK
Restbed
I recommend you to use Unix Sockets
For c++ check this: http://www.linuxhowtos.org/C_C++/socket.htm
For php check this: stream_socket_client
You can pass info internally from both processes.
Hope you can solve it, don't give up.
A SOAP solution could be something that solve the problem, but in my opinion it complicates a lot the application deployment.
You could go down a few levels and work directly with XML-RPC.
Here you have two interesting links, that shows how to implement the client and the server in both languages.
XML-RPC for C++
XML-RPC for PHP
There are other implementatios of XML-RPC for C++ (I have not used this approach with PHP, so I don't know others alternatives), don't stick with only one, try with others and use what you feel more comfortable with.
If you need some guidance on what stas told you then I suggest you look at
http://us2.php.net/manual-lookup.php?pattern=fsock&src={referrer:source?}
http://us2.php.net/manual-lookup.php?pattern=socket&src={referrer:source?}
In C++ you'll want to create a TCP listener that accepts commands (clearly you'll want to put some method of validation in),
then use PHP to open a connection (use fsock or socket your choice - fsock is easier), and write data to your C++ listener. It's ezpz
//updating with some example code
// protocol://ip, port, $errno, $errstr, $timeout
$fp = fsockopen("tcp://ip", 1337, $errno, $errstr, 30);
if(!$fp) die('failed connection or something');
//write something
fwrite($fp, "stuffs to write");
// get a reply?
while (!feof($fp)) {
echo fgets($fp, 128); // where 128 is size
}
I will try to make my first post here as interesting as possible.
Lately I have been interested in the feasibility of handling WebSocket requests on a shared hosting server.
Please don't tell me "upgrade your plan". All this would be trivial on at least a VPS. I realize that.
As many know, shared hosts will...
Kill a daemon if they see one
Block usage of server sockets
Deny you shell access
Keep apache off limits (no module installations)
These restrictions eliminate phpwebsocket, python altogether. A no-daemon solution that masquerades as a web page is needed.
PHP being my favorite server-side language, I crafted a PHP websocket gateway posing as a web page.
So far I have been successful in sending the right headers for the handshake and streaming output (using output buffering), but I still can't figure out how to continue to read data after the initial request.
In short, I want to continue to receive data from the client even after the PHP script is started. I have tried reading the php://input pseudofile, but I can't seem to get any more reads out of it after the end of the GET. Is there any setting or hack that will allow this?
Thanks!
the short version: What you're trying to do is simply not possible.
the long version: the best you can get is a oneway communication channel that looks like a websocket connection in your browser, but that only works on one direction. From the server to the browser. The other direction will simply not work, because the webserver isn't aware that you're trying to use a different protocol than HTTP, and there is no way of telling it. At least not in the scenario you just outlined.
Your problem here is Apache itself. Once Apache has read the first HTTP request (the websocket handshake) it will continue reading from the TCP connection for any additional HTTP requests. Thus any new data send on the TCP connection will never be passed on to your script. This is necessary as the HTTP/1.1 protocol supports Keep-Alive by default meaning multiple Request/Response cycles are done on one TCP connection. The browser doesn't open a HTTP connection for each request (which was the default in HTTP/1.0). You can't change this behavior. To implement a websocket server you will need to setup your own socket.
After the WebSocket handshake is done, it works pretty much like regular sockets. There is no reason why Apache would allow unidirectional communication without headers.
I'm looking at connecting an existing PHP codebase to a remote CORBA service. All actual data is passed via XML so I don't think I need an IDL to PHP mapping for remote invocation. I just need to connect to the CORBA service, transmit to it the XML string, and read the XML response.
After some research on this I found the CORBA4PHP PHP extension which I'm about to try although am having some reservations (last updated in 2009). I also found numerous implementations in Java and Python.
To avoid dealing with a new PHP extension I'm wondering if there exists a CORBA HTTP proxy of sorts in any language that would take care of communicating with the CORBA service. I would HTTP POST to the proxy (or some socket communication), it would relay it to the CORBA service, and relay back to me its response.
Does such a proxy exist?
I don't know of such a service, but perhaps others might know of one. That said, given how simple your IDL is, I would just go ahead and try the CORBA4PHP extension and use that if it works.
If it doesn't work (I've no idea about its quality), it would be really simple to build such a proxy yourself:
Download a free ORB (let's say you get one for Java, say JacORB)
Compile your IDL and build a client to the CORBA service
Add a front-end API to your Java application which your PHP code will use to call it and pass in the string parameter containing your XML (POST sounds reasonable, and there are plenty of ways to implement such a thing in Java)
I know that you can cache the WSDL but is there a way to cache the soap responses through configuration of the php soapclient?
Obviously, we could "cache" ourselves by constructing some tables in a database and running a cron. This will take much more effort and I am wondering if there is a way to specify caching abilities of the explicit SOAP data being returned from soap server to client.
Similar to how a browser can cache various data based on headers ?
Do I need to have the soap server configured properly or is this something I can do strictly on the soapclient.
Our soap server is a 3rd party vendor which we have little control over so I am hoping to keep the solution to soapclient side if possible.
Open to all suggestions/alternatives (aside from the one I mentioned) if this does not exist.
In short - No. That type of caching is very application-specific, so it's not built in to the protocol for you. I would say that the solution you chalked up your self is a good way to go. A side effect of such a queue is that you get a level of decoupling between your main application and the external service. This can be useful for a lot of things, once you get past the initial development phased (debugging, service windows, logging etc.)
Is it possible to implement a p2p using just PHP? Without Flash or Java and obviously without installing some sort of agent/client on one's computer.
so even though it might not be "true" p2p, but it'd use server to establish connection of some sort, but rest of communication must be done using p2p
i apologize for little miscommunication, by "php" i meant not a php binary, but a php script that hosted on web server remote from both peers, so each peer have nothing but a browser.
without installing some sort of
agent/client on one's computer
Each computer would have to have the PHP binaries installed.
EDIT
I see in a different post you mentioned browser based. Security restrictions in javascript would prohibit this type of interaction
No.
You could write a P2P client / server in PHP — but it would have to be installed on the participating computers.
You can't have PHP running on a webserver cause two other computers to communicate with each other without having P2P software installed.
You can't even use JavaScript to help — the same origin policy would prevent it.
JavaScript running a browser could use a PHP based server as a middleman so that two clients could communicate — but you aren't going to achieve P2P.
Since 2009 (when this answer was originally written), the WebRTC protocol was written and achieved widespread support among browsers.
This allows you to perform peer-to-peer between web browsers but you need to write the code in JavaScript (WebAssembly might also be an option and one that would let you write PHP.)
You also need a bunch of non-peer server code to support WebRTC (e.g. for allow peer discovery and proxy data around firewalls) which you could write in PHP.
It is non-theoretical because server side application(PHP) does not have peer's system access which is required to define ports, IP addresses, etc in order to establish a socket connection.
ADDITION:
But if you were to go with PHP in each peer's web servers, that may give you what you're looking for.
Doesn't peer-to-peer communication imply that communication is going directly from one client to another, without any servers in the middle? Since PHP is a server-based software, I don't think any program you write on it can be considered true p2p.
However, if you want to enable client to client communications with a php server as the middle man, that's definitely possible.
Depends on if you want the browser to be sending data to this PHP application.
I've made IRC bots entirely in PHP though, which showed their status and output in my web browser in a fashion much like mIRC. I just set the timeout limit to infinite and connected to the IRC server using sockets. You could connect to anything though. You can even make it listen for incoming connections and handle them.
What you can't do is to get a browser to keep a two-way connection without breaking off requests (not yet anyways...)
Yes, but its not what's generally called p2p, since there is a server in between. I have a feeling though that what you want to do is to have your peers communicate with each other, rather than have a direct connection between them with no 'middleman' server (which is what is normally meant by p2p)
Depending on the scalability requirements, implementing this kind of communication can be trivial (simple polling script on clients), or demanding (asynchronous comet server).
In case someone comes here seeing if you can write P2P software in PHP, the answer is yes, in this case, Quentin's answer to the original question is correct, PHP would have to be installed on the computer.
You can do whatever you want to do in PHP, including writing true p2p software. To create a true P2P program in PHP, you would use PHP as an interpreted language WITHOUT a web server, and you would use sockets - just like you would in c/c++. The original accepted answer is right and wrong, unless however the original poster was asking if PHP running on a webserver could be a p2p client - which would of course be no.
Basically to do this, you'd basically write a php script that:
Opens a server socket connection (stream_socket_server/socket_create)
Find a list of peer IP's
Open a client connection to each peer
...
Prove everyone wrong.
No, not really. PHP scripts are meant to run only for very small amount of time. Usually the default maximum runtime is two minutes which will be normally not enough for p2p communication. After this the script will be canceled though the server administrator can deactivate that. But even then the whole downloading time the http connection between the server and the client must be hold. The client's browser will show in this time its page loading indicator. If the connection breakes most web servers will kill the php script so the p2p download is canceled.
So it may be possible to implement the p2p protocol, but in a client/server scenario you run into problems with the execution model of php scripts.
both parties would need to be running a server such as apache although for demonstration purposes you could get away with just using the inbuilt php test server. Next you are going to have to research firewall hole punching in php I saw a script i think on github but was long time ago . Yes it can be done , if your client is not a savvy programmer type you would probably need to ensure that they have php installed and running. The path variable may not work unless you add it to the system registry in windows so make sure you provide a bat file that both would ensure the path is in the system registry so windows can find it .Sorry I am not a linux user.
Next you have to develop the code. There are instrucions for how hole punching works and it does require a server on the public domain which is required to allow 2 computers to find each others ip address. Maybe you could rig up something on a free website such as www.000.webhost.com alternatively you could use some kind of a built in mechanism such as using the persons email address. To report the current ip.
The biggest problem is routers and firewalls but packets even if they are directed at a public ip still need to know the destination on a lan so the information on how to write the packet should be straight forwards. With any luck you might find a script that has done most of the work for you.