简体   繁体   中英

Redirect an octet stream in Apache using PHP or Django

I have a webserver which serves the client with an octet stream on port 20000 (it's actually a socket.io server hosted with node.js). This is running on a shared hosting account with a regular Apache server running on port 80 (this cannot be turned off, hence the socket.io server is on port 20000). Due to firewalls and such, 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 produced by the socket.io server from the Apache server (sort of like a reverse proxy)? Unfortunately I cannot use mod_proxy on my Apache server given restraints of my hosting plan. I was thinking I could do this with a PHP page that opens a socket somehow.

Update: I also have Django for Python 3 installed on my server which could be useful. Please note that the proxy cannot simply request the target page and serve it back to the client since the data has to be transferred in real time.

Re "it cannot simply serve the target page back" ... this is not true because this is all an HTTP proxy is. Most protocol proxies use a socket (versus a file or pipe) and simply copy the data from socket to socket. An HTTP proxy does the same thing except 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. A POST proxy will need extra footwork.

I am not familiar with Socket.IO, but upon researching ... how does socket.io work? ... it appears it uses only "old" HTTP features and runs everything as REST. The REST is encapsulated as a transport inside of a persistent socket.

If you were looking for an TCP or IP-level proxy within Django, its not going to happen. Your apache server, and then WSGI/CGI/whatever closes the TCP socket off from you. The only way you'll be able to access it is with sufficient permissions to those parts of the server.

Here's what I'd do ... In django make a url pattern that captures the socket.io api, and have it connect to a view that does something like the following (untested pseudo code):

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 don't have an octet stream available so apologies for not testing.

Seems possible not impossible. I have not done it before but know the way to do but again I don't know the impact of Firewall on port openning and closing. The basic Idea about doing thing is:

Get you request from port 80 to do things and for response of that request use different port to communicate with client. It would become a tunnel to recieve request from one port and get reply from the other port. Only one thing to be properly taken care of that termination of connection as soon as possible once the purpose is resolve unless it would create memory load on the server.

With the below example you can do the above things but suggest you to use them with caution and after proper testing.

ref: Programming with Sockets through PHP

This example shows a simple talkback server. Change the address and port variables to suit your setup and execute. You may then connect to the server with a command similar to: telnet 192.168.1.53 10000 (where the address and port match your setup). Anything you type will then be output on the server side, and echoed 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";
?>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM