Victor Stone
Victor Stone

Reputation: 528

HTTP over socket using HTTP proxy

I have to use C#'s Socket class to load a web page. I've managed to learn a lot today and I can successfully create the GET request required to load a page.

However now I would like to use an HTTP proxy.

I've also learned how to connect to the proxy.

The problem I'm having now is, once I'm connected, how do I 'GET' the page?

Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Connect(proxyIP, proxyPort);
string connectMsg = "CONNECT " + proxyIPString + ":" + proxyPortString + " HTTP/1.1\r\n" +
                    "Proxy-Authorization: Basic " + base64ProxyCredentials + "\r\n" +
                    "\r\n";
byte[] msg = System.Text.Encoding.ASCII.GetBytes(connectMsg);
s.Send(msg);
string proxyConnectionResponseHeader = "";
while (!proxyConnectionResponseHeader.Contains("\r\n\r\n"))
{
    // read the header byte by byte, until \r\n\r\n
    byte[] buffer = new byte[1];
    s.Receive(buffer, 0, 1, 0);
    proxyConnectionResponseHeader += Encoding.ASCII.GetString(buffer);
}
if (!proxyConnectionResponseHeader.Contains("200 Connection established"))
{
    return /*some error*/;
}

At this point, I'm successfully connected to the proxy. Why does the following return a bad request?

string request = "GET / HTTP/1.1\r\n" +
                "Host: whatismyipaddress.com\r\n" +
                "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0\r\n" +
                "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
                "Accept-Language: en-US,en;q=0.5\r\n" +
                "Accept-Encoding: gzip, deflate\r\n" +
                "Connection: keep-alive\r\n" +
                "\r\n";
msg = Encoding.ASCII.GetBytes(request);
s.Send(msg);
string getResponseHeader = "";
while (!getResponseHeader.Contains("\r\n\r\n"))
{
    // read the header byte by byte, until \r\n\r\n
    byte[] buffer = new byte[1];
    s.Receive(buffer, 0, 1, 0);
    getResponseHeader += Encoding.ASCII.GetString(buffer);
}

The header of the response seems to be from the proxy rather than 'whatismyipaddress.com'

HTTP/1.0 400 Bad Request
Server: squid/3.1.19
Mime-Version: 1.0
Date: Sun, 04 Oct 2015 02:00:32 GMT
Content-Type: text/html
Content-Length: 3141
X-Squid-Error: ERR_INVALID_URL 0
Vary: Accept-Language
Content-Language: en
X-Cache: MISS from funky
X-Cache-Lookup: NONE from funky:<port>
Connection: close

EDIT: Or am I misunderstanding the process of using a proxy?

Upvotes: 0

Views: 1038

Answers (2)

Hikmet
Hikmet

Reputation: 63

string connectMsg = "CONNECT whatismyipaddress.com:80 HTTP/1.1\r\n" +
                "Proxy-Authorization: Basic " + base64ProxyCredentials + "\r\n" +

Upvotes: 0

Victor Stone
Victor Stone

Reputation: 528

Clemens is correct.

I didn't need to do a "CONNECT", I just need to issue GET requests normally, except pass authorization along with it. Also use an absolute path rather than relative.

string request = "GET http://whatismyipaddress.com/ HTTP/1.1\r\n" +
                 "Host: whatismyipaddress.com\r\n" +
                 "Proxy-Authorization: Basic " + base64ProxyCredentials + "\r\n" +
                 "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0\r\n" +
                 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
                 "Accept-Language: en-US,en;q=0.5\r\n" +
                 "Accept-Encoding: gzip, deflate\r\n" +
                 "Connection: keep-alive\r\n" +
                 "\r\n";
msg = Encoding.ASCII.GetBytes(request);
s.Send(msg);

Upvotes: 2

Related Questions