private async Task PutBoolAsync(IFlurlRequest url, bool value)
 {
     await url
     .WithHeader("Content-Type", "application/json")
     .PutJsonAsync(value)
     .ConfigureAwait(false);
 }
示例#2
0
        /// <inheritdoc />
        public async Task <TSource?> FindAsync(string docId, bool withConflicts    = false,
                                               CancellationToken cancellationToken = default)
        {
            try
            {
                IFlurlRequest request = NewRequest()
                                        .AppendPathSegment(docId);

                if (withConflicts)
                {
                    request = request.SetQueryParam("conflicts", "true");
                }

                TSource document = await request
                                   .GetJsonAsync <TSource>(cancellationToken)
                                   .SendRequestAsync()
                                   .ConfigureAwait(false);

                InitAttachments(document);
                return(document);
            }
            catch (CouchNotFoundException)
            {
                return(null);
            }
        }
示例#3
0
        internal static Task <IFlurlResponse> PatchMultipartAsync(this IFlurlRequest request, Action <CapturedMultipartContent> buildContent, CancellationToken cancellationToken = default(CancellationToken))
        {
            var cmc = new CapturedMultipartContent(request.Settings);

            buildContent(cmc);
            return(request.SendAsync(new HttpMethod("PATCH"), cmc, cancellationToken));
        }
示例#4
0
        public async Task EbayRestClient_Should_ThrowEbayException()
        {
            var moqAuth = Substitute.For <IOAuth2Authenticator>();

            moqAuth.GetTokenAsync().Returns(new Token
            {
                AccessToken = "randomtoken"
            });

            var restClient = new EbayRestClient
            {
                OAuth2Authenticator = moqAuth
            };

            IFlurlRequest flurl = "/some/path"
                                  .AppendPathSegment($"to", fullyEncode: true)
                                  .WithHeader("header", "value");

            using (var httpTest = new HttpTest())
            {
                httpTest.RespondWith("Resource Not Found", 404);

                await Assert.ThrowsAsync <EbayException>(async() => await restClient.Request <object>(flurl));
            }
        }
示例#5
0
        /// <inheritdoc />
        public async Task <TSource> AddOrUpdateAsync(TSource document, bool batch = false, CancellationToken cancellationToken = default)
        {
            Check.NotNull(document, nameof(document));

            if (string.IsNullOrEmpty(document.Id))
            {
                throw new InvalidOperationException("Cannot add or update a document without an ID.");
            }

            IFlurlRequest request = NewRequest()
                                    .AppendPathSegment(document.Id);

            if (batch)
            {
                request = request.SetQueryParam("batch", "ok");
            }

            DocumentSaveResponse response = await request
                                            .PutJsonAsync(document, cancellationToken)
                                            .ReceiveJson <DocumentSaveResponse>()
                                            .SendRequestAsync()
                                            .ConfigureAwait(false);

            document.ProcessSaveResponse(response);

            await UpdateAttachments(document, cancellationToken)
            .ConfigureAwait(false);

            return(document);
        }
示例#6
0
        public static async Task <ASMessageResponse> ToAngleSharpResponse(
            this IFlurlRequest flurlRequest,
            Func <IFlurlRequest, Task <HttpResponseMessage> > executionPredicate,
            CancellationToken cancellationToken = default
            )
        {
            // conversion from *flurl's* custom URL to *anglesharp's* custom URL
            // apparently .NET's URI just sucks that much
            var uri = flurlRequest.Url.ToUri();
            var url = Url.Convert(uri);


            if (executionPredicate == null)
            {
                Task <IFlurlResponse> flurlResponseMessageTask = flurlRequest.GetAsync(cancellationToken);

                var flurlResponseMessage = await flurlResponseMessageTask.ConfigureAwait(false);

                var content = await flurlResponseMessage.ResponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);

                return(new ASMessageResponse(url, flurlResponseMessage.ResponseMessage, content));
            }
            else
            {
                Task <HttpResponseMessage> httpResponseMessageTask = executionPredicate(flurlRequest);

                var httpResponseMessage = await httpResponseMessageTask.ConfigureAwait(false);

                var content = await httpResponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);

                return(new ASMessageResponse(url, httpResponseMessage, content));
            }
        }
