PC Review


Reply
Thread Tools Rate Thread

async http upload

 
 
éric
Guest
Posts: n/a
 
      19th Feb 2004
Hi,
below is the code I sort of adapted from an async http download example I
found so that I could upload files to the server.
It seems to be doing it asynchronously and the file makes it to the server
but it is going all in one shot.
How can trap it at every 1024 bytes to trigger an event like progress bar
advance as it does in the download version of this code?
When the code calls back uReadCallBack for the first time the entire file is
already on the server?

Any ideas?

-----------Code Start-------------

internal class UploadInfo
{
const int BufferSize = 1024;
internal byte[] BufferWrite;
internal bool useFastBuffers;
internal byte[] dataBufferFast;
internal System.Collections.ArrayList dataBufferSlow;
internal int dataLength;
internal int bytesProcessed;
internal HttpWebRequest Request;
internal Stream ResponseStream;
internal DownloadProgressHandler ProgressCallback;

internal UploadInfo()
{
BufferWrite = new byte[BufferSize];
Request = null;
bytesProcessed = 0;
useFastBuffers = true;
}
}

internal class WebDownload
{
private event System.EventHandler eventStop;
private event ECASOFT.Controls.DownloadError eventError;
internal ManualResetEvent allDone = new ManualResetEvent(false);
internal bool Abort;
private WebRequest req;

const int BUFFER_SIZE = 1024;
internal event System.EventHandler Aborted
{
add {eventStop += new System.EventHandler (value);}
remove {eventStop -= new System.EventHandler (value);}
}
internal event ECASOFT.Controls.DownloadError DownloadError
{
add {eventError += new ECASOFT.Controls.DownloadError (value);}
remove {eventError -= new ECASOFT.Controls.DownloadError (value);}
}
// Start the upload
internal byte[] Upload(
string url, string username, string password, string domain,
DownloadProgressHandler progressCB)
{
try
{
Abort = false;

allDone.Reset();

Uri httpSite = new Uri(url);

FileStream rdr = new FileStream(\\My File.txt, FileMode.Open);

HttpWebRequest req = (HttpWebRequest) WebRequest.Create(url);
req.Method = "PUT";

req.PreAuthenticate = true;
req.Credentials = new NetworkCredential(username, password,
domain);
req.AllowWriteStreamBuffering = true;
req.ContentLength = rdr.Length;
Stream reqStream = req.GetRequestStream();

byte[] inData = new byte[4096];
int bytesRead = rdr.Read(inData, 0, inData.Length);
while (bytesRead > 0)
{
reqStream.Write(inData, 0, bytesRead);
bytesRead = rdr.Read(inData, 0, inData.Length);
}

UploadInfo info = new UploadInfo();
info.Request = (HttpWebRequest) req;
info.dataLength = 1024;
rdr.Close();
reqStream.Close();

info.ProgressCallback += progressCB;

IAsyncResult r = (IAsyncResult) req.BeginGetResponse(new
AsyncCallback(uResponseCallback), info);
allDone.WaitOne();

byte[] data;
if ( info.useFastBuffers )
{
data = info.dataBufferFast;
info.dataBufferFast = null;
}
else
{
data = new byte[ info.dataBufferSlow.Count ];
for ( int b=0; b<info.dataBufferSlow.Count; b++ )
data[b] = (byte) info.dataBufferSlow[b];
info.dataBufferSlow = null;
}
if (this.Abort == false)
{
return data;
}
else
{
return new byte[0];
}
}
catch(System.Exception err)
{
return null;
}
}

private void uResponseCallback(IAsyncResult ar)
{
try
{
UploadInfo info = (UploadInfo) ar.AsyncState;
req = info.Request;
WebResponse resp = req.EndGetResponse(ar);
string strContentLength = resp.Headers["Content-Length"];
if ( strContentLength != null )
{
info.dataLength = Convert.ToInt32( strContentLength );
info.dataBufferFast = new byte[ info.dataLength ];
}
else
{
info.useFastBuffers = false;
info.dataBufferSlow = new System.Collections.ArrayList(
BUFFER_SIZE );
}
Stream ResponseStream = resp.GetResponseStream();
info.ResponseStream = ResponseStream;
IAsyncResult iarWrite =
ResponseStream.BeginRead(info.BufferWrite,
0,
BUFFER_SIZE,
new AsyncCallback(uReadCallBack),
info);
}
catch(System.Exception err)
{
}
}

private void uReadCallBack(IAsyncResult asyncResult)
{
try
{
UploadInfo info = (UploadInfo) asyncResult.AsyncState;
Stream responseStream = info.ResponseStream;
if (Abort == true)
{
req.Abort();
req = null;
System.Object o = new object();
eventStop(o, System.EventArgs.Empty);
allDone.Set();
}
else
{
int bytesWriten = responseStream.EndRead(asyncResult );
if (bytesWriten > 0)
{
if ( info.useFastBuffers )
{
System.Array.Copy(info.BufferWrite, 0,
info.dataBufferFast, info.bytesProcessed,
bytesWriten );
}
else
{
for ( int b=0; b<bytesWriten; b++ )
info.dataBufferSlow.Add( info.BufferWrite[b] );
}
info.bytesProcessed += bytesWriten;
if ( info.ProgressCallback != null )
info.ProgressCallback( info.bytesProcessed,
info.dataLength);
IAsyncResult ar = responseStream.BeginRead(
info.BufferWrite, 0, BUFFER_SIZE,
new AsyncCallback(uReadCallBack), info);
}
else
{
responseStream.Close();
allDone.Set();
}
}
}
catch(System.Exception err)
{
}
}
#endregion


 
Reply With Quote
 
 
 
 
éric
Guest
Posts: n/a
 
