Redirect octet stream in Apache using PHP or Django

I have a web server that serves a client with an octet stream on port 20000 (it is actually a socket.io server hosted with node.js). This is done on a shared hosting account with a regular Apache server running on port 80 (this cannot be disabled, so socket.io server is on port 20000). Due to firewalls etc. I cannot expect the user to be able to connect to port 20000 (or any other than 80). So, how can I serve the client with the octet stream created by socket.io from the Apache server (sort of like a reverse proxy)? Unfortunately, I cannot use mod_proxy on my Apache server with the limitations of my hosting plan. I thought I could do this with a PHP page that somehow opens a socket.

Update: I also have Django for Python 3 installed on my server, which may be useful. Please note that the proxy server cannot simply request the landing page and return it to the client, since the data must be transmitted in real time.

+6
source share
2 answers

Re "it cannot just return the landing page back" ... it is not, because it is all an HTTP proxy. Most proxy protocols use a socket (compared to a file or pipe) and simply copy data from the socket to the socket. The HTTP proxy does the same, except that every HTTP request requires a handshake, so the proxy will require a few packets back and forth before reaching the payload. You can create an HTTP GET proxy very easily in django. The POST proxy server will require additional work.

I am not familiar with Socket.IO, but when researching ... how does socket.io work? ... it looks like it uses only the "old" HTTP and runs everything as REST. REST is encapsulated as a transport inside a persistent socket.

If you were looking for a TCP or IP proxy in Django, it will not happen. Your apache server, and then WSGI / CGI / no matter what you close the TCP socket from you. The only way to access it is with sufficient permissions for these parts of the server.

Here I would do ... In django, create a url template that captures the socket.io api and connects to a view that does something like the following (unverified pseudocode):

import urllib2, mimetypes from django.http import HttpResponse def ForwardToSocketIO(request): # Capture the URL pattern path = request.get_full_path() # Create a URL opener response = urllib2.urlopen('http://localhost:20000%s' % path) # Capture and return response django_response = HttpResponse(response.read()) django_response['Content-Type'] = 'octet-stream' return django_response 

Hope this helps. I have no octet stream, so apologies for not testing.

+2
source

Seems possible not impossible. I have not done this before, but I know how to do it, but again I do not know how the firewall affects the opening and closing of the port. The basic idea of ​​what to do:

Receive a request from port 80 to do something, and to respond to this request, use a different port to communicate with the client. This will become a tunnel to receive a request from one port and receive a response from another port. Only one thing that should be properly taken care of this termination of the connection as soon as possible, when the goal is resolved, unless it creates a memory load on the server.

In the example below, you can do all of the above, but suggest using them with caution and after proper testing.

ref: Programming with Sockets via PHP

This example shows a simple talkback server. Change the address and port settings according to your settings and execute. Then you can connect to the server using a command similar to: telnet 192.168.1.53 10000 (where the address and port correspond to your setting). Everything that you type will be displayed on the server side and will be repeated back to you. To disconnect, enter "quit".

 <?php error_reporting(E_ALL); echo "<h2>TCP/IP Connection</h2>\n"; /* Get the port for the WWW service. */ $service_port = getservbyname('www', 'tcp'); /* Get the IP address for the target host. */ $address = gethostbyname('www.example.com'); /* Create a TCP/IP socket. */ $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket === false) { echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; } else { echo "OK.\n"; } echo "Attempting to connect to '$address' on port '$service_port'..."; $result = socket_connect($socket, $address, $service_port); if ($result === false) { echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n"; } else { echo "OK.\n"; } $in = "HEAD / HTTP/1.1\r\n"; $in .= "Host: www.example.com\r\n"; $in .= "Connection: Close\r\n\r\n"; $out = ''; echo "Sending HTTP HEAD request..."; socket_write($socket, $in, strlen($in)); echo "OK.\n"; echo "Reading response:\n\n"; while ($out = socket_read($socket, 2048)) { echo $out; } echo "Closing socket..."; socket_close($socket); echo "OK.\n\n"; ?> 
0
source

Source: https://habr.com/ru/post/987951/


All Articles