示例#7
0
        public static async Task <T> GetSoundByteJsonAsync <T>(this IFlurlRequest req, IAuthenticationService authenticationService)
        {
            // Internal request
            var r = req;

            // If the users SoundByte account is connected, perform an OAuth request
            var accountToken = await authenticationService.GetSoundByteAccountTokenAsync();

            if (accountToken != null)
            {
                r = r.WithOAuthBearerToken(accountToken.AccessToken);
            }

            try
            {
                // Attempt to get the response
                return(await r.GetJsonAsync <T>());
            }
            catch (FlurlHttpException ex)
            {
                // If an account token was provided, and
                if (accountToken != null && ex.Call.HttpStatus == System.Net.HttpStatusCode.Unauthorized)
                {
                    // Refresh the token and store it
                    var newToken = await authenticationService.RefreshTokenAsync(accountToken.RefreshToken, null);

                    await authenticationService.ConnectSoundByteAccountAsync(newToken);

                    // Perform the request again
                    return(await GetSoundByteJsonAsync <T>(req, authenticationService));
                }

                throw ex;
            }
        }
示例#8
0
        /// <summary>
        /// Returns changes as they happen. A continuous feed stays open and connected to the database until explicitly closed.
        /// </summary>
        /// <remarks>
        /// To stop receiving changes call <c>Cancel()</c> on the <c>CancellationTokenSource</c> used to create the <c>CancellationToken</c>.
        /// </remarks>
        /// <param name="options">Options to apply to the request.</param>
        /// <param name="filter">A filter to apply to the result.</param>
        /// <param name="cancellationToken">A cancellation token to stop receiving changes.</param>
        /// <returns></returns>
        public async IAsyncEnumerable <ChangesFeedResponseResult <TSource> > GetContinuousChangesAsync(ChangesFeedOptions options, ChangesFeedFilter filter,
                                                                                                       [EnumeratorCancellation] CancellationToken cancellationToken)
        {
            var           infiniteTimeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
            IFlurlRequest request         = NewRequest()
                                            .WithTimeout(infiniteTimeout)
                                            .AppendPathSegment("_changes")
                                            .SetQueryParam("feed", "continuous");

            SetChangesFeedOptions(request, options);

            await using Stream stream = filter == null
                ? await request.GetStreamAsync(cancellationToken, HttpCompletionOption.ResponseHeadersRead)
                                        .ConfigureAwait(false)
                : await QueryContinuousWithFilterAsync(request, filter, cancellationToken)
                                        .ConfigureAwait(false);

            using var reader = new StreamReader(stream);
            while (!cancellationToken.IsCancellationRequested && !reader.EndOfStream)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    continue;
                }

                var line = await reader.ReadLineAsync().ConfigureAwait(false);

                if (!string.IsNullOrEmpty(line))
                {
                    yield return(JsonConvert.DeserializeObject <ChangesFeedResponseResult <TSource> >(line));
                }
            }
        }
示例#9
0
 public static Task <T> GetHtmlAsync <T>(
     this IFlurlRequest request,
     CancellationToken cancellationToken   = default,
     HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead)
 {
     return(request.SendAsync(HttpMethod.Get, null, cancellationToken, completionOption).ReceiveHtml <T>());
 }
        public IEnumerable <TResponse> Enumerate(IFlurlRequest request)
        {
            request.AllowHttpStatus(HttpStatusCode.NotFound);
            var more = true;

            while (more)
            {
                // Need headers & result so capture task first: https://stackoverflow.com/a/53514668/129269
                var task = request.GetAsync();

                var response = task.ConfigureAwait(false).GetAwaiter().GetResult();
                if (response.StatusCode == HttpStatusCode.NotFound)
                {
                    throw new NotFoundException(request.Url.ToString());
                }
                var data = task.ReceiveJson <Multiple <TResponse> >().ConfigureAwait(false).GetAwaiter().GetResult();

                foreach (var item in data.Value)
                {
                    yield return(item);
                }

                more = response.Headers.TryGetValues("x-ms-continuationtoken", out var tokens);
                request.SetQueryParam("continuationToken", tokens?.First());
            }
        }
