public static async System.Threading.Tasks.Task PostSystemNetAsyncStreamReader(System.IO.Stream rr, ServiceResponse response) { try { using (System.IO.StreamReader r = new System.IO.StreamReader(rr)) // if needed, there is a constructor which will leave the stream open { // Google Cloud partial results are incomplete json strings while Google Web's are complete json of initial results response.ResponseString = await r.ReadToEndAsync(); if (Options.options.debugLevel >= 4) { Log.WriteLine("ResponseString:" + response.ResponseString); } if (string.IsNullOrWhiteSpace(response.ResponseString)) { throw new MissingFieldException(); } if (response.ResponseString[0] == '{') { response.ResponseJToken = Newtonsoft.Json.Linq.JObject.Parse(response.ResponseString); } else if (response.ResponseString[0] == '[') { response.ResponseJToken = Newtonsoft.Json.Linq.JArray.Parse(response.ResponseString); } else { throw new MissingFieldException(); } response.ResponseJsonFormatted = Newtonsoft.Json.JsonConvert.SerializeObject(response.ResponseJToken, new Newtonsoft.Json.JsonSerializerSettings() { Formatting = Newtonsoft.Json.Formatting.Indented }); if (Options.options.debugLevel >= 4) { Log.WriteLine("ResponseJsonFormatted:" + response.ResponseJsonFormatted); } } } catch (Exception ex) { Log.WriteLine("Exception:" + ex.Message); if (ex.InnerException != null) { Log.WriteLine("InnerException:" + ex.InnerException); } } }
private static async System.Threading.Tasks.Task SystemNetAsync(ServiceResponse response, string method, Uri uri, List <Tuple <string, string> > headers, System.Net.Http.HttpContent requestContent, bool binaryResponse, int maxResponseLength) { long t = 0; response.stopWatch.Start(); try { System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(uri); request.Method = method; if (requestContent != null) { if (requestContent.GetType() == typeof(System.Net.Http.MultipartFormDataContent)) { request.ContentType = requestContent.Headers.ContentType.ToString(); } using (System.IO.Stream requestStream = await request.GetRequestStreamAsync()) { #if false System.IO.Stream s = await requestContent.ReadAsStreamAsync(); long?l = requestContent.Headers.ContentLength; if (l > int.MaxValue) { throw new ArgumentOutOfRangeException(); } int i = (int)l; byte[] buffer = new byte[i]; int len = await s.ReadAsync(buffer, 0, i); //System.IO.StreamReader sr = new System.IO.StreamReader(requestContent.ReadAsStreamAsync()); //await requestContent.CopyToAsync(sr); #endif await requestContent.CopyToAsync(requestStream); } } if (headers != null) { foreach (Tuple <string, string> h in headers) { switch (h.Item1) { case "Accept": // must use explicity Accept property otherwise an error is thrown request.Accept = h.Item2; break; case "Content-Type": // must use explicity ContentType property otherwise an error is thrown request.ContentType = h.Item2; break; case "User-Agent": // must use explicity ContentType property otherwise an error is thrown request.UserAgent = h.Item2; break; default: request.Headers[h.Item1] = h.Item2; break; } } } t = response.stopWatch.ElapsedMilliseconds; using (System.Net.WebResponse wr = await request.GetResponseAsync()) { response.RequestElapsedMilliseconds = response.stopWatch.ElapsedMilliseconds - t; Log.WriteLine("Request Elapsed milliseconds:" + response.RequestElapsedMilliseconds); using (System.Net.HttpWebResponse hwr = (System.Net.HttpWebResponse)wr) { response.StatusCode = (int)hwr.StatusCode; Log.WriteLine("Request StatusCode:" + response.StatusCode); if (hwr.StatusCode == System.Net.HttpStatusCode.OK) { response.ResponseJson = null; using (System.IO.Stream rr = wr.GetResponseStream()) { if (binaryResponse) { await PostSystemNetAsyncBinaryReader(rr, maxResponseLength, response); } else { await PostSystemNetAsyncStreamReader(rr, response); } } } else { response.ResponseResult = hwr.StatusDescription; Log.WriteLine("PostAsync Failed: StatusCode:" + hwr.StatusDescription + "(" + response.StatusCode.ToString() + ")"); } } } } catch (Exception ex) { Log.WriteLine("Exception:" + ex.Message); if (ex.InnerException != null) { Log.WriteLine("InnerException:" + ex.InnerException); } } response.FileName = "curl-" + httpCallCount; response.stopWatch.Stop(); response.TotalElapsedMilliseconds = response.stopWatch.ElapsedMilliseconds; Log.WriteLine("Total Elapsed milliseconds:" + response.TotalElapsedMilliseconds); }
public static async System.Threading.Tasks.Task PostSystemNetAsyncBinaryReader(System.IO.Stream rr, int maxResponseLength, ServiceResponse response) { try { using (System.IO.BinaryReader r = new System.IO.BinaryReader(rr)) // if needed, there is a constructor which will leave the stream open { response.ResponseBytes = r.ReadBytes(maxResponseLength); } } catch (Exception ex) { Log.WriteLine("Exception:" + ex.Message); if (ex.InnerException != null) { Log.WriteLine("InnerException:" + ex.InnerException); } } }
private static async System.Threading.Tasks.Task PostAsync(ServiceResponse response, Uri uri, List <Tuple <string, string> > UriSubstitutes, List <Tuple <string, string> > headers, List <Tuple <string, string> > postDataSubstitutes, byte[] bytes, System.Collections.Generic.Dictionary <string, string> apiArgs, int maxResponseLength = 10000000) { Settings.Request request = response.Request; bool binaryResponse = request.response.type == "binary"; string fileName = null; if (apiArgs.ContainsKey("fileName")) { fileName = apiArgs["fileName"]; } if (uri == null) { uri = MakeUri(request, apiArgs, UriSubstitutes); } if (headers == null) { headers = MakeHeaders(request); } List <string> texts = MakePostDataSubstitutes(request, null, bytes, apiArgs, postDataSubstitutes); System.Net.Http.HttpContent requestContent; if (texts == null) { await MakePostCurl(uri, headers, bytes, request.response.jq, binaryResponse); requestContent = new System.Net.Http.ByteArrayContent(bytes); } else { if (texts.Count == 1 && !isMultipart(headers)) { await MakePostCurl(uri, headers, texts, request.response.jq, binaryResponse); if (texts[0] == null) // Houndify text intent { requestContent = new System.Net.Http.ByteArrayContent(bytes); } else { requestContent = new System.Net.Http.StringContent(texts[0]); } await SystemNetAsync(response, "POST", uri, headers, requestContent, binaryResponse, maxResponseLength); return; } else { List <KeyValuePair <string, string> > lkvp = new List <KeyValuePair <string, string> >(); foreach (string s in texts) { lkvp.Add(new KeyValuePair <string, string>(s.Substring(0, s.IndexOf("=")), s.Substring(s.IndexOf("=") + 1))); } await MakePostMultiPartCurl(uri, headers, lkvp, request.response.jq, binaryResponse); System.Net.Http.MultipartFormDataContent multiPartRequestContent = new System.Net.Http.MultipartFormDataContent(); foreach (KeyValuePair <string, string> kvp in lkvp) { System.Net.Http.HttpContent ht; switch (kvp.Key) { case "file": ht = new System.Net.Http.ByteArrayContent(bytes); ht.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); // optional for HPE Haven? multiPartRequestContent.Add(ht, "\"file\"", "\"" + fileName + "\""); break; default: ht = new System.Net.Http.StringContent(kvp.Value); ht.Headers.ContentType = null; multiPartRequestContent.Add(ht, '"' + kvp.Key + '"'); break; } } await SystemNetAsync(response, "POST", uri, headers, multiPartRequestContent, binaryResponse, maxResponseLength); response.FileName = "curl-" + httpCallCount; return; } } #if WINDOWS_UWP if (Options.options.Services.APIs.PreferSystemNet) { await SystemNetAsync("POST", uri, headers, new System.Net.Http.ByteArrayContent(requestContent), binaryResponse, maxResponseLength); } else { await WindowsWebAsync("POST", new Uri(requestUri), audioBytes, sampleRate, contentType, headerValue); } #else await SystemNetAsync(response, "POST", uri, headers, requestContent, binaryResponse, maxResponseLength); #endif response.FileName = "curl-" + httpCallCount; }
private static async System.Threading.Tasks.Task PostAsync(ServiceResponse response, Uri uri, List <Tuple <string, string> > UriSubstitutes, List <Tuple <string, string> > headers, List <Tuple <string, string> > postDataSubstitutes, string text, System.Collections.Generic.Dictionary <string, string> apiArgs, int maxResponseLength = 10000000) { Settings.Request request = response.Request; bool binaryResponse = request.response.type == "binary"; if (uri == null) { uri = MakeUri(request, apiArgs, UriSubstitutes, text); } if (headers == null) { headers = MakeHeaders(request); } List <string> data = MakePostDataSubstitutes(request, text, null, apiArgs, postDataSubstitutes); if (data.Count == 1 && !isMultipart(headers)) { await MakePostCurl(uri, headers, data, request == null?null : request.response.jq, binaryResponse); System.Net.Http.HttpContent requestContent = new System.Net.Http.StringContent(data[0]); await SystemNetAsync(response, "POST", uri, headers, requestContent, binaryResponse, maxResponseLength); response.FileName = "curl-" + httpCallCount; return; } else { #if true // MicrosoftCognitiveInsightService can use multipart? See Post Byte[] overload above for helpful details. throw new Exception("PostAsync: multipart/form-data not implemented. Doesn't seem to work with System.Net.Http"); #else List <KeyValuePair <string, string> > kvps = new List <KeyValuePair <string, string> >(); foreach (string s in data) { kvps.Add(new KeyValuePair <string, string>(s.Substring(0, s.IndexOf("=")), s.Substring(s.IndexOf("=") + 1))); } await MakePostMultiPartCurl(uri, headers, kvps, request.response.jq, binaryResponse); List <KeyValuePair <string, string> > newkvps = new List <KeyValuePair <string, string> >(); foreach (KeyValuePair <string, string> kvp in kvps) { string s = kvp.Value; if (kvp.Value[0] == '@') { byte[] bytes = System.IO.File.ReadAllBytes(kvp.Value.Substring(1)); s = Convert.ToBase64String(bytes); } newkvps.Add(new KeyValuePair <string, string>(kvp.Key, s)); } System.Net.Http.MultipartFormDataContent multiPartRequestContent = new System.Net.Http.MultipartFormDataContent(); multiPartRequestContent.Add(new System.Net.Http.FormUrlEncodedContent(newkvps)); await SystemNetAsync(response, "POST", uri, headers, multiPartRequestContent, binaryResponse, maxResponseLength); response.FileName = "curl-" + httpCallCount; #endif } #if WINDOWS_UWP // major bit rot. Multi-part not implemented. if (Options.options.Services.APIs.PreferSystemNet) { response = await SystemNetAsync("POST", uri, headers, new System.Net.Http.ByteArrayContent(requestContent), binaryResponse, maxResponseLength); } else { response = await WindowsWebAsync("POST", new Uri(requestUri), audioBytes, sampleRate, contentType, headerValue); } #else { response = await SystemNetAsync("POST", uri, headers, requestContent, binaryResponse, maxResponseLength); } response.FileName = "curl-" + httpCallCount; return(response); #endif }
public static async System.Threading.Tasks.Task CallApiAsync(ServiceResponse response, List <Tuple <string, string> > UriSubstitutes, List <Tuple <string, string> > headers, List <Tuple <string, string> > postDataSubstitutes, string text, System.Collections.Generic.Dictionary <string, string> apiArgs, int maxResponseLength = 10000000) { await CallApiAsyncInternal(response, null, UriSubstitutes, headers, postDataSubstitutes, text, apiArgs); }
public static async System.Threading.Tasks.Task CallApiAsync(ServiceResponse response, Uri uri, string text, System.Collections.Generic.Dictionary <string, string> apiArgs, List <Tuple <string, string> > headers) { await CallApiAsyncInternal(response, uri, null, headers, null, text, apiArgs); }
public static async System.Threading.Tasks.Task CallApiAsync(ServiceResponse response, Uri url, System.Collections.Generic.Dictionary <string, string> apiArgs) { await CallApiAsyncInternal(response, null, null, null, null, url.ToString(), apiArgs); }
public static async System.Threading.Tasks.Task CallApiAsync(ServiceResponse response, List <Tuple <string, string> > uriSubstitutes, List <Tuple <string, string> > headers) { await CallApiAsyncInternal(response, null, uriSubstitutes, headers, null, new byte[0], null); }
private static JToken IntentConversationState = null; // need this to expire // override is working but somewhat verbose. Need to explore other methods such as passing Type? Need to combine Command->Run->Call as they're all the same Type. Make tail of Command into virtual. //public override async System.Threading.Tasks.Task<GenericCallServiceResponse<IHoundifyServiceResponse>> CallServiceAsync(byte[] bytes, System.Collections.Generic.Dictionary<string, string> apiArgs) public static async System.Threading.Tasks.Task HoundifyPostAsync(Settings.Service service, ServiceResponse response, Uri uri, byte[] RequestContentBytes, System.Collections.Generic.Dictionary <string, string> apiArgs) { Log.WriteLine("Content length:" + RequestContentBytes.Length); string ClientID = service.requests[0].headers[0].HoundifyAuthentication.ClientID; // moot? throws Exception thrown: 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' in Microsoft.CSharp.dll string ClientKey = service.requests[0].headers[0].HoundifyAuthentication.ClientKey; // moot? Exception thrown: 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' in Microsoft.CSharp.dll string UserID = service.requests[0].headers[0].HoundifyAuthentication.UserID; JObject RequestBodyObject; RequestBodyObject = JObject.FromObject(new { Latitude = GeoLocation.latitude, Longitude = GeoLocation.longitude, City = GeoLocation.town, Country = GeoLocation.country, UserID = UserID, ClientID = ClientID, // audio specific PartialTranscriptsDesired = Options.services["HoundifyIntentAudioService"].service.requests[0].PartialTranscriptsDesired, //ConversationState = IntentConversationState, }); if (IntentConversationState != null) { RequestBodyObject.Add(IntentConversationState); } string RequestBodyJson = JsonConvert.SerializeObject(RequestBodyObject); // no formatting. Could use ToString() but it formats (spaces, EOL). if (Options.options.debugLevel >= 4) { Log.WriteLine("RequestBodyJson:" + RequestBodyJson); } byte[] RequestBodyBytes = System.Text.Encoding.UTF8.GetBytes(RequestBodyJson).Concat(RequestContentBytes).ToArray(); //byte[] RequestBodyBytes = System.Text.Encoding.UTF8.GetBytes(RequestBodyJson).Concat(ReadBytesFromFile("wb_male.wav")).ToArray(); string RequestID = System.Guid.NewGuid().ToString("D"); // Houndify requires lower case? TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1); string Timestamp = Math.Floor(t.TotalSeconds).ToString(); string FriendlyClientKey = ClientKey.Replace('-', '+').Replace('_', '/'); // translate possible PHP encode style to FromBase64String style #if WINDOWS_UWP Windows.Storage.Streams.IBuffer KeyBytes = Windows.Security.Cryptography.CryptographicBuffer.DecodeFromBase64String(FriendlyClientKey); Windows.Storage.Streams.IBuffer MessageBytes = Windows.Security.Cryptography.CryptographicBuffer.ConvertStringToBinary(UserID + ";" + RequestID + Timestamp, Windows.Security.Cryptography.BinaryStringEncoding.Utf8); Windows.Security.Cryptography.Core.MacAlgorithmProvider MacAlg = Windows.Security.Cryptography.Core.MacAlgorithmProvider.OpenAlgorithm(Windows.Security.Cryptography.Core.MacAlgorithmNames.HmacSha256); Windows.Security.Cryptography.Core.CryptographicHash MacHash = MacAlg.CreateHash(KeyBytes); MacHash.Append(MessageBytes); Windows.Storage.Streams.IBuffer MacHashBuf = MacHash.GetValueAndReset(); string HashSignature = Windows.Security.Cryptography.CryptographicBuffer.EncodeToBase64String(MacHashBuf).Replace('+', '-').Replace('/', '_'); #else byte[] KeyBytes = Convert.FromBase64String(FriendlyClientKey); // TODO: shouldn't this be System.Text.Encoding.UTF8.GetBytes? byte[] MessageBytes = System.Text.Encoding.UTF8.GetBytes(UserID + ";" + RequestID + Timestamp); byte[] HashBytes = new System.Security.Cryptography.HMACSHA256(KeyBytes).ComputeHash(MessageBytes); // always length of 32? string HashSignature = Convert.ToBase64String(HashBytes).Replace('+', '-').Replace('/', '_'); #endif string HoundRequestAuthentication = UserID + ";" + RequestID; string HoundClientAuthentication = ClientID + ";" + Timestamp + ";" + HashSignature; if (Options.options.debugLevel >= 4) { Log.WriteLine("Uri:" + uri); Log.WriteLine("UserID:" + UserID); Log.WriteLine("RequestID:" + RequestID); Log.WriteLine("Timestamp:" + Timestamp); Log.WriteLine("ClientID:" + ClientID); Log.WriteLine("ClientKey:" + ClientKey); Log.WriteLine("FriendlyClientKey:" + FriendlyClientKey); Log.WriteLine("HashSignature:" + HashSignature); Log.WriteLine("HoundRequestAuthentication:" + HoundRequestAuthentication); Log.WriteLine("HoundClientAuthentication:" + HoundClientAuthentication); } #if true // TODO: put curl into woundifysettings.json? Log.WriteLine("curl -X POST" + " --data-binary @computer.wav" + " --header \"Hound-Request-Authentication:" + HoundRequestAuthentication + "\" --header \"Hound-Client-Authentication:" + HoundClientAuthentication + "\" --header \"Hound-Request-Info:" + RequestBodyJson.Replace('"', '\'') + "\" " + uri); #endif System.Collections.Generic.List <Tuple <string, string> > headers = new System.Collections.Generic.List <Tuple <string, string> >() { new Tuple <string, string>("Hound-Request-Info-Length", RequestBodyJson.Length.ToString()), new Tuple <string, string>("Hound-Request-Authentication", HoundRequestAuthentication), new Tuple <string, string>("Hound-Client-Authentication", HoundClientAuthentication) }; await HttpMethods.CallApiAsync(response, uri, RequestBodyBytes, apiArgs, headers); ProcessResponse(response.ResponseJToken); await HttpMethods.ExtractResultAsync(response); }