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); }
public ReadOnlyHttpCookies Sign(Uri uri, HttpMethod method, ReadOnlyHttpCookies headers, HttpContent content) { return(headers); }
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; } }