示例#11
0
        /// <summary>
        /// Creates a new document and returns it.
        /// </summary>
        /// <param name="document">The document to create.</param>
        /// <param name="batch">Stores document in batch mode.</param>
        /// <returns>A task that represents the asynchronous operation. The task result contains the element created.</returns>
        public async Task <TSource> CreateAsync(TSource document, bool batch = false)
        {
            if (!string.IsNullOrEmpty(document.Id))
            {
                return(await CreateOrUpdateAsync(document)
                       .ConfigureAwait(false));
            }

            IFlurlRequest request = NewRequest();

            if (batch)
            {
                request = request.SetQueryParam("batch", "ok");
            }

            DocumentSaveResponse response = await request
                                            .PostJsonAsync(document)
                                            .ReceiveJson <DocumentSaveResponse>()
                                            .SendRequestAsync()
                                            .ConfigureAwait(false);

            document.ProcessSaveResponse(response);

            await UpdateAttachments(document)
            .ConfigureAwait(false);

            return(document);
        }
示例#12
0
        /// <summary>
        /// This method is used to get a commit author's full name via the github rest api.
        /// Reference: https://docs.github.com/en/rest
        /// For an example response: https://api.github.com/repos/Azure/iotedge/commits/704250b
        /// </summary>
        /// <param name="commit">Commit for which to get the author's full name.</param>
        /// <returns>Full name of author.</returns>
        public async Task <string> GetAuthorFullNameFromCommitAsync(string commit)
        {
            string requestPath = string.Format(UserPathSegmentFormat, commit);

            IFlurlRequest workItemQueryRequest = ((Url)requestPath)
                                                 .WithHeader("Content-Type", "application/json")
                                                 .WithHeader("User-Agent", "Azure/iotedge");

            JObject result;

            try
            {
                IFlurlResponse response = await workItemQueryRequest.GetAsync();

                result = await response.GetJsonAsync <JObject>();

                string fullName = result["commit"]["author"]["name"].ToString();
                return(fullName);
            }
            catch (FlurlHttpException e)
            {
                string message = $"Failed making call to commit api: {e.Message}";
                Console.WriteLine(message);
                Console.WriteLine(e.Call.RequestBody);
                Console.WriteLine(e.Call.Response.StatusCode);
                Console.WriteLine(e.Call.Response.ResponseMessage);

                throw new Exception(message);
            }
        }
示例#13
0
        public static async Task <CiatData> LoadData(Position position, string crop)
        {
            string        lat     = position.Latitude.ToString().Replace(",", ".");
            string        lon     = position.Longitude.ToString().Replace(",", ".");
            IFlurlRequest request = Constants
                                    .MatrizBaseUrl
                                    .SetQueryParams(
                new
            {
                lat     = lat,
                lon     = lon,
                type    = "matriz",
                tkn     = Constants.BemToken,
                cultivo = crop
            })
                                    .WithBasicAuth(Constants.BemUsername, Constants.BemPassword);

            List <CiatResponseData> responseData;

            try
            {
                responseData = await request.GetJsonAsync <List <CiatResponseData> >();
            }
            catch (Exception e)
            {
                return(null);
            }

            return(CiatData.FromResponse(responseData, request.Url));
        }
示例#14
0
        /// <summary>
        /// Adds or updates a name-value pair in this request's Cookie header.
        /// To automatically maintain a cookie "session", consider using a CookieJar or CookieSession instead.
        /// </summary>
        /// <param name="request">The IFlurlRequest.</param>
        /// <param name="name">The cookie name.</param>
        /// <param name="value">The cookie value.</param>
        /// <returns>This IFlurlClient instance.</returns>
        public static IFlurlRequest WithCookie(this IFlurlRequest request, string name, object value)
        {
            var cookies = new NameValueList <string>(request.Cookies);

            cookies.AddOrReplace(name, value.ToInvariantString());
            return(request.WithHeader("Cookie", CookieCutter.ToRequestHeader(cookies)));
        }
