private static async Task <RTIHttpContent> CreateRequestContentAsync(HttpRequestMessage request, HttpRequestHeaderCollection rtHeaderCollection) { HttpContent content = request.Content; RTIHttpContent rtContent; ArraySegment <byte> buffer; // If we are buffered already, it is more efficient to send the data directly using the buffer with the // WinRT HttpBufferContent class than using HttpStreamContent. This also avoids issues caused by // a design limitation in the System.Runtime.WindowsRuntime System.IO.NetFxToWinRtStreamAdapter. if (content.TryGetBuffer(out buffer)) { rtContent = new RTHttpBufferContent(buffer.Array.AsBuffer(), (uint)buffer.Offset, (uint)buffer.Count); } else { Stream contentStream = await content.ReadAsStreamAsync().ConfigureAwait(false); if (contentStream is RTIInputStream) { rtContent = new RTHttpStreamContent((RTIInputStream)contentStream); } else if (contentStream is MemoryStream) { var memStream = contentStream as MemoryStream; if (memStream.TryGetBuffer(out buffer)) { rtContent = new RTHttpBufferContent(buffer.Array.AsBuffer(), (uint)buffer.Offset, (uint)buffer.Count); } else { byte[] byteArray = memStream.ToArray(); rtContent = new RTHttpBufferContent(byteArray.AsBuffer(), 0, (uint)byteArray.Length); } } else { rtContent = new RTHttpStreamContent(contentStream.AsInputStream()); } } // RTHttpBufferContent constructor automatically adds a Content-Length header. RTHttpStreamContent does not. // Clear any 'Content-Length' header added by the RTHttp*Content objects. We need to clear that now // and decide later whether we need 'Content-Length' or 'Transfer-Encoding: chunked' headers based on the // .NET HttpRequestMessage and Content header collections. rtContent.Headers.ContentLength = null; // Deal with conflict between 'Content-Length' vs. 'Transfer-Encoding: chunked' semantics. // Desktop System.Net allows both headers to be specified but ends up stripping out // 'Content-Length' and using chunked semantics. The WinRT APIs throw an exception so // we need to manually strip out the conflicting header to maintain app compatibility. if (request.Headers.TransferEncodingChunked.HasValue && request.Headers.TransferEncodingChunked.Value) { content.Headers.ContentLength = null; } else { // Trigger delayed header generation via TryComputeLength. This code is needed due to an outstanding // bug in HttpContentHeaders.ContentLength. See GitHub Issue #5523. content.Headers.ContentLength = content.Headers.ContentLength; } foreach (KeyValuePair <string, IEnumerable <string> > headerPair in content.Headers) { foreach (string value in headerPair.Value) { if (!rtContent.Headers.TryAppendWithoutValidation(headerPair.Key, value)) { // rtContent headers are restricted to a white-list of allowed headers, while System.Net.HttpClient's content headers // will allow custom headers. If something is not successfully added to the content headers, try adding them to the standard headers. bool success = rtHeaderCollection.TryAppendWithoutValidation(headerPair.Key, value); Debug.Assert(success); } } } return(rtContent); }
/// <summary> /// Invoked to acquire the PlayReady License /// </summary> async System.Threading.Tasks.Task<bool> LicenseAcquisitionRequest(Microsoft.Media.PlayReadyClient.PlayReadyLicenseAcquisitionServiceRequest licenseRequest, Windows.Media.Protection.MediaProtectionServiceCompletion CompletionNotifier, string Url, string ChallengeCustomData) { bool bResult = false; string ExceptionMessage = string.Empty; try { if (!string.IsNullOrEmpty(Url)) { LogMessage("ProtectionManager PlayReady Manual License Acquisition Service Request in progress - URL: " + Url); if (!string.IsNullOrEmpty(ChallengeCustomData)) { // disable Base64String encoding //System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); //byte[] b = encoding.GetBytes(ChallengeCustomData); //licenseRequest.ChallengeCustomData = Convert.ToBase64String(b, 0, b.Length); licenseRequest.ChallengeCustomData = ChallengeCustomData; } Microsoft.Media.PlayReadyClient.PlayReadySoapMessage soapMessage = licenseRequest.GenerateManualEnablingChallenge(); byte[] messageBytes = soapMessage.GetMessageBody(); Windows.Web.Http.IHttpContent httpContent = new Windows.Web.Http.HttpBufferContent(messageBytes.AsBuffer()); IPropertySet propertySetHeaders = soapMessage.MessageHeaders; foreach (string strHeaderName in propertySetHeaders.Keys) { string strHeaderValue = propertySetHeaders[strHeaderName].ToString(); // The Add method throws an ArgumentException try to set protected headers like "Content-Type" // so set it via "ContentType" property if (strHeaderName.Equals("Content-Type", StringComparison.OrdinalIgnoreCase)) httpContent.Headers.ContentType = Windows.Web.Http.Headers.HttpMediaTypeHeaderValue.Parse(strHeaderValue); else httpContent.Headers.TryAppendWithoutValidation(strHeaderName.ToString(), strHeaderValue); } CommonLicenseRequest licenseAcquision = new CommonLicenseRequest(); Windows.Web.Http.IHttpContent responseHttpContent = await licenseAcquision.AcquireLicense(new Uri(Url), httpContent); if (responseHttpContent != null) { //string res = await responseHttpContent.ReadAsStringAsync(); var buffer = await responseHttpContent.ReadAsBufferAsync(); Exception exResult = licenseRequest.ProcessManualEnablingResponse(buffer.ToArray()); if (exResult != null) { throw exResult; } bResult = true; } else ExceptionMessage = licenseAcquision.GetLastErrorMessage(); } else { LogMessage("ProtectionManager PlayReady License Acquisition Service Request in progress - URL: " + licenseRequest.Uri.ToString()); await licenseRequest.BeginServiceRequest(); bResult = true; } } catch (Exception e) { ExceptionMessage = e.Message; } if (bResult == true) LogMessage(!string.IsNullOrEmpty(Url) ? "ProtectionManager Manual PlayReady License Acquisition Service Request successful" : "ProtectionManager PlayReady License Acquisition Service Request successful"); else LogMessage(!string.IsNullOrEmpty(Url) ? "ProtectionManager Manual PlayReady License Acquisition Service Request failed: " + ExceptionMessage : "ProtectionManager PlayReady License Acquisition Service Request failed: " + ExceptionMessage); if (CompletionNotifier != null) CompletionNotifier.Complete(bResult); return bResult; }
public virtual async System.Threading.Tasks.Task <IServiceResponse> PostAsyncWindowsWeb(Uri uri, byte[] audioBytes, apiArgs) { IServiceResponse response = new IServiceResponse(service); try { // Using HttpClient to grab chunked encoding (partial) responses. using (Windows.Web.Http.HttpClient httpClient = new Windows.Web.Http.HttpClient()) { Log.WriteLine("before requestContent"); Log.WriteLine("after requestContent"); // rate must be specified but doesn't seem to need to be accurate. Windows.Web.Http.IHttpContent requestContent = null; if (Options.options.APIs.preferChunkedEncodedRequests) { // using chunked transfer requests Log.WriteLine("Using chunked encoding"); Windows.Storage.Streams.InMemoryRandomAccessStream contentStream = new Windows.Storage.Streams.InMemoryRandomAccessStream(); // TODO: obsolete to use DataWriter? use await Windows.Storage.FileIO.Write..(file); Windows.Storage.Streams.DataWriter dw = new Windows.Storage.Streams.DataWriter(contentStream); dw.WriteBytes(audioBytes); await dw.StoreAsync(); // GetInputStreamAt(0) forces chunked transfer (sort of undocumented behavior). requestContent = new Windows.Web.Http.HttpStreamContent(contentStream.GetInputStreamAt(0)); } else { requestContent = new Windows.Web.Http.HttpBufferContent(audioBytes.AsBuffer()); } requestContent.Headers.Add("Content-Type", "audio/l16; rate=" + sampleRate.ToString()); // must add header AFTER contents are initialized Log.WriteLine("Before Post: Elapsed milliseconds:" + stopWatch.ElapsedMilliseconds); response.RequestElapsedMilliseconds = stopWatch.ElapsedMilliseconds; using (Windows.Web.Http.HttpResponseMessage hrm = await httpClient.PostAsync(uri, requestContent)) { response.RequestElapsedMilliseconds = stopWatch.ElapsedMilliseconds - response.RequestElapsedMilliseconds; response.StatusCode = (int)hrm.StatusCode; Log.WriteLine("After Post: StatusCode:" + response.StatusCode + " Total milliseconds:" + stopWatch.ElapsedMilliseconds + " Request milliseconds:" + response.RequestElapsedMilliseconds); if (hrm.StatusCode == Windows.Web.Http.HttpStatusCode.Ok) { string responseContents = await hrm.Content.ReadAsStringAsync(); string[] responseJsons = responseContents.Split("\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); foreach (string rj in responseJsons) { response.ResponseJson = rj; Newtonsoft.Json.Linq.JToken ResponseBodyToken = Newtonsoft.Json.Linq.JObject.Parse(response.ResponseJson); response.ResponseJsonFormatted = Newtonsoft.Json.JsonConvert.SerializeObject(ResponseBodyToken, new Newtonsoft.Json.JsonSerializerSettings() { Formatting = Newtonsoft.Json.Formatting.Indented }); if (Options.options.debugLevel >= 4) { Log.WriteLine(response.ResponseJsonFormatted); } Newtonsoft.Json.Linq.JToken tokResult = ProcessResponse(ResponseBodyToken); if (tokResult == null || string.IsNullOrEmpty(tokResult.ToString())) { response.ResponseResult = Options.options.Services.APIs.SpeechToText.missingResponse; if (Options.options.debugLevel >= 3) { Log.WriteLine("ResponseResult:" + response.ResponseResult); } } else { response.ResponseResult = tokResult.ToString(); if (Options.options.debugLevel >= 3) { Log.WriteLine("ResponseResult:" + tokResult.Path + ": " + response.ResponseResult); } } } } else { response.ResponseResult = hrm.ReasonPhrase; Log.WriteLine("PostAsync Failed: StatusCode:" + hrm.ReasonPhrase + "(" + response.StatusCode.ToString() + ")"); } } } } catch (Exception ex) { Log.WriteLine("Exception:" + ex.Message); if (ex.InnerException != null) { Log.WriteLine("InnerException:" + ex.InnerException); } } return(response); }
private static async Task<RTIHttpContent> CreateRequestContentAsync(HttpRequestMessage request, RTHttpRequestHeaderCollection rtHeaderCollection) { HttpContent content = request.Content; RTIHttpContent rtContent; ArraySegment<byte> buffer; // If we are buffered already, it is more efficient to send the data directly using the buffer with the // WinRT HttpBufferContent class than using HttpStreamContent. This also avoids issues caused by // a design limitation in the System.Runtime.WindowsRuntime System.IO.NetFxToWinRtStreamAdapter. Stream contentStream = await content.ReadAsStreamAsync().ConfigureAwait(false); if (contentStream is RTIInputStream) { rtContent = new RTHttpStreamContent((RTIInputStream)contentStream); } else if (contentStream is MemoryStream) { var memStream = contentStream as MemoryStream; if (memStream.TryGetBuffer(out buffer)) { rtContent = new RTHttpBufferContent(buffer.Array.AsBuffer(), (uint)buffer.Offset, (uint)buffer.Count); } else { byte[] byteArray = memStream.ToArray(); rtContent = new RTHttpBufferContent(byteArray.AsBuffer(), 0, (uint)byteArray.Length); } } else { rtContent = new RTHttpStreamContent(contentStream.AsInputStream()); } // RTHttpBufferContent constructor automatically adds a Content-Length header. RTHttpStreamContent does not. // Clear any 'Content-Length' header added by the RTHttp*Content objects. We need to clear that now // and decide later whether we need 'Content-Length' or 'Transfer-Encoding: chunked' headers based on the // .NET HttpRequestMessage and Content header collections. rtContent.Headers.ContentLength = null; // Deal with conflict between 'Content-Length' vs. 'Transfer-Encoding: chunked' semantics. // Desktop System.Net allows both headers to be specified but ends up stripping out // 'Content-Length' and using chunked semantics. The WinRT APIs throw an exception so // we need to manually strip out the conflicting header to maintain app compatibility. if (request.Headers.TransferEncodingChunked.HasValue && request.Headers.TransferEncodingChunked.Value) { content.Headers.ContentLength = null; } else { // Trigger delayed header generation via TryComputeLength. This code is needed due to an outstanding content.Headers.ContentLength = content.Headers.ContentLength; } foreach (KeyValuePair<string, IEnumerable<string>> headerPair in content.Headers) { foreach (string value in headerPair.Value) { if (!rtContent.Headers.TryAppendWithoutValidation(headerPair.Key, value)) { // rtContent headers are restricted to a white-list of allowed headers, while System.Net.HttpClient's content headers // will allow custom headers. If something is not successfully added to the content headers, try adding them to the standard headers. bool success = rtHeaderCollection.TryAppendWithoutValidation(headerPair.Key, value); Debug.Assert(success); } } } return rtContent; }
/// <summary> /// GetCachePlayReadyLicense /// Return true if get the PlayReady license successfully /// </summary> /// <param name="PlayReadyLicenseUri">PlayReady server Uri</param> /// <param name="PlayReadyChallengeCustomData">PlayReady custom Data</param> /// <param name="DefaultContentKeyId">Content KeyId</param> /// <param name="DefaultContentKeyIdString">Content KeyId string </param> /// <param name="DefaultDomainServiceId">Domain Service Id </param> /// <returns>true if license acquired</returns> protected async Task<bool> GetCachePlayReadyLicense(Uri PlayReadyLicenseUri, string PlayReadyChallengeCustomData, Guid DefaultContentKeyId, string DefaultContentKeyIdString, Guid DefaultDomainServiceId ) { bool bResult = false; Windows.Media.Protection.PlayReady.PlayReadyLicenseAcquisitionServiceRequest licenseRequest = new Windows.Media.Protection.PlayReady.PlayReadyLicenseAcquisitionServiceRequest(); if (licenseRequest != null) { if (!string.IsNullOrEmpty(PlayReadyChallengeCustomData)) { // disable Base64String encoding //System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); //byte[] b = encoding.GetBytes(PlayReadyChallengeCustomData); //licenseRequest.ChallengeCustomData = Convert.ToBase64String(b, 0, b.Length); licenseRequest.ChallengeCustomData = PlayReadyChallengeCustomData; } licenseRequest.ContentHeader = new Windows.Media.Protection.PlayReady.PlayReadyContentHeader( DefaultContentKeyId, DefaultContentKeyIdString, Windows.Media.Protection.PlayReady.PlayReadyEncryptionAlgorithm.Aes128Ctr, PlayReadyLicenseUri, null, String.Empty, DefaultDomainServiceId); Windows.Media.Protection.PlayReady.PlayReadySoapMessage soapMessage = licenseRequest.GenerateManualEnablingChallenge(); byte[] messageBytes = soapMessage.GetMessageBody(); Windows.Web.Http.IHttpContent httpContent = new Windows.Web.Http.HttpBufferContent(messageBytes.AsBuffer()); IPropertySet propertySetHeaders = soapMessage.MessageHeaders; foreach (string strHeaderName in propertySetHeaders.Keys) { string strHeaderValue = propertySetHeaders[strHeaderName].ToString(); // The Add method throws an ArgumentException try to set protected headers like "Content-Type" // so set it via "ContentType" property if (strHeaderName.Equals("Content-Type", StringComparison.OrdinalIgnoreCase)) httpContent.Headers.ContentType = Windows.Web.Http.Headers.HttpMediaTypeHeaderValue.Parse(strHeaderValue); else httpContent.Headers.TryAppendWithoutValidation(strHeaderName.ToString(), strHeaderValue); } CommonLicenseRequest licenseAcquision = new CommonLicenseRequest(); Windows.Web.Http.IHttpContent responseHttpContent = await licenseAcquision.AcquireLicense(PlayReadyLicenseUri, httpContent); if (responseHttpContent != null) { var buffer = await responseHttpContent.ReadAsBufferAsync(); Exception exResult = licenseRequest.ProcessManualEnablingResponse(buffer.ToArray()); if (exResult == null) { bResult = true; } else throw exResult; } } return bResult; }