internal RequestState(TimedRequest request, string requestBody, AsyncCallback successCallback, Action timeoutCallback) { this.TimedRequest = request; this.RequestBody = requestBody; this.SuccessCallback = successCallback; this.TimeoutCallback = timeoutCallback; }
/// <summary> /// Writes request data to the request stream /// </summary> /// <param name="ar">The async response</param> private void RequestStreamCallback(IAsyncResult ar) { var requestState = (RequestState)ar.AsyncState; try { Stream streamResponse = requestState.TimedRequest.WebRequest.EndGetRequestStream(ar); byte[] byteArray = Encoding.UTF8.GetBytes(requestState.RequestBody); streamResponse.Write(byteArray, 0, byteArray.Length); streamResponse.Dispose(); TimedRequest request = requestState.TimedRequest; request.BeginGetResponse(requestState.SuccessCallback, requestState.TimeoutCallback, request); } catch (WebException ex) { DebugLogger.Instance.WriteLog("WebException in RequestStreamCallback: {0}", ex); requestState.TimeoutCallback(); } }
/// <summary> /// Makes the API request /// </summary> /// <typeparam name="T">The type of response item</typeparam> /// <param name="command">The command to call.</param> /// <param name="settings">The music client settings.</param> /// <param name="queryParams">The querystring.</param> /// <param name="callback">The callback to hit when done.</param> /// <param name="requestHeaders">HTTP headers to add to the request</param> /// <exception cref="System.ArgumentNullException">Thrown when no callback is specified</exception> public void SendRequestAsync <T>( MusicClientCommand command, IMusicClientSettings settings, List <KeyValuePair <string, string> > queryParams, IResponseCallback <T> callback, Dictionary <string, string> requestHeaders = null) { if (callback == null) { throw new ArgumentNullException("callback"); } Uri uri = this.UriBuilder.BuildUri(command, settings, queryParams); DebugLogger.Instance.WriteLog("Calling {0}", uri.ToString()); TimedRequest request = new TimedRequest(uri); this.AddRequestHeaders(request.WebRequest, requestHeaders); this.TryBuildRequestBody( (IAsyncResult ar) => { if (request.HasTimedOut) { return; } WebResponse response = null; HttpWebResponse webResponse = null; T responseItem = default(T); HttpStatusCode?statusCode = null; Exception error = null; string responseBody = null; try { response = request.WebRequest.EndGetResponse(ar); webResponse = response as HttpWebResponse; if (webResponse != null) { statusCode = webResponse.StatusCode; command.SetAdditionalResponseInfo(new ResponseInfo(webResponse.ResponseUri, webResponse.Headers)); // Capture Server Time offset if we haven't already... this.DeriveServerTimeOffset(webResponse.Headers); } } catch (WebException ex) { DebugLogger.Instance.WriteVerboseInfo("Web Exception: {0} when calling {1}", ex, uri); error = ex; if (ex.Response != null) { response = ex.Response; webResponse = (HttpWebResponse)ex.Response; statusCode = webResponse.StatusCode; } } string contentType = null; if (response != null) { contentType = response.ContentType; try { using (Stream responseStream = this._gzipHandler.GetResponseStream(response)) { responseBody = responseStream.AsString(); responseItem = callback.ConvertFromRawResponse(responseBody); } } catch (Exception ex) { DebugLogger.Instance.WriteVerboseInfo("Exception: {0} trying to handle response stream when calling {1}", ex, uri); error = ex; responseItem = default(T); } } DoCallback(callback.Callback, responseItem, statusCode, contentType, error, responseBody, command.RequestId, uri, IsFake404(response)); }, () => DoCallback(callback.Callback, default(T), null, null, new ApiCallFailedException(), null, command.RequestId, uri), request, command); }
private void TryBuildRequestBody(AsyncCallback requestSuccessCallback, Action requestTimeoutCallback, TimedRequest request, MusicClientCommand apiMethod) { var requestBody = apiMethod.BuildRequestBody(); request.WebRequest.Method = apiMethod.HttpMethod.ToString().ToUpperInvariant(); if (requestBody != null) { var requestState = new RequestState(request, requestBody, requestSuccessCallback, requestTimeoutCallback); request.WebRequest.ContentType = apiMethod.ContentType; request.WebRequest.BeginGetRequestStream(this.RequestStreamCallback, requestState); } else { // No request body, just make the request immediately request.BeginGetResponse(requestSuccessCallback, requestTimeoutCallback, request); } }