示例#15
0
        /// <summary>
        /// This method is used to get latest build result of given build definition Ids and branch name.
        /// The results should always contain same number of vsts build entity of given build definitions.
        /// If result is not found for a build definition Id, it will return vsts build entity with no result.
        /// Note: no validation of build definition ids is taken.
        /// Reference: https://docs.microsoft.com/en-us/rest/api/azure/devops/wit/work%20items/list?view=azure-devops-rest-5.1
        /// </summary>
        /// <param name="buildDefinitionIds">build definition Ids</param>
        /// <param name="branchName">github repository branch name</param>
        /// <returns>List of vsts build entities</returns>
        public async Task <IList <VstsBuild> > GetLatestBuildsAsync(HashSet <BuildDefinitionId> buildDefinitionIds, string branchName)
        {
            ValidationUtil.ThrowIfNulOrEmptySet(buildDefinitionIds, nameof(buildDefinitionIds));
            ValidationUtil.ThrowIfNullOrWhiteSpace(branchName, nameof(branchName));

            // TODO: need to think about how to handle unexpected exception during REST API call
            string        requestPath        = string.Format(LatestBuildPathSegmentFormat, this.accessSetting.Organization, this.accessSetting.Project);
            IFlurlRequest latestBuildRequest = DevOpsAccessSetting.BaseUrl
                                               .AppendPathSegment(requestPath)
                                               .SetQueryParam("definitions", string.Join(",", buildDefinitionIds.Select(b => b.IdString())))
                                               .SetQueryParam("queryOrder", "finishTimeDescending")
                                               .SetQueryParam("maxBuildsPerDefinition", "1")
                                               .SetQueryParam("api-version", "5.1")
                                               .SetQueryParam("branchName", branchName)
                                               .WithBasicAuth(string.Empty, this.accessSetting.PersonalAccessToken);

            string resultJson = await latestBuildRequest.GetStringAsync().ConfigureAwait(false);

            JObject result = JObject.Parse(resultJson);

            if (!result.ContainsKey("count") || (int)result["count"] <= 0)
            {
                return(buildDefinitionIds.Select(i => VstsBuild.GetBuildWithNoResult(i, branchName)).ToList());
            }

            Dictionary <BuildDefinitionId, VstsBuild> latestBuilds = JsonConvert.DeserializeObject <VstsBuild[]>(result["value"].ToString()).ToDictionary(b => b.DefinitionId, b => b);

            return(buildDefinitionIds.Select(i => latestBuilds.ContainsKey(i) ? latestBuilds[i] : VstsBuild.GetBuildWithNoResult(i, branchName)).ToList());
        }
示例#16
0
        /// <summary>
        /// Creates a new database with the given name in the server.
        /// The name must begin with a lowercase letter and can contains only lowercase characters, digits or _, $, (, ), +, - and /.s
        /// </summary>
        /// <typeparam name="TSource">The type of database documents.</typeparam>
        /// <param name="database">The database name.</param>
        /// <param name="shards">The number of range partitions. Default is 8, unless overridden in the cluster config.</param>
        /// <param name="replicas">The number of copies of the database in the cluster. The default is 3, unless overridden in the cluster config.</param>
        /// <returns>A task that represents the asynchronous operation. The task result contains the newly created CouchDB database.</returns>
        public async Task <CouchDatabase <TSource> > CreateDatabaseAsync <TSource>(string database, int?shards = null, int?replicas = null) where TSource : CouchDocument
        {
            database = EscapeDatabaseName(database);

            IFlurlRequest request = NewRequest()
                                    .AppendPathSegment(database);

            if (shards.HasValue)
            {
                request = request.SetQueryParam("q", shards.Value);
            }

            if (replicas.HasValue)
            {
                request = request.SetQueryParam("n", replicas.Value);
            }

            OperationResult result = await request
                                     .PutAsync(null)
                                     .ReceiveJson <OperationResult>()
                                     .SendRequestAsync()
                                     .ConfigureAwait(false);

            if (!result.Ok)
            {
                throw new CouchException("Something went wrong during the creation");
            }

            return(new CouchDatabase <TSource>(_flurlClient, _settings, ConnectionString, database));
        }
