// Copyright (c) ServiceStack, Inc. All Rights Reserved.
// License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt
using System;
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using ServiceStack.Logging;
using ServiceStack.Text;
using ServiceStack.Web;
#if NETFX_CORE
using Windows.System.Threading;
#endif
namespace ServiceStack
{
/**
* Need to provide async request options
* http://msdn.microsoft.com/en-us/library/86wf6409(VS.71).aspx
*/
public partial class AsyncServiceClient : IHasSessionId, IHasVersion
{
private static readonly ILog Log = LogManager.GetLogger(typeof(AsyncServiceClient));
private static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(60);
//private HttpWebRequest webRequest = null;
private AuthenticationInfo authInfo = null;
///
/// The request filter is called before any request.
/// This request filter is executed globally.
///
public static Action GlobalRequestFilter { get; set; }
///
/// The response action is called once the server response is available.
/// It will allow you to access raw response information.
/// This response action is executed globally.
/// Note that you should NOT consume the response stream as this is handled by ServiceStack
///
public static Action GlobalResponseFilter { get; set; }
///
/// Called before request resend, when the initial request required authentication
///
public Action OnAuthenticationRequired { get; set; }
public static int BufferSize = 8192;
public ICredentials Credentials { get; set; }
public bool AlwaysSendBasicAuthHeader { get; set; }
public bool StoreCookies { get; set; }
public INameValueCollection Headers { get; set; }
public CookieContainer CookieContainer { get; set; }
///
/// The request filter is called before any request.
/// This request filter only works with the instance where it was set (not global).
///
public Action RequestFilter { get; set; }
///
/// The response action is called once the server response is available.
/// It will allow you to access raw response information.
/// Note that you should NOT consume the response stream as this is handled by ServiceStack
///
public Action ResponseFilter { get; set; }
///
/// The ResultsFilter is called before the Request is sent allowing you to return a cached response.
///
public ResultsFilterDelegate ResultsFilter { get; set; }
///
/// The ResultsFilterResponse is called before returning the response allowing responses to be cached.
///
public ResultsFilterResponseDelegate ResultsFilterResponse { get; set; }
///
/// Called with requestUri, ResponseType when server returns 304 NotModified
///
public ExceptionFilterDelegate ExceptionFilter { get; set; }
public string BaseUri { get; set; }
public bool DisableAutoCompression { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public void SetCredentials(string userName, string password)
{
this.UserName = userName;
this.Password = password;
}
public string BearerToken { get; set; }
public TimeSpan? Timeout { get; set; }
public string ContentType { get; set; }
public StreamSerializerDelegate StreamSerializer { get; set; }
public StreamDeserializerDelegate StreamDeserializer { get; set; }
public string UserAgent { get; set; }
public bool CaptureSynchronizationContext { get; set; }
public bool HandleCallbackOnUiThread { get; set; }
public bool EmulateHttpViaPost { get; set; }
public ProgressDelegate OnDownloadProgress { get; set; }
public ProgressDelegate OnUploadProgress { get; set; }
public bool ShareCookiesWithBrowser { get; set; }
public int Version { get; set; }
public string SessionId { get; set; }
internal Action CancelAsyncFn;
public static bool DisableTimer { get; set; }
public void CancelAsync()
{
if (CancelAsyncFn != null)
{
// Request will be nulled after it throws an exception on its async methods
// See - http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.abort
CancelAsyncFn();
CancelAsyncFn = null;
}
}
public Task SendAsync(string httpMethod, string absoluteUrl, object request, CancellationToken token=default(CancellationToken))
{
var tcs = new TaskCompletionSource();
if (ResultsFilter != null)
{
var response = ResultsFilter(typeof(TResponse), httpMethod, absoluteUrl, request);
if (response is TResponse)
{
tcs.SetResult((TResponse)response);
return tcs.Task;
}
}
if (ResultsFilterResponse != null)
{
WebResponse webRes = null;
SendWebRequest(httpMethod, absoluteUrl, request, token,
r => {
ResultsFilterResponse(webRes, r, httpMethod, absoluteUrl, request);
tcs.SetResult(r);
},
(response, exc) => tcs.SetException(exc),
wr => webRes = wr
);
}
else
{
SendWebRequest(httpMethod, absoluteUrl, request, token,
tcs.SetResult,
(response, exc) => tcs.SetException(exc)
);
}
return tcs.Task;
}
private void SendWebRequest(string httpMethod, string absoluteUrl, object request, CancellationToken token,
Action onSuccess, Action