Example #1
0
        public static async System.Threading.Tasks.Task ExtractResultAsync(ServiceResponse response)
        {
            switch (response.Request.response.type)
            {
            case "json":
                if (response.Request.response.jsonPath == null)     // json routine but no jsonPath specified. just ignore.
                {
                    return;
                }
                Settings.Request request = response.Request;
                if (response.ResponseJToken == null || string.IsNullOrEmpty(response.ResponseJToken.ToString()))
                {
                    response.ResponseResult = request.response.missingResponse;
                    if (Options.options.debugLevel >= 3)
                    {
                        Log.WriteLine(response.ResponseResult);
                    }
                }
                else
                {
                    // not sure how to handle array result
                    //response.ResponseResult = response.ResponseJToken.SelectTokens(service.response.jsonPath).ToString();
                    // jq.net doesn't seem to be supported. I don't know how to instantiate it as there's no constructor. I haven't found a substitute.
                    IEnumerable <Newtonsoft.Json.Linq.JToken> jtoks = response.ResponseJToken.SelectTokens(request.response.jsonPath);
                    response.ResponseResult = string.Empty;
                    foreach (Newtonsoft.Json.Linq.JToken jtok in jtoks)
                    {
                        response.ResponseResult += ", " + jtok.ToString();
                    }
                    if (response.ResponseResult.Length > 0)
                    {
                        response.ResponseResult = response.ResponseResult.Substring(2);
                    }
                    if (Options.options.debugLevel >= 3)
                    {
                        Log.WriteLine(response.ResponseJToken.Path + ": " + response.ResponseResult);
                    }
                }
                break;

            case "xml":
                // not implemented/debugged
                response.ResponseXml.LoadXml(response.ResponseResult);
                response.ResponseXmlNodeList  = response.ResponseXml.SelectNodes(response.Request.response.xpath);
                response.ResponseXmlFormatted = response.ResponseXmlNodeList.ToString();     // must be wrong
                break;

            default:
                break;
            }
        }
Example #2
0
        private static List <Tuple <string, string> > MakeHeaders(Settings.Request request)
        {
            List <Tuple <string, string> > headers = new List <Tuple <string, string> >();

            if (request == null || request.headers == null)
            {
                return(headers);
            }
            foreach (Settings.Header h in request.headers)
            {
                // TODO: need to expand request headers to include any header. Use Value instead of "Generic" or concrete name (Accept, ContentType)
                switch (h.Name)
                {
                case "BearerAuthentication":
                    AccessTokenInfo accessTokenInfo = ImageAuth.PerformAuthenticationAsync(request, h).Result;     // TODO: make this method async so don't have to do Wait?

                    headers.Add(new Tuple <string, string>("Authorization", "Bearer " + accessTokenInfo.access_token));
                    break;

                case "BasicAuthentication":
                    string userpass = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", h.BasicAuthentication.username, h.BasicAuthentication.password).Replace('+', '-').Replace('/', '_')));
                    headers.Add(new Tuple <string, string>("Authorization", "Basic " + userpass));
                    break;

                case "HoundifyAuthentication":     // will be passed in but must skip, don't let default
                    break;

                case "OcpApimSubscriptionKey":
                    headers.Add(new Tuple <string, string>("Ocp-Apim-Subscription-Key", h.OcpApimSubscriptionKey));    // needs rewrite. see above.
                    break;

                default:
                    if (h.Generic == null)
                    {
                        throw new Exception("Header: Generic is null");
                    }
                    headers.Add(new Tuple <string, string>(h.Name, h.Generic));
                    break;
                }
            }
            return(headers);
        }