示例#17
0
        public static Url SetQueryModel <TType>(this IFlurlRequest url, TType model)
        {
            var properties = model.GetType().GetProperties();

            Dictionary <string, object> dict = new Dictionary <string, object>();

            foreach (var prop in properties)
            {
                var name  = prop.Name.ToLower();
                var value = prop.GetValue(model, null);
                var attrs = prop.GetCustomAttributes(false);

                foreach (var item in attrs)
                {
                    if (item is FlurlPropertyAttribute castedItem)
                    {
                        name = castedItem.ParamName;
                    }
                }

                if (value != null)
                {
                    dict.Add(name, value);
                }
            }

            return(new Url(url.Url).SetQueryParams(dict));
        }
示例#18
0
        /// <summary>
        /// This method is used to execute a Dev Ops work item query and get the number of bugs for a given query.
        /// If result is not found for a query, it will return 0.
        /// Reference: https://docs.microsoft.com/en-us/rest/api/azure/devops/wit/wiql/query%20by%20wiql?view=azure-devops-rest-5.1
        /// </summary>
        /// <param name="bugQuery">Bug query object representing vsts shared queries</param>
        /// <returns>Number of bugs output by query</returns>
        public async Task <int> GetBugsCountAsync(BugQuery bugQuery)
        {
            // TODO: need to think about how to handle unexpected exception during REST API call
            string        requestPath          = string.Format(WorkItemPathSegmentFormat, DevOpsAccessSetting.BaseUrl, this.accessSetting.Organization, this.accessSetting.Project, this.accessSetting.Team);
            IFlurlRequest workItemQueryRequest = ((Url)requestPath)
                                                 .WithBasicAuth(string.Empty, this.accessSetting.PersonalAccessToken)
                                                 .SetQueryParam("api-version", "5.1");

            JObject result;

            try
            {
                IFlurlResponse response = await workItemQueryRequest
                                          .PostJsonAsync(new { query = bugQuery.GetWiqlFromConfiguration() });

                result = await response.GetJsonAsync <JObject>();
            }
            catch (FlurlHttpException e)
            {
                Console.WriteLine($"Failed making call to vsts work item api: {e.Message}");
                Console.WriteLine(e.Call.RequestBody);
                Console.WriteLine(e.Call.Response.StatusCode);
                Console.WriteLine(e.Call.Response.ResponseMessage);
                return(0);
            }

            if (!result.ContainsKey("queryType"))
            {
                return(0);
            }

            return(result["workItems"].Count());
        }
示例#19
0
        public static async Task <string> HandleAuthExpireAsync(this IFlurlRequest req, IAuthenticationService authenticationService, MusicProvider musicProvider)
        {
            // Internal request
            var r = req;

            // If the music provider account is connected, perform an OAuth request
            var accountToken = await authenticationService.GetTokenAsync(musicProvider.Identifier);

            if (accountToken != null && musicProvider.Manifest.Authentication != null)
            {
                r = r.WithHeader("Authorization", $"{musicProvider.Manifest.Authentication.Scheme ?? "Bearer"} {accountToken.AccessToken}");
            }

            try
            {
                // Attempt to get the response
                return(await r.GetStringAsync());
            }
            catch (FlurlHttpException ex)
            {
                // If an account token was provided, and
                if (accountToken != null && ex.Call.HttpStatus == System.Net.HttpStatusCode.Unauthorized)
                {
                    // Refresh the token and store it
                    var newToken = await authenticationService.RefreshTokenAsync(accountToken.RefreshToken, musicProvider.Identifier);

                    await authenticationService.ConnectAccountAsync(musicProvider.Identifier, newToken);

                    // Perform the request again
                    return(await HandleAuthExpireAsync(req, authenticationService, musicProvider));
                }

                throw ex;
            }
        }
