示例#1
0
        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);
                }
            }
        }
示例#2
0
        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);
        }
示例#3
0
 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);
         }
     }
 }
示例#4
0
        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;
        }
示例#5
0
        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
        }
示例#6
0
 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);
 }
示例#7
0
 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);
 }
示例#8
0
 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);
 }
示例#9
0
 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);
 }
示例#10
0
        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);
        }