Example #3
0
        private static async System.Threading.Tasks.Task GetAsync(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> texts = MakePostDataSubstitutes(request, text, null, apiArgs, postDataSubstitutes);

            if (texts.Count != 1)
            {
                throw new Exception("multipart GET not allowed");
            }
            await MakeGetCurl(uri, headers, request.response.jq, binaryResponse);

#if WINDOWS_UWP
            ServiceResponse response;
            if (Options.options.Services.APIs.PreferSystemNet)
            {
                await SystemNetAsync("GET", uri, headers, new System.Net.Http.ByteArrayContent(requestContent), binaryResponse, maxResponseLength);
            }
            else
            {
                await WindowsWebAsync("GET", new Uri(requestUri), audioBytes, sampleRate, contentType, headerValue);
            }
#else
            await SystemNetAsync(response, "GET", uri, headers, null, binaryResponse, maxResponseLength);
#endif
            response.FileName = "curl-" + httpCallCount;
        }
Example #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, 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
        }
Example #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, 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;
        }
Example #6
0
        private static List <string> MakePostDataSubstitutes(Settings.Request request, string text, byte[] bytes, System.Collections.Generic.Dictionary <string, string> apiArgs, List <Tuple <string, string> > postDataSubstitutes)
        {
            if (request == null || request.data == null || request.data.type == null) // some POSTs have no data
            {
                return new List <string> {
                           text
                }
            }
            ;

            if (text != null && bytes != null)
            {
                throw new Exception("MakePostDataSubstitutes: Both text and bytes are not null");
            }

            string data = text;

            if (request.data.value != null)
            {
                data = request.data.value;
            }

            if (postDataSubstitutes != null)
            {
                foreach (Tuple <string, string> r in postDataSubstitutes)
                {
                    data = data.Replace(r.Item1, r.Item2);
                }
            }

            string fileName = null;

            if (apiArgs.ContainsKey("fileName"))
            {
                fileName = apiArgs["fileName"];
            }

            switch (request.data.type)
            {
            case "ascii":
                return(new List <string> {
                    data
                });

            case "base64":
                // TODO: use Helpers.stringToDictionary()
                if (data.Contains("="))     // TODO: use text or data?
                {
                    List <string> base64content = new List <string>();
                    foreach (string multicontent in data.Split('&'))
                    {
                        string[] namecontent = multicontent.Split('=');
                        if (namecontent.Length != 2)
                        {
                            throw new FormatException();
                        }
                        base64content.Add(namecontent[0] + "=" + namecontent[1].Replace("{text}", Convert.ToBase64String(bytes)));
                    }
                    return(base64content);
                }
                else
                {
                    return(new List <string> {
                        data.Replace("{text}", Convert.ToBase64String(bytes))
                    });
                }

            case "binary":
                return(null);

            case "json":
                // TODO: pass list of substitutes instead of hard coding?
                // TODO: issue with replacing "'" with "\\'". Seems to work when json properties are delimited with single-quotes but not with double-quotes.
                if (data.Contains("{base64}") ^ bytes != null)
                {
                    throw new Exception("json: bytes ^ {base64} mismatch");             // can occur if string/url argument is passed to binary data API
                }
                if ((data.Contains("{text}") || data.Contains("{url}")) ^ text != null) // todo: remove when url is implemented
                {
                    throw new Exception("json: text ^ {text} mismatch");
                }
                // pass Uri here so request use Url instead of text
                //if (data.Contains("{url}") ^ text != null)
                //throw new Exception("json: text ^ {url} mismatch");
                if (bytes != null)
                {
                    return new List <string> {
                               data.Replace("{guid}", Guid.NewGuid().ToString()).Replace("{base64}", Convert.ToBase64String(bytes))
                    }
                }
                ;
                else if (text != null)
                {
                    return new List <string> {
                               data.Replace("{guid}", Guid.NewGuid().ToString()).Replace("{url}", text).Replace("{text}", text.Replace("\"", "\\\""))
                    }
                }
                ;                                                                                                                                                           // bing sentiment uses guid. Replace '"' with '\"'
                else
                {
                    throw new Exception("json: expecting bytes or text");
                }

            case "multipart":
                // TODO: use Helpers.stringToDictionary()
                if (!data.Contains("="))     // && isMultipart(headers)?
                {
                    throw new Exception("multipart is missing =");
                }
                List <string> multipartcontent = new List <string>();
                foreach (string multicontent in data.Split('&'))
                {
                    string[] namecontent = multicontent.Split('=');
                    if (namecontent.Length != 2)
                    {
                        throw new FormatException();
                    }
                    if (fileName != null)
                    {
                        multipartcontent.Add(namecontent[0] + "=" + namecontent[1].Replace("{text}", fileName));     // hpe haven ocr
                    }
                    else if (bytes != null)
                    {
                        multipartcontent.Add(namecontent[0] + "=" + namecontent[1].Replace("{text}", Convert.ToBase64String(bytes)));     // bing spell, Microsoft Detect
                    }
                    else if (text != null)
                    {
                        multipartcontent.Add(namecontent[0] + "=" + namecontent[1].Replace("{text}", text));     // bing spell, Microsoft Detect
                    }
                }
                return(multipartcontent);

            case "raw":
                return(new List <string> {
                    data
                });

            case "string":
                return(new List <string> {
                    data
                });

            case "urlencode":
                // TODO: use Helpers.stringToDictionary()
                if (text == null)
                {
                    throw new Exception("urlencode: expecting text");
                }
                if (data.Contains("="))     // && isMultipart(headers)?
                {
                    List <string> urlencodecontent = new List <string>();
                    foreach (string multicontent in data.Split('&'))
                    {
                        string[] namecontent = multicontent.Split('=');
                        if (namecontent.Length != 2)
                        {
                            throw new FormatException();
                        }
                        urlencodecontent.Add(namecontent[0] + "=" + (namecontent[1][0] == '@' ? namecontent[1] : System.Web.HttpUtility.UrlEncode(namecontent[1].Replace("{text}", text))));
                    }
                    return(urlencodecontent);
                }
                else
                {
                    return(new List <string> {
                        System.Web.HttpUtility.UrlEncode(data)
                    });
                }

            case "xml":
                // TODO: pass list of substitutes instead of hard coding?
                if (bytes == null)
                {
                    return new List <string> {
                               data.Replace("{guid}", Guid.NewGuid().ToString()).Replace("{text}", text)
                    }
                }
                ;                                                                                                              // bing sentiment uses guid
                else
                {
                    return new List <string> {
                               data.Replace("{guid}", Guid.NewGuid().ToString()).Replace("{text}", Convert.ToBase64String(bytes))
                    }
                };                                                                                                                                      // bing sentiment uses guid

            default:
                throw new MissingFieldException();
            }
        }