示例#20
0
        private static async Task <List <T> > Load <T>(string parameter, double?lat = null, double?lon = null, CropType?crop = null)
        {
            IFlurlRequest request = $"{Constants.BemBaseUrl}?type={parameter}&tkn={Constants.BemToken}"
                                    .WithBasicAuth(Constants.BemUsername, Constants.BemPassword);

            if (lat != null)
            {
                request.SetQueryParam("lat", lat.Value.ToString(CultureInfo.InvariantCulture));
            }

            if (lon != null)
            {
                request.SetQueryParam("lon", lon.Value.ToString(CultureInfo.InvariantCulture));
            }

            if (crop != null && crop == CropType.Corn) //TODO: use crop types
            {
                request.SetQueryParam("cultivo", "Maiz");
            }

            List <T> data = null;

            try
            {
                data = await request.GetJsonAsync <List <T> >();
            }
            catch (Exception)
            {
            }

            return(data);
        }
示例#21
0
        public static async Task <dynamic> PostRequest(string[] PathSegments, object RequestBodyObject)
        {
            IFlurlRequest request = TrackIt_2019.API.BaseUri.AppendPathSegments(PathSegments).WithOAuthBearerToken((string)TrackIt_2019.API.Authentication.Token.access_token);
            dynamic       result  = await request.PostJsonAsync(RequestBodyObject).ReceiveJson();

            return(result);
        }
示例#22
0
        /// <summary>
        /// Sends an asynchronous multipart/form-data POST request.
        /// </summary>
        /// <param name="buildContent">A delegate for building the content parts.</param>
        /// <param name="request">The IFlurlRequest.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <returns>A Task whose result is the received HttpResponseMessage.</returns>
        public static Task <HttpResponseMessage> PostMultipartAsync(this IFlurlRequest request, Action <CapturedMultipartContent> buildContent, CancellationToken cancellationToken = default(CancellationToken))
        {
            var cmc = new CapturedMultipartContent(request.Settings);

            buildContent(cmc);
            return(request.SendAsync(HttpMethod.Post, cmc, cancellationToken));
        }
示例#23
0
        /// <inheritdoc />
        public async Task <TSource> AddAsync(TSource document, bool batch = false, CancellationToken cancellationToken = default)
        {
            Check.NotNull(document, nameof(document));

            if (!string.IsNullOrEmpty(document.Id))
            {
                return(await AddOrUpdateAsync(document, batch, cancellationToken)
                       .ConfigureAwait(false));
            }

            IFlurlRequest request = NewRequest();

            if (batch)
            {
                request = request.SetQueryParam("batch", "ok");
            }

            DocumentSaveResponse response = await request
                                            .PostJsonAsync(document, cancellationToken)
                                            .ReceiveJson <DocumentSaveResponse>()
                                            .SendRequestAsync()
                                            .ConfigureAwait(false);

            document.ProcessSaveResponse(response);

            await UpdateAttachments(document, cancellationToken)
            .ConfigureAwait(false);

            return(document);
        }
        private async Task <HttpResponseMessage> SendAuthorizedHttpPostRequestAsync <TEvent>(IEnumerable <TEvent> events) where TEvent : class
        {
            IFlurlRequest authorizedRequest =
                TopicEndpoint.WithHeader(name: "aeg-sas-key", value: _authenticationKey);

            return(await authorizedRequest.PostJsonAsync(events));
        }
