Search code examples
c#.netsystem.net.httpwebrequest

How to upload data by portions via HttpWebRequest


Problem:

I want to upload data by chunks via a single http request and show progress changes after each uploading (phisical sending data over the internet). (Now is not important how I shall show an uploading progress. I can simply output some data to the console).

Code:

Stackoverlow has many such questions: link 1, etc. (I can not include more links because I have no sufficient reputation).

using System;
using System.Text;
using System.IO;
using System.Net;

...

public static void UploadData()
{
    const string data = "simple string";
    byte[] buffer = new ASCIIEncoding().GetBytes(data);

    // Thanks to http://www.posttestserver.com all is working from the box
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://posttestserver.com/post.php");
    req.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.10 " + 
                    "(KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10";
    req.Accept = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
    req.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
    req.Headers.Add("Accept-Language", "en-US,en;q=0.8");
    req.Method = "POST";
    req.ContentType = "application/x-www-form-urlencoded";
    req.ContentLength = buffer.Length;            
    req.SendChunked = true;            

    int bytesRead = buffer.Length;
    const int chunkSize = 3;
    Stream s = req.GetRequestStream();
    for (int offset = 0; offset < bytesRead; offset += chunkSize)
    {
        int bytesLeft = bytesRead - offset;
        int bytesWrite = bytesLeft > chunkSize ? chunkSize : bytesLeft;
        s.Write(buffer, offset, bytesWrite);
    }
    s.Close(); // IMPORTANT: only here all data will be send
}

Remarks:

Also according to this link, each sending must occur during each writing to a request stream, but in reality (it can be demonstrated in Fiddler) all sending operations occur only after request stream closing or only by response getting and not earlier. (all depends from the SendChuncked, AllowWriteStreamBuffering and ContentLength parameters, but data are never sent after each writing to a stream).

Question:

How data can be sent (physically) after each writing (each call of the Write method)?

Constraints:

  • Net 2.0;

  • using only the HttpWebRequest primitive (not WebClient).


Solution

  • Because nobody answered this question, but this question has been answered on russian stackoverflow by the zergatul user, I shall post this answer from russian stackoverflow here.


    The answer
    It works how you expected. I used Microsoft Network Monitor. This is a good utility and it is free (in contrast to httpdebugger). I debugged your code in Net 2.0.

    enter image description here

    Network Monitor shows each 3-byte sending (I have taken a longer string).

    enter image description here

    Here the text "ple" ("simple string") has been sent.

    enter image description here


    Remark
    In the first picture the string
    // ВАЖНО: только здесь будут отправлены данные через сеть
    means
    // IMPORTANT: only here data will be sent over the net