예제 #1
0
 public RestClient(IRestTransport transport,
                   string baseUrl        = "",
                   IRequestSigner signer = null,
                   ReadOnlyHttpHeaders defaultHeaders = null,
                   ReadOnlyHttpCookies defaultCookies = null)
 {
     Transport      = transport;
     BaseUrl        = baseUrl;
     Signer         = signer ?? new UnitRequestSigner();
     DefaultHeaders = defaultHeaders ?? new ReadOnlyDictionary <string, string>(NoHeaders);
     DefaultCookies = defaultCookies ?? new ReadOnlyDictionary <string, string>(NoCookies);
 }
예제 #2
0
 public ReadOnlyHttpCookies Sign(Uri uri, HttpMethod method, ReadOnlyHttpCookies headers, HttpContent content)
 {
     return(headers);
 }
예제 #3
0
        public void MakeRequest <TContent>(Uri uri,
                                           HttpMethod method,
                                           HttpContent content,
                                           ReadOnlyHttpHeaders headers,
                                           ReadOnlyHttpCookies cookies,
                                           int maxRedirectCount,
                                           RestResponse <TContent> allocatedResult)
        {
            allocatedResult.RequestUri = uri;

            try
            {
                // TODO: Dispose this
                var request = new HttpRequestMessage(method, uri)
                {
                    Content = content
                };

                // Set headers
                foreach (var h in headers)
                {
                    request.Headers.TryAddWithoutValidation(h.Key, h.Value);
                }

                // Set cookies
                var cookieHeaderValue = string.Join("; ", cookies.Select(x => $"{x.Key}={x.Value}"));
                request.Headers.TryAddWithoutValidation("Cookie", cookieHeaderValue);

                // Don't use .Result here but rather .GetAwaiter().GetResult()
                // It produces a nicer call stack and no AggregateException nonsense
                // https://stackoverflow.com/a/36427080/362938
                // TODO: Dispose this?
                var response = _http.SendAsync(request).GetAwaiter().GetResult();

                var responseCookies = ParseResponseCookies(response, uri);
                var allCookies      = cookies.MergeCopy(responseCookies);

                // Redirect if still possible (HTTP Status 3XX)
                if ((int)response.StatusCode / 100 == 3 && maxRedirectCount > 0)
                {
                    // Uri ctor should take care of both absolute and relative redirects. There have
                    // been problems with Android in the past.
                    // (see https://github.com/detunized/password-manager-access/issues/21)
                    var newUri = new Uri(uri, response.Headers.Location);

                    // Redirect always does a GET with no content
                    MakeRequest(newUri,
                                HttpMethod.Get,
                                null,
                                headers,
                                allCookies,
                                maxRedirectCount - 1,
                                allocatedResult);
                    return;
                }

                // Set up the result
                allocatedResult.StatusCode = response.StatusCode;
                allocatedResult.Cookies    = allCookies;

                switch (allocatedResult)
                {
                case RestResponse <string> text:
                    text.Content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                    break;

                case RestResponse <byte[]> binary:
                    binary.Content = response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();
                    break;

                default:
                    throw new InternalErrorException($"Unsupported content type {typeof(TContent)}");
                }

                // TODO: Here we're ignoring possible duplicated headers. See if we need to preserve those!
                allocatedResult.Headers = response.Headers.ToDictionary(x => x.Key,
                                                                        x => x.Value.FirstOrDefault() ?? "");
            }
            catch (HttpRequestException e)
            {
                allocatedResult.Error = e;
            }
        }