Example #7
0
        public static Uri MakeUri(Settings.Request request, Dictionary <string, string> apiArgs, List <Tuple <string, string> > uriSubstitutes = null, string text = null)
        {
            UriBuilder ub     = new UriBuilder();
            string     scheme = request.uri.scheme;
            string     host   = request.uri.host;
            string     path   = request.uri.path;
            string     query  = request.uri.query;

            if (apiArgs != null)
            {
                foreach (KeyValuePair <string, string> r in apiArgs)
                {
                    // so far only query needs substitutes
                    string k = "{" + r.Key + "}";
                    scheme = scheme.Replace(k, r.Value);
                    host   = host.Replace(k, r.Value);
                    path   = path.Replace(k, r.Value);
                    if (query == null)
                    {
                        query = string.Empty;
                    }
                    else
                    {
                        query = query.Replace(k, r.Value);
                    }
                }
            }

            if (uriSubstitutes == null)
            {
                uriSubstitutes = new System.Collections.Generic.List <Tuple <string, string> >()
                {
                    new Tuple <string, string>("{guid}", Guid.NewGuid().ToString()),        // Microsoft SpeechToText
                    new Tuple <string, string>("{locale}", Options.options.locale.language) // Microsoft SpeechToText
                };
                if (text != null)
                {
                    uriSubstitutes.Add(new Tuple <string, string>("{text}", text));
                }
            }

            if (uriSubstitutes != null)
            {
                foreach (Tuple <string, string> r in uriSubstitutes)
                {
                    // so far only query needs substitutes
                    scheme = scheme.Replace(r.Item1, r.Item2);
                    host   = host.Replace(r.Item1, r.Item2);
                    path   = path.Replace(r.Item1, r.Item2);
                    if (query == null)
                    {
                        query = string.Empty;
                    }
                    else
                    {
                        query = query.Replace(r.Item1, r.Item2);
                    }
                }
            }
            ub.Scheme = scheme;
            ub.Host   = host;
            ub.Path   = path;
            ub.Query  = query;
            ub.Query  = query;
            return(ub.Uri);
        }
