Click here to Skip to main content
15,900,815 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello,

I've been trying to get this HTTPwrapper class to work, but for some reason it keeps getting stuck at ReadToEnd(); for about 3 minutes at line 140. This used to work pretty good, but all of a sudden it keeps locking.

Oke, well, this is my code:

XML
//-----------------------------------------------------------------------
// <copyright file="ClsHttpWrapper.cs" company="Ron.Sijm.">
//     Copyright (c) Necrowizard. All rights reserved.
// </copyright>
// <author>Necrowizard</author>
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
/// <summary>
/// Httpwrapper class. Class to use HTTP functions like POST and GET
/// </summary>
public class Httpwrapper
{
    /// <summary>
    /// the TcpClient, used for all traffic.
    /// </summary>
    private TcpClient client;
    /// <summary>
    /// Cookie dictionary. Keeping the right cookies for the right sites.
    /// </summary>
    private IDictionary<string, string> colCookies = new Dictionary<string, string>();
    /// <summary>
    /// Cookies string.
    /// </summary>
    private string strCookies;
    /// <summary>
    /// The last page visted
    /// </summary>
    private string lastPage;
    /// <summary>
    /// Function to send HTTPRequests
    /// </summary>
    /// <param name="method">GET or POST</param>
    /// <param name="url">The URL You want to go to</param>
    /// <param name="referer">The referrer you want to use</param>
    /// <returns>The data from the http request.</returns>
    public string Request(string method, string url, string referer = null)
    {
        string strFile;
        string strPost = null;
        var pos = 0;
        referer = referer ?? this.lastPage;
        var host = url.Contains("http://") ? url.Substring(7) : url;
        if (host.Contains("/"))
        {
            pos = host.IndexOf("/", 0);
            strFile = host.Substring(pos);
            host = host.Substring(0, pos);
        }
        else
        {
            strFile = "/";
        }
        if (method == "POST")
        {
            pos = strFile.IndexOf("?");
            if (pos != -1)
            {
                strPost = strFile.Substring(pos + 1);
                strFile = strFile.Substring(0, pos);
            }
            else
            {
                strPost = null;
            }
        }
        this.lastPage = url;
        string reqHeaders = null;
        if (method == "GET" || method == "PIC")
        {
            reqHeaders = "GET" + " " + strFile + " HTTP/1.1" + "\r\n"
            + "Host: " + host + "\r\n"
            + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7" + "\r\n"
            + "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/ *;q=0.5" + "\r\n"
            + "Accept-Language: en-us,en;q=0.5" + "\r\n"
            + "Accept-Encoding: gzip, deflate" + "\r\n"
            + "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" + "\r\n"
            + "Keep-Alive: 300" + "\r\n"
            + "Connection: keep-alive" + "\r\n"
            + "Referer: " + referer + "\r\n"
            + "Cookie: " + this.strCookies + "\r\n" + "\r\n";
        }
        else
        {
            var contentLength = strPost;
            reqHeaders = "POST " + strFile + " HTTP/1.1" + "\r\n"
                                + "Host: " + host + "\r\n"
                                +
                                "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7" +
                                "\r\n"
                                +
                                "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/ *;q=0.5" +
                                "\r\n"
                                + "Accept-Language: en-us,en;q=0.5" + "\r\n"
                                + "Accept-Encoding: gzip, deflate" + "\r\n"
                                + "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" + "\r\n"
                                + "Connection: close" + "\r\n"
                                + "Referer: " + referer + "\r\n"
                                + "Cookie: " + this.strCookies + "\r\n"
                                + "Content-Type: application/x-www-form-urlencoded" + "\r\n"
                                + "Content-Length: " + contentLength + "\r\n"
                                + "Connection: close" + "\r\n" + "\r\n"
                                + strPost;
            }
        if (method == "PIC")
        {
            if (reqHeaders != null)
            {
                reqHeaders.Replace("Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/ *;q=0.5", "Accept: image/png,*/*;q=0.5");
            }
        }
        this.client = new TcpClient(host, 80);
        var headers = System.Text.Encoding.ASCII.GetBytes(reqHeaders);
        var ns = this.client.GetStream();
        ns.Write(headers, 0, headers.Length);
        var sr = new StreamReader(ns, Encoding.Default);
<big>        //ReadToEnd gets stuck for 2 minutes here!
        var strHtml = sr.ReadToEnd();</big>
        var strParts = Regex.Split(strHtml, Environment.NewLine + Environment.NewLine);
        this.strCookies = this.ParseCookies(strParts[0]);
        if (strParts[0].Contains("Content-Encoding"))
        {
            strParts[1] = DecompressGzip(strParts[1]);
        }
        return strParts[0] + Environment.NewLine + Environment.NewLine + strParts[1];
    }
    /// <summary>
    /// Method to strip the header data from a httpRequest
    /// </summary>
    /// <param name="strSource">The source to strip it from</param>
    /// <returns>The data without a header</returns>
    public string StripHeaders(string strSource)
    {
        var strParts = Regex.Split(strSource, Environment.NewLine + Environment.NewLine);
        return strParts[1];
    }
    /// <summary>
    /// Function to grab a picure from an url
    /// </summary>
    /// <param name="strURL">The url to grab the picture from</param>
    /// <returns>The picture in a bitmap format</returns>
    public Bitmap GrabPic(string strURL)
    {
        var memStream = new MemoryStream(System.Text.Encoding.Default.GetBytes(this.StripHeaders(this.Request(" GET", strURL, this.lastPage))));
        var bitmap = new Bitmap(memStream);
        return bitmap;
    }
    /// <summary>
    /// Function to delete all cookies.
    /// </summary>
    public void ClearCookies()
    {
        this.colCookies.Clear();
        this.strCookies = null;
    }
    /// <summary>
    /// Function to decompress Gzip html data
    /// </summary>
    /// <param name="compressed">The compressed html dats</param>
    /// <returns>the decompressed html data</returns>
    private static string DecompressGzip(string compressed)
    {
        var memStream = new MemoryStream(System.Text.Encoding.Default.GetBytes(compressed));
        var decompressStream = new GZipStream(memStream, CompressionMode.Decompress);
        var endBytes = new byte[4];
        var position = (int)memStream.Length - 4;
        memStream.Position = position;
        memStream.Read(endBytes, 0, 4);
        memStream.Position = 0;
        var buffer = new byte[BitConverter.ToInt32(endBytes, 0) + 100];
        var offset = 0;
        while (true)
        {
            var o = decompressStream.Read(buffer, offset, 100);
            if (o == 0)
            {
                break;
            }
            offset += o;
        }
        return Encoding.ASCII.GetString(buffer);
    }
    /// <summary>
    /// Function to pause the program.
    /// </summary>
    /// <param name="seconds">amount of seconds to pause</param>
    private static void Pause(double seconds)
    {
        var num = seconds * 1000;
        DateTime t1 = DateTime.Now, t2 = DateTime.Now;
        var tmpDiff = t2 - t1;
        while (Convert.ToDouble(tmpDiff.TotalMilliseconds.ToString()) < num)
        {
            t2 = DateTime.Now;
            tmpDiff = t2 - t1;
            Application.DoEvents();
        }
    }
    /// <summary>
    /// Function to parse cookies from a html request
    /// </summary>
    /// <param name="headers">The htlm headers containing the cookies.</param>
    /// <returns>The parsed cookies</returns>
    private string ParseCookies(string headers)
    {
        string parseCookies = null;
        var reg = new Regex("set-cookie:\\s*([^=]+)=([^;]+) ;", RegexOptions.IgnoreCase);
        if (reg.IsMatch(headers))
        {
            var matches = reg.Matches(headers);
            foreach (Match m in matches)
            {
                if (this.colCookies.ContainsKey(m.Groups[1].ToString()))
                {
                    this.colCookies.Remove(m.Groups[1].ToString());
                    this.colCookies.Add(m.Groups[1].ToString(), m.Groups[1].ToString() + "=" + m.Groups[2].ToString());
                }
                else
                {
                    this.colCookies.Add(m.Groups[1].ToString(), m.Groups[1].ToString() + "=" + m.Groups[2].ToString());
                }
            }
        }
        foreach (KeyValuePair<string, string> item in this.colCookies)
        {
            parseCookies = parseCookies + item.Value.ToString() + "; ";
        }
        return parseCookies;
    }
}


To call it:

text1.text = http.Request("GET", "http://google.com/");


Sorry for the large lap of code... but I figured it was probably better than a few random snipets...

Code is checked, and is considered valid by stylecop, so it should be readable...

Does anyone know how to fix this, or does anyone have any alternative?
I'm looking for some HTML swissknife class which allows me to send raw POST and GET requests, save returned cookies (for sites that require login)

Thanks in advance,

Gr.


PS, getting a popup telling me this message is extreme long, and might piss off people with low bandwidth; well, I'm sorry ;)
Posted

1 solution

Can you use the HttpRequest/Response classes rather than rolling your own lowlevel implementat?

You could also try the HtmlAgilityPack library.
 
Share this answer
 
Comments
Necrowizard 17-Jul-10 10:40am    
Reason for my vote of 3
Thanks for the HtmlAgilityPack suggestion, it does the job, but its really slow tho

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900