From 643a97df7d76a605547c8f64f79dd4605ee83cc5 Mon Sep 17 00:00:00 2001 From: Victor Rojas Date: Fri, 27 May 2022 13:46:42 -0500 Subject: [PATCH 1/4] Add followRedirects bool to constructor, update http clients --- links/gql_http_link/lib/src/link.dart | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/links/gql_http_link/lib/src/link.dart b/links/gql_http_link/lib/src/link.dart index 74a4fcf9..94c40012 100644 --- a/links/gql_http_link/lib/src/link.dart +++ b/links/gql_http_link/lib/src/link.dart @@ -66,6 +66,9 @@ class HttpLink extends Link { /// Default HTTP headers final Map defaultHeaders; + /// set to `true` to follow redirects in request chain + final bool followRedirects; + /// set to `true` to use the HTTP `GET` method for queries (but not for mutations) final bool useGETForQueries; @@ -104,6 +107,7 @@ class HttpLink extends Link { this.serializer = const RequestSerializer(), this.parser = const ResponseParser(), this.httpResponseDecoder = _defaultHttpResponseDecoder, + this.followRedirects = false, }) : uri = Uri.parse(uri) { _httpClient = httpClient ?? http.Client(); } @@ -116,8 +120,9 @@ class HttpLink extends Link { final httpResponse = await _executeRequest(request); final response = await _parseHttpResponse(httpResponse); + final maxStatusCode = followRedirects ? 400 : 300; - if (httpResponse.statusCode >= 300 || + if (httpResponse.statusCode >= maxStatusCode || (response.data == null && response.errors == null)) { throw HttpLinkServerException( response: httpResponse, @@ -204,7 +209,9 @@ class HttpLink extends Link { _encodeAsUriParams, )(body), ), - )..headers.addAll(headers); + ) + ..headers.addAll(headers) + ..followRedirects = followRedirects; } final httpBody = _encodeAttempter( @@ -220,11 +227,13 @@ class HttpLink extends Link { return http.MultipartRequest("POST", uri) ..body = httpBody ..addAllFiles(fileMap) - ..headers.addAll(headers); + ..headers.addAll(headers) + ..followRedirects = followRedirects; } return http.Request("POST", uri) ..body = httpBody - ..headers.addAll(headers); + ..headers.addAll(headers) + ..followRedirects = followRedirects; } /// wrap an encoding transform in exception handling From 6542d5d0604eef927a81372edf57905f7b908591 Mon Sep 17 00:00:00 2001 From: Victor Rojas Date: Fri, 27 May 2022 16:17:34 -0500 Subject: [PATCH 2/4] Catch on ResponseFormatException --- links/gql_http_link/lib/src/link.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/links/gql_http_link/lib/src/link.dart b/links/gql_http_link/lib/src/link.dart index 94c40012..5755fb4f 100644 --- a/links/gql_http_link/lib/src/link.dart +++ b/links/gql_http_link/lib/src/link.dart @@ -160,6 +160,10 @@ class HttpLink extends Link { try { final responseBody = await httpResponseDecoder(httpResponse); return parser.parseResponse(responseBody!); + } on ResponseFormatException { + if (!followRedirects && (httpResponse.statusCode == 301 || httpResponse.statusCode == 302)) { + rethrow; + } } catch (e) { throw HttpLinkParserException( originalException: e, From 2f899ad8ba93521990ba6ccb9d565268b35b9d3b Mon Sep 17 00:00:00 2001 From: Victor Rojas Date: Fri, 27 May 2022 17:55:28 -0500 Subject: [PATCH 3/4] Return empty response for non-redirect status code --- links/gql_http_link/lib/src/link.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/links/gql_http_link/lib/src/link.dart b/links/gql_http_link/lib/src/link.dart index 5755fb4f..9a3bd7db 100644 --- a/links/gql_http_link/lib/src/link.dart +++ b/links/gql_http_link/lib/src/link.dart @@ -164,6 +164,7 @@ class HttpLink extends Link { if (!followRedirects && (httpResponse.statusCode == 301 || httpResponse.statusCode == 302)) { rethrow; } + return Response(response: const {}); } catch (e) { throw HttpLinkParserException( originalException: e, From aee31f71ab921cd92be1ceaadb22c132c52a6994 Mon Sep 17 00:00:00 2001 From: Victor Rojas Date: Fri, 27 May 2022 18:21:46 -0500 Subject: [PATCH 4/4] Update followRedirects default Update ResponseFormatException to FormatException catch Update returned Response object from FormatException catch block Add comments --- links/gql_http_link/lib/src/link.dart | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/links/gql_http_link/lib/src/link.dart b/links/gql_http_link/lib/src/link.dart index 9a3bd7db..e95457d1 100644 --- a/links/gql_http_link/lib/src/link.dart +++ b/links/gql_http_link/lib/src/link.dart @@ -66,7 +66,7 @@ class HttpLink extends Link { /// Default HTTP headers final Map defaultHeaders; - /// set to `true` to follow redirects in request chain + /// set to `false` to throw exceptions on redirects in request chain, defaults to true final bool followRedirects; /// set to `true` to use the HTTP `GET` method for queries (but not for mutations) @@ -107,7 +107,7 @@ class HttpLink extends Link { this.serializer = const RequestSerializer(), this.parser = const ResponseParser(), this.httpResponseDecoder = _defaultHttpResponseDecoder, - this.followRedirects = false, + this.followRedirects = true, }) : uri = Uri.parse(uri) { _httpClient = httpClient ?? http.Client(); } @@ -160,11 +160,17 @@ class HttpLink extends Link { try { final responseBody = await httpResponseDecoder(httpResponse); return parser.parseResponse(responseBody!); - } on ResponseFormatException { - if (!followRedirects && (httpResponse.statusCode == 301 || httpResponse.statusCode == 302)) { + } on FormatException { + if (!followRedirects && + (httpResponse.statusCode == 301 || httpResponse.statusCode == 302)) { rethrow; } - return Response(response: const {}); + + // Empty data object sent to bypass HttpLinkServerException in subsequent request() invocation + return Response( + data: const {}, + response: const {}, + ); } catch (e) { throw HttpLinkParserException( originalException: e,