Example #8
0
        public async System.Threading.Tasks.Task <AccessTokenInfo> PerformAuthenticationAsync(Settings.Request request, Settings.Header h)
        {
            Settings.BearerAuthentication bearer = h.BearerAuthentication;
            if (request == null || h == null)
            {
                throw new Exception("request/h is null");
            }
            if (h.OcpApimSubscriptionKey != null) // ClarifAi, OcpApimSubscriptionKey
            {
                Settings.BearerAuthentication BearerAuth = h.BearerAuthentication;
                Uri accessUri = new Uri(BearerAuth.uri);
                // todo: this only works for Microsoft APIs. Make code conditional on Microsoft? Break out as separate API to be execute first? Change headers in json file?
                headers = new System.Collections.Generic.List <Tuple <string, string> >()
                {
                    new Tuple <string, string>("Content-Type", "application/x-www-form-urlencoded"),
                    new Tuple <string, string>("Ocp-Apim-Subscription-Key", h.OcpApimSubscriptionKey)        // TODO: need dictionary lookup instead of hardcoding
                };
                ServiceResponse sr = new ServiceResponse();
                HttpMethods.CallApiAuthAsync(sr, accessUri, "", headers).Wait();
                accessTokenInfo = new AccessTokenInfo();
                accessTokenInfo.access_token = sr.ResponseString;
            }
            else if (h.BearerAuthentication.clientID != null && h.BearerAuthentication.clientSecret != null) // Microsoft
            {
                string clientID     = bearer.clientID;
                string clientSecret = bearer.clientSecret;
                //string scope = bearer.scope;

                this.request = request;
                System.Collections.Generic.List <Tuple <string, string> > grantSubstitutes = new System.Collections.Generic.List <Tuple <string, string> >()
                {
                    new Tuple <string, string>("{clientID}", System.Web.HttpUtility.UrlEncode(clientID)),
                    new Tuple <string, string>("{clientSecret}", System.Web.HttpUtility.UrlEncode(clientSecret)),
                    //new Tuple<string, string>("{scope}", System.Web.HttpUtility.UrlEncode(scope)),
                };
                grant = bearer.grant;
                foreach (Tuple <string, string> r in grantSubstitutes)
                {
                    grant = grant.Replace(r.Item1, r.Item2);
                }
                accessUri = new Uri(bearer.uri);
                headers   = new System.Collections.Generic.List <Tuple <string, string> >()
                {
                    new Tuple <string, string>("Content-Type", "application/x-www-form-urlencoded")
                };
                ServiceResponse sr = new ServiceResponse();
                await HttpMethods.CallApiAuthAsync(sr, accessUri, grant, headers);

                accessTokenInfo = Newtonsoft.Json.JsonConvert.DeserializeObject <AccessTokenInfo>(sr.ResponseString);

                // renew the token every specfied minutes
                accessTokenRenewer = new System.Threading.Timer(new System.Threading.TimerCallback(OnTokenExpiredCallbackAsync),
                                                                this,
                                                                TimeSpan.FromMinutes(RefreshTokenDuration),
                                                                TimeSpan.FromMilliseconds(-1));
            }
            else if (h.BearerAuthentication.bearer != null) // Wit.Ai
            {
                accessTokenInfo.access_token = h.BearerAuthentication.bearer;
            }
            else
            {
                throw new Exception("Unknown Bearer Authentication");
            }
            return(accessTokenInfo);
        }