Question

I'm working on a solution to redirect http requests from my browser to another pc. In a nutshell: Is there a more accurate way to send an incoming HttpListenerRequest as an HttpRequest to a client?

Background: The browser sends http requests to 127.0.0.1:9666 (yes, click'n'load), which should be answered by a download program. In my case, the download program isn't running on the machine which runs the browser. Port Forwarding tools like these don't work for me: http://www.quantumg.net/portforward.php So I decided to write a specific click'n'load redirector in C#. My problem is to redirect the browser's request. ATM, I listen on 127.0.0.1:9666, send some information to a client, the client redirects this to the downloader program, which answers. (long term short: this is redirected to the browser). But using pre-defined cases to redirect only the core-information doesn't seem quite right for me. It should be possible to redirect the whole request. So I don't need to differ between various cases, and this should be more accurate. Is there any other way to redirect this request, except from copying all headers and properties?

The Server uses an HttpListener to listen for the browser's requests. Then, the server sends an HttpReqest to the Client. The Client uses an HttpListener to listen for the server's requests. The client sends an HttpRequest to the Downloader, uses GetResponse, and sends this as a response to the server, which responds to the browser. I've looked up some functions in the MSDN, but didn't find a good way to "copy a whole request".

So here is my problem code:

Thread.Sleep(1500);
//Read client's/JDownloader's stream, send to browser/redirector
do
{
    Read = Outstream.Read(Buffer, 0, Buffer.Length);
    Totalr += Read;
    Instream.Write(Buffer, 0, Read);
    Sent += Read;
    // Bufferstr += ASCIIEncoding.ASCII.GetString(Buffer, 0, Read); debugging
} while (Read != 0);

Without the Thread.Sleep, the first read returns 171 bytes were read (just and exactly the HTTP header, buffer-length is 1024bytes). second iteration: when executing Outstream.Read, nothing happens. No matter how long I wait. It seems, the reader is waiting for traffic to receive, but there is no traffic to receive (weird...) When the thread sleeps for 500-1500ms, the first read returns 351bytes were read (the complete http request), and then again, second iteration, nothing. This happens when reading from the browser's or JDownloader's NetworkStream. They never return 0. A dirty method to get this working is to replace the while-argument with Read == Buffer.Length, dirty because it will fail when exactly Buffer.Length bytes are received (endless waiting again, yay). The DataAvailable property also dosn't always seem to be right, sometimes it is set to false, when the program didn't even read something from the stream, but there were bytes to receive.(also weird...) Any other ideas for proper receiving loops?


Nobody? short summary of my problem: neither the browser's request stream, nor JDownloaders response stream return 0. When attempting another read, the program just waits for more bytes to receive. So I don't know a failsafe method to read the entire stream. Just repeating until the amount of bytes read is lower than the buffer's length will result in previously mentioned endless wait for bytes, when streamlength % bufferlength == 0.

Also, it seems JDownloader needs more time to generate an answer and write it into the stream than my program attempts to read the stream. So I will only receive a part of the stream. Another read attempt will result in, hooray, an endless wait for bytes. Is there another way to receive the whole stream without a static delay (via thread sleep)?

Was it helpful?

Solution

Can you just open a TcpListener and forward the raw bytes? That way you do not need to concern yourself with HTTP at all.

OTHER TIPS

What you ask for is basically a proxy implementation - building a well working proxy is no simple task as you will have to understand and handle HTTP etc. in both directions.

I would recommend to either use an existing library for that OR some configurable proxy:

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