WebHeaderCollection headers;
WebHeaderCollection responseHeaders;
string baseAddress;
+ Uri base_address_uri;
bool is_busy;
Encoding encoding = Encoding.UTF8;
bool allow_read_buffering = true;
WebRequest request;
object locker;
CallbackData callback_data;
+ long upload_length;
public WebClient ()
{
// but without adding dependency on System.Windows.dll. GetData is [SecurityCritical]
// this makes the default .ctor [SecuritySafeCritical] which would be a problem (inheritance)
// but it happens that MS SL2 also has this default .ctor as SSC :-)
- baseAddress = (AppDomain.CurrentDomain.GetData ("xap_uri") as string);
+ BaseAddress = (AppDomain.CurrentDomain.GetData ("xap_uri") as string);
locker = new object ();
UseDefaultCredentials = true;
}
set {
if (String.IsNullOrEmpty (value)) {
baseAddress = String.Empty;
+ base_address_uri = null;
} else {
- Uri uri = null;
- if (!Uri.TryCreate (value, UriKind.Absolute, out uri))
+ if (!Uri.TryCreate (value, UriKind.Absolute, out base_address_uri))
throw new ArgumentException ("Invalid URI");
- baseAddress = Uri.UnescapeDataString (uri.AbsoluteUri);
+ baseAddress = Uri.UnescapeDataString (base_address_uri.AbsoluteUri);
}
}
}
{
callback_data = callbackData;
WebRequest request = GetWebRequest (uri);
- request.Method = DetermineMethod (uri, method);
+ // do not send a relative URI to Determine method
+ request.Method = DetermineMethod (request.RequestUri, method);
// copy headers to the request - some needs special treatments
foreach (string header in Headers) {
switch (header.ToLowerInvariant ()) {
{
if (request != null)
request.Abort ();
+ upload_length = 0;
}
void CompleteAsync ()
{
is_busy = false;
+ upload_length = 0;
}
internal class CallbackData {
}
}
- internal void WriteStreamClosedCallback (object WebClientData)
+ internal void WriteStreamClosedCallback (object WebClientData, long length)
{
try {
request.BeginGetResponse (OpenWriteAsyncResponseCallback, WebClientData);
OnWriteStreamClosed (new WriteStreamClosedEventArgs (e));
}, null);
}
+ finally {
+ // kind of dummy, 0% progress, that is always emitted
+ upload_length = length;
+ OnUploadProgressChanged (
+ new UploadProgressChangedEventArgs (0, -1, length, -1, 0, callback_data.user_token));
+ }
}
private void OpenWriteAsyncResponseCallback (IAsyncResult result)
{
+ Exception ex = null;
try {
WebResponse response = request.EndGetResponse (result);
ProcessResponse (response);
}
+ catch (SecurityException se) {
+ // SecurityException inside a SecurityException (not a WebException) for SL compatibility
+ ex = new SecurityException (String.Empty, se);
+ }
catch (Exception e) {
+ ex = new WebException ("Could not complete operation.", e, WebExceptionStatus.UnknownError, null);
+ }
+ finally {
callback_data.sync_context.Post (delegate (object sender) {
- OnWriteStreamClosed (new WriteStreamClosedEventArgs (e));
+ OnWriteStreamClosed (new WriteStreamClosedEventArgs (ex));
}, null);
}
}
request.Abort ();
throw;
}
+ finally {
+ // kind of dummy, 0% progress, that is always emitted
+ upload_length = callback_data.data.Length;
+ OnUploadProgressChanged (
+ new UploadProgressChangedEventArgs (0, -1, upload_length, -1, 0, callback_data.user_token));
+ }
}
private void UploadStringResponseAsyncCallback (IAsyncResult result)
throw new ArgumentNullException ("address");
// if the URI is relative then we use our base address URI to make an absolute one
- Uri uri = address.IsAbsoluteUri ? address : new Uri (new Uri (baseAddress), address);
+ Uri uri = address.IsAbsoluteUri || base_address_uri == null ? address : new Uri (base_address_uri, address);
HttpWebRequest request = (HttpWebRequest) WebRequest.Create (uri);
request.AllowReadStreamBuffering = AllowReadStreamBuffering;
request.progress = delegate (long read, long length) {
callback_data.sync_context.Post (delegate (object sender) {
- OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (read, length, callback_data.user_token));
+ if (upload_length > 0) {
+ // always emitted as 50% with an unknown (-1) TotalBytesToSend
+ OnUploadProgressChanged (new UploadProgressChangedEventArgs (read, length,
+ upload_length, -1, 50, callback_data.user_token));
+ } else {
+ OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (read, length,
+ callback_data.user_token));
+ }
}, null);
-
};
return request;
}