      19th Feb 2004
OR if anyone has a sample for HTTP async file upload that would be greatly
appreciated!

éric


"éric" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi,
> below is the code I sort of adapted from an async http download example I
> found so that I could upload files to the server.
> It seems to be doing it asynchronously and the file makes it to the server
> but it is going all in one shot.
> How can trap it at every 1024 bytes to trigger an event like progress bar
> advance as it does in the download version of this code?
> When the code calls back uReadCallBack for the first time the entire file

is
> already on the server?
>
> Any ideas?
>
> -----------Code Start-------------
>
> internal class UploadInfo
> {
> const int BufferSize = 1024;
> internal byte[] BufferWrite;
> internal bool useFastBuffers;
> internal byte[] dataBufferFast;
> internal System.Collections.ArrayList dataBufferSlow;
> internal int dataLength;
> internal int bytesProcessed;
> internal HttpWebRequest Request;
> internal Stream ResponseStream;
> internal DownloadProgressHandler ProgressCallback;
>
> internal UploadInfo()
> {
> BufferWrite = new byte[BufferSize];
> Request = null;
> bytesProcessed = 0;
> useFastBuffers = true;
> }
> }
>
> internal class WebDownload
> {
> private event System.EventHandler eventStop;
> private event ECASOFT.Controls.DownloadError eventError;
> internal ManualResetEvent allDone = new ManualResetEvent(false);
> internal bool Abort;
> private WebRequest req;
>
> const int BUFFER_SIZE = 1024;
> internal event System.EventHandler Aborted
> {
> add {eventStop += new System.EventHandler (value);}
> remove {eventStop -= new System.EventHandler (value);}
> }
> internal event ECASOFT.Controls.DownloadError DownloadError
> {
> add {eventError += new ECASOFT.Controls.DownloadError (value);}
> remove {eventError -= new ECASOFT.Controls.DownloadError (value);}
> }
> // Start the upload
> internal byte[] Upload(
> string url, string username, string password, string domain,
> DownloadProgressHandler progressCB)
> {
> try
> {
> Abort = false;
>
> allDone.Reset();
>
> Uri httpSite = new Uri(url);
>
> FileStream rdr = new FileStream(\\My File.txt, FileMode.Open);
>
> HttpWebRequest req = (HttpWebRequest) WebRequest.Create(url);
> req.Method = "PUT";
>
> req.PreAuthenticate = true;
> req.Credentials = new NetworkCredential(username, password,
> domain);
> req.AllowWriteStreamBuffering = true;
> req.ContentLength = rdr.Length;
> Stream reqStream = req.GetRequestStream();
>
> byte[] inData = new byte[4096];
> int bytesRead = rdr.Read(inData, 0, inData.Length);
> while (bytesRead > 0)
> {
> reqStream.Write(inData, 0, bytesRead);
> bytesRead = rdr.Read(inData, 0, inData.Length);
> }
>
> UploadInfo info = new UploadInfo();
> info.Request = (HttpWebRequest) req;
> info.dataLength = 1024;
> rdr.Close();
> reqStream.Close();
>
> info.ProgressCallback += progressCB;
>
> IAsyncResult r = (IAsyncResult) req.BeginGetResponse(new
> AsyncCallback(uResponseCallback), info);
> allDone.WaitOne();
>
> byte[] data;
> if ( info.useFastBuffers )
> {
> data = info.dataBufferFast;
> info.dataBufferFast = null;
> }
> else
> {
> data = new byte[ info.dataBufferSlow.Count ];
> for ( int b=0; b<info.dataBufferSlow.Count; b++ )
> data[b] = (byte) info.dataBufferSlow[b];
> info.dataBufferSlow = null;
> }
> if (this.Abort == false)
> {
> return data;
> }
> else
> {
> return new byte[0];
> }
> }
> catch(System.Exception err)
> {
> return null;
> }
> }
>
> private void uResponseCallback(IAsyncResult ar)
> {
> try
> {
> UploadInfo info = (UploadInfo) ar.AsyncState;
> req = info.Request;
> WebResponse resp = req.EndGetResponse(ar);
> string strContentLength = resp.Headers["Content-Length"];
> if ( strContentLength != null )
> {
> info.dataLength = Convert.ToInt32( strContentLength );
> info.dataBufferFast = new byte[ info.dataLength ];
> }
> else
> {
> info.useFastBuffers = false;
> info.dataBufferSlow = new System.Collections.ArrayList(
> BUFFER_SIZE );
> }
> Stream ResponseStream = resp.GetResponseStream();
> info.ResponseStream = ResponseStream;
> IAsyncResult iarWrite =
> ResponseStream.BeginRead(info.BufferWrite,
> 0,
> BUFFER_SIZE,
> new AsyncCallback(uReadCallBack),
> info);
> }
> catch(System.Exception err)
> {
> }
> }
>
> private void uReadCallBack(IAsyncResult asyncResult)
> {
> try
> {
> UploadInfo info = (UploadInfo) asyncResult.AsyncState;
> Stream responseStream = info.ResponseStream;
> if (Abort == true)
> {
> req.Abort();
> req = null;
> System.Object o = new object();
> eventStop(o, System.EventArgs.Empty);
> allDone.Set();
> }
> else
> {
> int bytesWriten = responseStream.EndRead(asyncResult );
> if (bytesWriten > 0)
> {
> if ( info.useFastBuffers )
> {
> System.Array.Copy(info.BufferWrite, 0,
> info.dataBufferFast, info.bytesProcessed,
> bytesWriten );
> }
> else
> {
> for ( int b=0; b<bytesWriten; b++ )
> info.dataBufferSlow.Add( info.BufferWrite[b] );
> }
> info.bytesProcessed += bytesWriten;
> if ( info.ProgressCallback != null )
> info.ProgressCallback( info.bytesProcessed,
> info.dataLength);
> IAsyncResult ar = responseStream.BeginRead(
> info.BufferWrite, 0, BUFFER_SIZE,
> new AsyncCallback(uReadCallBack), info);
> }
> else
> {
> responseStream.Close();
> allDone.Set();
> }
> }
> }
> catch(System.Exception err)
> {
> }
> }
> #endregion
>
>



 
Reply With Quote
 
Alex Feinman [MVP]
Guest
Posts: n/a
 
      19th Feb 2004
I think if you set AllowWriteStreamBuffering to false on the outgoing
request, it will send your data as you write them into the output stream.
This will allow you to update progress yourself.

"éric" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi,
> below is the code I sort of adapted from an async http download example I
> found so that I could upload files to the server.
> It seems to be doing it asynchronously and the file makes it to the server
> but it is going all in one shot.
> How can trap it at every 1024 bytes to trigger an event like progress bar
> advance as it does in the download version of this code?
> When the code calls back uReadCallBack for the first time the entire file

is
> already on the server?
>
> Any ideas?
>
> -----------Code Start-------------
>
> internal class UploadInfo
> {
> const int BufferSize = 1024;
> internal byte[] BufferWrite;
> internal bool useFastBuffers;
> internal byte[] dataBufferFast;
> internal System.Collections.ArrayList dataBufferSlow;
> internal int dataLength;
> internal int bytesProcessed;
> internal HttpWebRequest Request;
> internal Stream ResponseStream;
> internal DownloadProgressHandler ProgressCallback;
>
> internal UploadInfo()
> {
> BufferWrite = new byte[BufferSize];
> Request = null;
> bytesProcessed = 0;
> useFastBuffers = true;
> }
> }
>
> internal class WebDownload
> {
> private event System.EventHandler eventStop;
> private event ECASOFT.Controls.DownloadError eventError;
> internal ManualResetEvent allDone = new ManualResetEvent(false);
> internal bool Abort;
> private WebRequest req;
>
> const int BUFFER_SIZE = 1024;
> internal event System.EventHandler Aborted
> {
> add {eventStop += new System.EventHandler (value);}
> remove {eventStop -= new System.EventHandler (value);}
> }
> internal event ECASOFT.Controls.DownloadError DownloadError
> {
> add {eventError += new ECASOFT.Controls.DownloadError (value);}
> remove {eventError -= new ECASOFT.Controls.DownloadError (value);}
> }
> // Start the upload
> internal byte[] Upload(
> string url, string username, string password, string domain,
> DownloadProgressHandler progressCB)
> {
> try
> {
> Abort = false;
>
> allDone.Reset();
>
> Uri httpSite = new Uri(url);
>
> FileStream rdr = new FileStream(\\My File.txt, FileMode.Open);
>
> HttpWebRequest req = (HttpWebRequest) WebRequest.Create(url);
> req.Method = "PUT";
>
> req.PreAuthenticate = true;
> req.Credentials = new NetworkCredential(username, password,
> domain);
> req.AllowWriteStreamBuffering = true;
> req.ContentLength = rdr.Length;
> Stream reqStream = req.GetRequestStream();
>
> byte[] inData = new byte[4096];
> int bytesRead = rdr.Read(inData, 0, inData.Length);
> while (bytesRead > 0)
> {
> reqStream.Write(inData, 0, bytesRead);
> bytesRead = rdr.Read(inData, 0, inData.Length);
> }
>
> UploadInfo info = new UploadInfo();
> info.Request = (HttpWebRequest) req;
> info.dataLength = 1024;
> rdr.Close();
> reqStream.Close();
>
> info.ProgressCallback += progressCB;
>
> IAsyncResult r = (IAsyncResult) req.BeginGetResponse(new
> AsyncCallback(uResponseCallback), info);
> allDone.WaitOne();
>
> byte[] data;
> if ( info.useFastBuffers )
> {
> data = info.dataBufferFast;
> info.dataBufferFast = null;
> }
> else
> {
> data = new byte[ info.dataBufferSlow.Count ];
> for ( int b=0; b<info.dataBufferSlow.Count; b++ )
> data[b] = (byte) info.dataBufferSlow[b];
> info.dataBufferSlow = null;
> }
> if (this.Abort == false)
> {
> return data;
> }
> else
> {
> return new byte[0];
> }
> }
> catch(System.Exception err)
> {
> return null;
> }
> }
>
> private void uResponseCallback(IAsyncResult ar)
> {
> try
> {
> UploadInfo info = (UploadInfo) ar.AsyncState;
> req = info.Request;
> WebResponse resp = req.EndGetResponse(ar);
> string strContentLength = resp.Headers["Content-Length"];
> if ( strContentLength != null )
> {
> info.dataLength = Convert.ToInt32( strContentLength );
> info.dataBufferFast = new byte[ info.dataLength ];
> }
> else
> {
> info.useFastBuffers = false;
> info.dataBufferSlow = new System.Collections.ArrayList(
> BUFFER_SIZE );
> }
> Stream ResponseStream = resp.GetResponseStream();
> info.ResponseStream = ResponseStream;
> IAsyncResult iarWrite =
> ResponseStream.BeginRead(info.BufferWrite,
> 0,
> BUFFER_SIZE,
> new AsyncCallback(uReadCallBack),
> info);
> }
> catch(System.Exception err)
> {
> }
> }
>
> private void uReadCallBack(IAsyncResult asyncResult)
> {
> try
> {
> UploadInfo info = (UploadInfo) asyncResult.AsyncState;
> Stream responseStream = info.ResponseStream;
> if (Abort == true)
> {
> req.Abort();
> req = null;
> System.Object o = new object();
> eventStop(o, System.EventArgs.Empty);
> allDone.Set();
> }
> else
> {
> int bytesWriten = responseStream.EndRead(asyncResult );
> if (bytesWriten > 0)
> {
> if ( info.useFastBuffers )
> {
> System.Array.Copy(info.BufferWrite, 0,
> info.dataBufferFast, info.bytesProcessed,
> bytesWriten );
> }
> else
> {
> for ( int b=0; b<bytesWriten; b++ )
> info.dataBufferSlow.Add( info.BufferWrite[b] );
> }
> info.bytesProcessed += bytesWriten;
> if ( info.ProgressCallback != null )
> info.ProgressCallback( info.bytesProcessed,
> info.dataLength);
> IAsyncResult ar = responseStream.BeginRead(
> info.BufferWrite, 0, BUFFER_SIZE,
> new AsyncCallback(uReadCallBack), info);
> }
> else
> {
> responseStream.Close();
> allDone.Set();
> }
> }
> }
> catch(System.Exception err)
> {
> }
> }
> #endregion
>
>



 
Reply With Quote
 
=?Utf-8?B?TmFuZGFs?=
Guest
Posts: n/a
 
      20th Feb 2004
SEE REMARKS
http://msdn.microsoft.com/library/de...ticatetopic.as

This is little stupidity in NET CF if preauthenticate is true. Framework does not send HTTP-AUTHORIZATION header in first POST request. Try to make one small GET request only to
make connection and then send data with POST.Otherwise you need to buffer dat
to handle 401 WWW-Authenticate Basic response from server

----- Alex Feinman [MVP] wrote: ----

I think if you set AllowWriteStreamBuffering to false on the outgoin
request, it will send your data as you write them into the output stream
This will allow you to update progress yourself

 
Reply With Quote
 
éric
Guest
Posts: n/a
 
      20th Feb 2004
with AllowWriteStreamBuffering = false I get this error :

{"This request requires buffering of data for authentication or redirection
to be sucessful." }

preauthenticate seems to have no affect if true or false

I know I am missing something else... should I be loading the Request Stream
before starting the connection to the server? or should I be somehow loading
slowly bit by bit?
..
..
..
Stream reqStream = req.GetRequestStream();
// Allocate byte buffer to hold file contents
byte[] inData = new byte[4096];
// loop through the local file reading each data block
// and writing to the request stream buffer
int bytesRead = rdr.Read(inData, 0, inData.Length);
while (bytesRead > 0)
{
reqStream.Write(inData, 0, bytesRead);
bytesRead = rdr.Read(inData, 0, inData.Length);
}
..
..
..
allDone.WaitOne();


éric


 
Reply With Quote
 
éric
Guest
Posts: n/a
 
      20th Feb 2004
Can one of you tell me if this is the right logic?

void Upload()
{
Read entire file
Load Request stream with file byte[]
Request method = PUT
IAsyncResult r = (IAsyncResult) req.BeginGetResponse(new AsyncCallback(a, b)
wait for callback
}


"Nandal" <(E-Mail Removed)> wrote in message
news:EE7FD291-1BF2-4A67-99FE-(E-Mail Removed)...
> SEE REMARKS:
>

http://msdn.microsoft.com/library/de...icatetopic.asp
>
> This is little stupidity in NET CF if preauthenticate is true. Framework

does not send HTTP-AUTHORIZATION header in first POST request. Try to make
one small GET request only to
> make connection and then send data with POST.Otherwise you need to buffer

data
> to handle 401 WWW-Authenticate Basic response from server.
>
> ----- Alex Feinman [MVP] wrote: -----
>
> I think if you set AllowWriteStreamBuffering to false on the outgoing
> request, it will send your data as you write them into the output

stream.
> This will allow you to update progress yourself.
>



 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Async Upload Control PJ on Development Microsoft ASP .NET 1 2nd Nov 2007 07:12 PM
Async Upload Control PJ on Development Microsoft Dot NET 0 2nd Nov 2007 04:13 PM
ftpwebreques async upload, active transfer problem. lushdog Microsoft Dot NET Framework 0 10th Apr 2006 03:46 AM
Large Upload to SQL - Async? Patrick Microsoft ADO .NET 4 4th Apr 2006 04:51 PM
Is HTTP an Async Protocol Bob Badger Microsoft ASP .NET 4 1st Feb 2006 03:25 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 08:17 PM.