示例#25
0
        /// <inheritdoc />
        public async IAsyncEnumerable <ChangesFeedResponseResult <TSource> > GetContinuousChangesAsync(ChangesFeedOptions options, ChangesFeedFilter filter,
                                                                                                       [EnumeratorCancellation] CancellationToken cancellationToken)
        {
            var           infiniteTimeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
            IFlurlRequest request         = NewRequest()
                                            .WithTimeout(infiniteTimeout)
                                            .AppendPathSegment("_changes")
                                            .SetQueryParam("feed", "continuous");

            if (options != null)
            {
                request = request.ApplyQueryParametersOptions(options);
            }

            await using Stream stream = filter == null
                ? await request.GetStreamAsync(cancellationToken, HttpCompletionOption.ResponseHeadersRead)
                                        .ConfigureAwait(false)
                : await request.QueryContinuousWithFilterAsync <TSource>(_queryProvider, filter, cancellationToken)
                                        .ConfigureAwait(false);

            await foreach (var line in stream.ReadLinesAsync(cancellationToken))
            {
                if (string.IsNullOrEmpty(line))
                {
                    continue;
                }

                ChangesFeedResponseResult <TSource> result = JsonConvert.DeserializeObject <ChangesFeedResponseResult <TSource> >(line);
                yield return(result);
            }
        }
        /// <summary>
        /// Create new API service with specific route
        /// </summary>
        /// <param name="route">Specific route </param>
        public APIService(string route = "")
        {
            try
            {
#if  DEBUG
                var httpClientHandler = new HttpClientHandler
                {
                    ServerCertificateCustomValidationCallback = (message, cert, chain,
                                                                 errors) => true
                };
#endif

                var httpClient = new HttpClient(httpClientHandler)
                {
                    BaseAddress = new Uri(Device.RuntimePlatform == Device.Android
                        ? AppResources.ApiUrlAndroid
                        : AppResources.ApiUrl)
                };

                IFlurlClient flurlClient = new FlurlClient(httpClient);
                request = flurlClient.Request(route).AllowAnyHttpStatus();
                if (Auth.IsAuthenticated(setLoginPage: false))
                {
                    request.Headers.Add("Authorization", $"Bearer {Auth.AccessToken.ConvertToString()}");
                }
                BaseUrl = request.Url;
            }
#pragma warning disable 168
            catch (Exception ex)
#pragma warning restore 168
            {
                // ignored
            }
        }
