0

I'm trying to login to a website via HttpWebRequests from my C# Application. The post data of the login page looks like:

-----------------------------18327245165630\r\n
Content-Disposition: form-data; name="user"\r\n
\r\n
123\r\n
-----------------------------18327245165630\r\n
Content-Disposition: form-data; name="pass"\r\n
\r\n
1234\r\n
-----------------------------18327245165630\r\n
Content-Disposition: form-data; name="mode"\r\n
\r\n
login\r\n
-----------------------------18327245165630\r\n
Content-Disposition: form-data; name="submit"\r\n
\r\n
Submit\r\n
-----------------------------18327245165630--\r\n

The fields are user and pass and the values completed on browser are 123 and 1234 .

The question is how to send these values via HttpWebRequests?

My code looks like:

private void loginButton_Click(object sender, EventArgs e)
{
    try
    {
        HttpWebRequest oRequest = null;
        oRequest = (HttpWebRequest)HttpWebRequest.Create(loginLinkPost);
        oRequest.ContentType = "multipart/form-data; boundary=" + PostData.boundary;
        oRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0";

        oRequest.KeepAlive = true;
        oRequest.AllowAutoRedirect = true;

        oRequest.Method = "POST";
        oRequest.CookieContainer = cookies;
        PostData pData = new PostData();
        Encoding encoding = Encoding.UTF8;
        System.IO.Stream oStream = null;

        pData.Params.Add(new PostDataParam("email", this.usernameBox.Text, PostDataParamType.Field));
        pData.Params.Add(new PostDataParam("password", this.passwordBox.Text, PostDataParamType.Field));
        pData.Params.Add(new PostDataParam("mode", "login", PostDataParamType.Field));
        pData.Params.Add(new PostDataParam("submit", "Submit", PostDataParamType.Field));

        byte[] buffer = encoding.GetBytes(pData.GetPostData());
        oRequest.ContentLength = buffer.Length;
        oStream = oRequest.GetRequestStream();
        oStream.Write(buffer, 0, buffer.Length);
        oStream.Close();

        string sursa = "";
        using (HttpWebResponse oResponse = (HttpWebResponse)oRequest.GetResponse())
        {
            if (oResponse.StatusCode == HttpStatusCode.OK)
            {
                System.IO.Stream responseStream = oResponse.GetResponseStream();
                System.IO.StreamReader reader = new System.IO.StreamReader(responseStream, Encoding.UTF8);
                sursa = reader.ReadToEnd();
                MessageBox.Show("Logged in :)!");
            }
            else
            {
                setStatus("Server response failed...");
                MessageBox.Show("Server failed to respond!", "Error!");
                setStatus("Ready...");
            }
        }
    }
    catch(Exception ex)
    {
        setStatus("Error while trying to log in...");
        MessageBox.Show(ex.ToString(), "Error when try to login...");
        setStatus("Ready...");
    } 
}

And the PostData.cs Class:

namespace IPSocksBot
{
    public class PostData
    {
        public static string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");

        private List<PostDataParam> m_Params;

        public List<PostDataParam> Params
        {
            get { return m_Params; }
            set { m_Params = value; }
        }

        public PostData()
        {
            m_Params = new List<PostDataParam>();
        }
        public string GetPostData()
        {
            StringBuilder sb = new StringBuilder();
            foreach (PostDataParam p in m_Params)
            {
                sb.AppendLine("--" + boundary + "\\r\\n");

                if (p.Type == PostDataParamType.File)
                {
                    sb.AppendLine(string.Format("Content-Disposition: file; name=\"{0}\"; filename=\"{1}\"", p.Name, p.FileName));
                    sb.AppendLine("Content-Type: application/octet-stream");
                    sb.AppendLine();
                    sb.AppendLine(p.Value);
                }
                else
                {
                    sb.AppendLine(string.Format("Content-Disposition: form-data; name=\"{0}\"\\r\\n", p.Name));
                    sb.AppendLine("\\r\\n");
                    sb.AppendLine(p.Value + "\\r\\n");
                }
            }

            sb.AppendLine("--" +boundary + "--" + "\\r\\n");

            return sb.ToString();
        }
    }

    public enum PostDataParamType
    {
        Field,
        File
    }

    public class PostDataParam
    {
        public PostDataParam(string name, string value, PostDataParamType type)
        {
            Name = name;
            Value = value;
            Type = type;
        }

        public PostDataParam(string name, string filename, string value, PostDataParamType type)
        {
            Name = name;
            Value = value;
            FileName = filename;
            Type = type;
        }

        public string Name;
        public string FileName;
        public string Value;
        public PostDataParamType Type;
    }
}

What I'm missing? Why my values aren't submitted? I've used Fiddler to see my sending post values and are exactly the same... .

caffeine
  • 435
  • 7
  • 26

1 Answers1

1

As i see your code i notice 2 thing that might cause the problem.
First: you should use same name to send data!
If you see browser send user you should use it too. So change email to user and do same for pass field.

-----------------------------18327245165630\r\n
Content-Disposition: form-data; name="user"\r\n
\r\n
123\r\n

so your code should like this one:

pData.Params.Add(new PostDataParam("user", this.usernameBox.Text, PostDataParamType.Field));
pData.Params.Add(new PostDataParam("pass", this.passwordBox.Text, PostDataParamType.Field));
pData.Params.Add(new PostDataParam("mode", "login", PostDataParamType.Field));
pData.Params.Add(new PostDataParam("submit", "Submit", PostDataParamType.Field));

The second thing i noticed is in your PostData.cs Class!
you should enter \r\n instead of \\r\\n.

Make sure that the length of your request be equal to length of request send by fiddler.

Hope it helps you. Best regards.

MasterAref
  • 59
  • 4
  • \\r\\n are because I have to escape the backslashes. – caffeine Apr 29 '14 at 18:25
  • **@curiosul1**You will encode string to UTF-8 so why you need to use escape character?\\r\\n cause string's length increase and this cause problem! – MasterAref Apr 29 '14 at 19:33
  • I don't know why but I've replaced \\r\\n with \r\n and when check webforms with Fiddler the \\r\\n tags are complete missing from any request... and \n was replaced with new line in request... – caffeine Apr 29 '14 at 20:52
  • @curiosul \r\n is for newline! so Did it work? if it's possible for you, please tell the URL so maybe we can help more. – MasterAref May 01 '14 at 04:48
  • My generated boundary looks like: 8d13c0e39a292f8 but captured boundarys from website all looks like this: 11692187636794 , this should not be a problem, or? – caffeine May 12 '14 at 12:36
  • Solved! And yes, the problem was with "\r\n" sequences. There was too many newline sequences. Thank you :) – caffeine May 12 '14 at 16:54