internal IAsyncResult BeginRequest(
string url,
HttpVerb httpVerb,
Dictionary<string, string> args,
AsyncCallback cb, object state)
{
if (args != null && args.Keys.Count > 0 && httpVerb == HttpVerb.Get)
url = url+ (url.Contains("?") ? "&" : "?") + EncodeDictionary(args);
var request = (HttpWebRequest)WebRequest.Create(url);
request.Proxy = Proxy;
request.Headers.Add(HttpRequestHeader.AcceptLanguage, Culture.IetfLanguageTag.ToLowerInvariant());
request.Method = httpVerb.ToString();
var tar = new TypedAsyncResult<ResponseData>(cb, state);
Action beginGetResp = () => request.BeginGetResponse(tar.AsSafe(gr =>
{
HttpWebResponse resp;
Stream respStm;
string contentType;
try
{
resp = (HttpWebResponse)request.EndGetResponse(gr);
contentType = ExtractContentType(resp);
respStm = resp.GetResponseStream();
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
resp = (HttpWebResponse)ex.Response;
contentType = ExtractContentType(resp);
if (contentType == "text/javascript")
{
respStm = resp.GetResponseStream();
goto ok;
}
}
throw TransportError(ex);
}
ok: var buf = new byte[4096];
var ms = new MemoryStream(buf.Length);
AsyncCallback cbr = null;
cbr = tar.AsSafe(br =>
{
int cnt = respStm.EndRead(br);
if (cnt == 0)
{
if (!tar.IsCompleted)
{
((IDisposable)resp).Dispose();
ms.Seek(0, SeekOrigin.Begin);
tar.Complete(new ResponseData
{
Json = Encoding.UTF8.GetString(ms.ToArray()),
ContentType = contentType,
}, false);
}
}
else
{
ms.Write(buf, 0, cnt);
respStm.BeginRead(buf, 0, buf.Length, cbr, null);
}
}, ex => ((IDisposable)resp).Dispose());
respStm.BeginRead(buf, 0, buf.Length, cbr, null);
}), null);
try
{
if (httpVerb == HttpVerb.Post)
{
string postData = EncodeDictionary(args);
byte[] postDataBytes = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postDataBytes.Length;
request.BeginGetRequestStream(tar.AsSafe(rar =>
{
Stream rqStm = request.EndGetRequestStream(rar);
rqStm.BeginWrite(postDataBytes, 0, postDataBytes.Length, tar.AsSafe(wr =>
{
rqStm.EndWrite(wr);
beginGetResp();
}), null);
}), null);
}
else
{
beginGetResp();
}
}
catch (Exception ex)
{
if (!tar.IsCompleted)
tar.Complete(true, ex);
}
return tar;
}