示例#27
0
        /// <summary>
        /// Sends an asynchronous HTTP request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="httpMethod">HTTP method of the request</param>
        /// <param name="data">Contents of the request body.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation. Optional.</param>
        /// <param name="completionOption">The HttpCompletionOption used in the request. Optional.</param>
        /// <returns>
        /// A Task whose result is the received HttpResponseMessage.
        /// </returns>
        public static async Task <HttpResponseMessage> SendXmlAsync(this IFlurlRequest request, HttpMethod httpMethod, object data,
                                                                    CancellationToken cancellationToken = default(CancellationToken), HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead)
        {
            var content = new CapturedXmlContent(request.Settings.XmlSerializer().Serialize(data), request.GetMediaType());

            return(await request.SendAsync(httpMethod, content, cancellationToken, completionOption));
        }
        private static async Task <IList <JToken> > GetJsonTokensAsync(this IFlurlRequest request, CancellationToken cancellationToken = default, HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead)
        {
            var responseMessage = await request.SendAsync(HttpMethod.Get, null, cancellationToken, completionOption).ConfigureAwait(false);

            if (responseMessage == null)
            {
                return(default);
示例#29
0
        public static async Task <HttpResponseMessage> PostRequestAsync(this IFlurlRequest client, IRequest request, CancellationToken token = default(CancellationToken), bool isMultipart = false)
        {
            // Get all form keys from request
            var keys = request.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
                       .Where(prop => prop.GetCustomAttribute <FormIgnoreAttribute>() == null);

            // Get determination key for determine if the web call is a v2 call or not
            var  v2DetKey = keys.SingleOrDefault(prop => prop.GetCustomAttribute <V2DeterminationKeyAttribute>() != null);
            bool isV2     = v2DetKey != null && v2DetKey.GetValue(request) != null;

            if (isV2 && v2DetKey.GetCustomAttribute <V2DeterminationKeyAttribute>().IsByVersionNumber)
            {
                isV2 &= v2DetKey.GetValue(request).ToString() == "2.0";
            }

            // Get keys to process
            var keysToProcess = keys.Except(keys.Where(k => k.GetCustomAttribute <FormAttribute>()?.IsFor.Equals(isV2 ? VersionOption.V1 : VersionOption.V2) ?? false));

            // Check null for required keys
            foreach (var option in new List <VersionOption> {
                isV2?VersionOption.V2 : VersionOption.V1, VersionOption.All
            })
            {
                var keysToValidate = keysToProcess.Where(k => k.GetCustomAttribute <FormAttribute>()?.IsFor.Equals(option) ?? false);
                var invalidKeys    = keysToValidate.Where(k => (k.GetCustomAttribute <FormAttribute>()?.IsRequiredFor.HasFlag(option) ?? false) && k.GetValue(request) == null);
                if (invalidKeys.Any())
                {
                    throw new KeyRequiredException(invalidKeys.Select(k => k.Name).ToArray());
                }
            }

            Func <PropertyInfo, string> keyName = prop => prop.GetCustomAttribute <FormAttribute>()?.Name ?? prop.Name.ToLower();

            // Process keys to form
            var form = new Dictionary <string, string>();

            keysToProcess.Where(ok => ok.GetValue(request) != null)
            .ToList()
            .ForEach(ok =>
            {
                if (ok.GetValue(request) is IEnumerable <string> list)
                {
                    foreach (var item in list)
                    {
                        form.Add(keyName(ok), item);
                    }
                }
                else
                {
                    var objValue = ok.GetValue(request);
                    if (!(objValue is bool && ok.GetCustomAttribute <FormAttribute>().AddKeyOnlyIfBoolTrue&& !(bool)objValue))
                    {
                        form.Add(keyName(ok), ok.PropertyType.IsSimpleType() ?
                                 objValue.ToString() : JsonConvert.SerializeObject(ok.GetValue(request), SerializationHelper.SerializationSettings));
                    }
                }
            });
            // ConfigureAwait was missing...
            return(isMultipart ? await client.PostMultipartAsync(mp => mp.AddStringParts(form)).ConfigureAwait(false) : await client.PostUrlEncodedAsync(form, token).ConfigureAwait(false));
        }
示例#30
0
        /// <summary>
        /// This method is used to get latest release result of given release definition Id and branch name with descending order.
        /// Reference: https://docs.microsoft.com/en-us/rest/api/azure/devops/release/releases/list?view=azure-devops-rest-5.1
        /// </summary>
        /// <param name="definitionId">release definition Ids</param>
        /// <param name="branchName">github repository branch name</param>
        /// <returns>List of IoT Edge releases</returns>
        public async Task <List <IoTEdgeRelease> > GetReleasesAsync(ReleaseDefinitionId definitionId, string branchName, int top = 5)
        {
            ValidationUtil.ThrowIfNullOrWhiteSpace(branchName, nameof(branchName));
            ValidationUtil.ThrowIfNonPositive(top, nameof(top));

            // TODO: need to think about how to handle unexpected exception during REST API call
            string        requestPath        = string.Format(ReleasePathSegmentFormat, this.accessSetting.Organization, this.accessSetting.Project);
            IFlurlRequest latestBuildRequest = DevOpsAccessSetting.ReleaseManagementBaseUrl
                                               .AppendPathSegment(requestPath)
                                               .SetQueryParam("definitionId", definitionId.IdString())
                                               .SetQueryParam("queryOrder", "descending")
                                               .SetQueryParam("$expand", "environments")
                                               .SetQueryParam("$top", top)
                                               .SetQueryParam("api-version", "5.1")
                                               .SetQueryParam("sourceBranchFilter", branchName)
                                               .WithBasicAuth(string.Empty, this.accessSetting.PersonalAccessToken);

            string resultJson = await latestBuildRequest.GetStringAsync().ConfigureAwait(false);

            JObject result = JObject.Parse(resultJson);

            if (!result.ContainsKey("count") || (int)result["count"] <= 0)
            {
                return(new List <IoTEdgeRelease>());
            }

            VstsRelease[] releases = JsonConvert.DeserializeObject <VstsRelease[]>(result["value"].ToString());
            return(releases.Select(r => IoTEdgeRelease.Create(r, branchName)).ToList());
        }