Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

POST request using sockets C#

Tags:

c#

post

sockets

I'm trying to make an auction sniper for a site. To place a bid you need to send 4 parameters(and cookies of course) to /auction/place_bid. I need to use sockets, not HttpWebRequest. Here's the code:

        string request1 = "POST /auction/place_bid HTTP/1.1\r\nHost: *host here*\r\nConnection: Keep-Alive\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)\r\nAccept: /*\r\nContent-Type: application/x-www-form-urlencoded; charset=UTF-8\r\nX-Requested-With: XMLHttpRequest\r\n" + cookies +"\r\n";
        string request3 = "token=" + token + "&aid=" + aid + "&bidReq=" + ptzReq + "&recaptcha_challenge_field=" + rcf + "&recaptcha_response_field=" + rrf+"\r\n\r\n";
        string request2 = "Content-Length: " + (Encoding.UTF8.GetByteCount(request1+request3)+23).ToString() + "\r\n";
        byte[] dataSent = Encoding.UTF8.GetBytes(request1+request2+request3);
        byte[] dataReceived = new byte[10000];
        Socket socket = ConnectSocket(server, 80);
        if (socket == null)
        {
            return null;
        }
        socket.Send(dataSent, dataSent.Length, 0);
        int bytes = 0;
        string page = "";
        do
        {
            bytes = socket.Receive(dataReceived, dataReceived.Length, 0);
            page = page + Encoding.ASCII.GetString(dataReceived, 0, bytes);
        }
        while (bytes > 0);

        return page;

When I'm trying to receive the webpage Visual Studio says that "Operation on an unblocked socket cannot be completed immediatly", when I add

socket.Blocking = true;

My application stops responsing and after ~1 minute it returns page, but it's empty! When I'm trying to make a GET request it works perfect. I hope you will help me. By the way, this is the first time when I use sockets so my code is pretty bad, sorry about that.

*I'm using a ConnectSocket class, which was given as an example at msdn (The link leads to Russian MSDN, sorry, I didn't find the same article in English, but you'll understand the code anyway)

like image 287
Cracker Avatar asked Feb 18 '11 12:02

Cracker


1 Answers

The Content-Length header should indicate the size of the content. You're setting it to the total size of your headers and content.

Encoding.UTF8.GetByteCount(request1+request3)+23).ToString()

Since the content part of your message is just request3, the server is patiently waiting for ByteCount(request1)+23 more bytes of content which you never send.

Try this instead:

"Content-Length: " + Encoding.UTF8.GetByteCount(request3).ToString() + "\r\n"

Another issue looks like your loop:

do
{
    bytes = socket.Receive(dataReceived, dataReceived.Length, 0);
    page = page + Encoding.ASCII.GetString(dataReceived, 0, bytes);
}
while (bytes > 0);

Since non-blocking socket operations always return immediately whether or not they've completed yet, you need a loop that keeps calling Receive() until the operation has actually completed. Here, if the call to Receive() returns 0 (which it almost certainly will the first time) you exit the loop.

You should at least change it to while (bytes <= 0) which would get you at least some data (probably just the first packet's worth or so). Ideally, you should keep calling Receive() until you see the Content-Length header in the reply, then continue calling Receive() until the end of the headers, then read Content-Length more bytes.

Since you're using sockets, you really have to re-implement the HTTP protocol.

like image 191
eater Avatar answered Sep 26 '22 02:09

eater