/** * {@inheritDoc} */ @Override public void filter(final ClientRequestContext requestContext, final ClientResponseContext responseContext) throws IOException { final Object requestId = requestContext.getProperty(LOGGING_ID_PROPERTY); final long id = requestId != null ? (Long) requestId : _id.incrementAndGet(); StringBuilder b = (StringBuilder) requestContext.getProperty(LOGGER_BUFFER_PROPERTY); if (b == null) { b = new StringBuilder(); requestContext.setProperty(LOGGER_BUFFER_PROPERTY, b); } printResponseLine(b, "Client response received", id, responseContext.getStatus()); printPrefixedHeaders(b, id, RESPONSE_PREFIX, responseContext.getHeaders()); if (printEntity && responseContext.hasEntity() && isSupportPrintType(responseContext.getMediaType())) { responseContext.setEntityStream(logInboundEntity(b, responseContext.getEntityStream(), MessageUtils.getCharset(responseContext.getMediaType()))); } log(b); }
@Override public void filter( final ClientRequestContext requestContext, final ClientResponseContext responseContext ) throws IOException { if ( Response.Status.UNAUTHORIZED.getStatusCode() == responseContext.getStatus() ) { final List<Object> headers = requestContext.getHeaders().get( HttpHeaders.AUTHORIZATION ); if ( null == headers ) { return; } for ( final Object header : headers ) { if ( header instanceof String ) { final String headerValue = (String) header; if ( headerValue.startsWith( AUTH_HEADER_PREFIX ) ) { final String token = headerValue.substring( AUTH_HEADER_PREFIX.length() ); _keycloak.invalidate( token ); } } } } }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { logger.info("getAllowedMethods : " + responseContext.getAllowedMethods()); logger.info("getCookies : " + responseContext.getCookies()); logger.info("getDate : " + responseContext.getDate()); logger.info("getEntityStream : " + responseContext.getEntityStream()); logger.info("getEntityTag : " + responseContext.getEntityTag()); logger.info("getHeaders : " + responseContext.getHeaders()); logger.info("getLanguage : " + responseContext.getLanguage()); logger.info("getLastModified : " + responseContext.getLastModified()); logger.info("getLength : " + responseContext.getLength()); logger.info("getLinks : " + responseContext.getLinks()); logger.info("getLocation : " + responseContext.getLocation()); logger.info("getMediaType : " + responseContext.getMediaType()); logger.info("getStatus : " + responseContext.getStatus()); logger.info("getStatusInfo : " + responseContext.getStatusInfo()); responseContext.getHeaders().putSingle(CONTENT_TYPE_STRING, requestContext.getHeaderString(CONTENT_TYPE_STRING)); }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { logger.info("getAllowedMethods : " + responseContext.getAllowedMethods()); logger.info("getCookies : " + responseContext.getCookies()); logger.info("getDate : " + responseContext.getDate()); logger.info("getEntityStream : " + responseContext.getEntityStream()); logger.info("getEntityTag : " + responseContext.getEntityTag()); logger.info("getHeaders : " + responseContext.getHeaders()); logger.info("getLanguage : " + responseContext.getLanguage()); logger.info("getLastModified : " + responseContext.getLastModified()); logger.info("getLength : " + responseContext.getLength()); logger.info("getLinks : " + responseContext.getLinks()); logger.info("getLocation : " + responseContext.getLocation()); logger.info("getMediaType : " + responseContext.getMediaType()); logger.info("getStatus : " + responseContext.getStatus()); logger.info("getStatusInfo : " + responseContext.getStatusInfo()); }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { System.out.println("Response = " + requestContext + " " + responseContext); Long start = concurrentRequests.get(requestContext); concurrentRequests.remove(requestContext); long duration = (System.nanoTime() - start); System.out.println("Duration: " + duration); URI uri = requestContext.getUri(); String ipv4 = extractIpAddress(uri); System.out.println("ipv4 = " + ipv4); String serviceName = extractServiceName(uri); System.out.println("serviceName = " + serviceName); String spanName = uri.getPath(); System.out.println("spanName = " + spanName); String traceId = extractTraceId(requestContext).orElse("--no spanid--"); Boolean spanExists = Optional.ofNullable(requestContext.getProperty(SPAN_EXISTED)). map((o) -> (boolean) o). orElse(false); if (spanExists) { this.tracEE.saveChildSpan(traceId, spanName, serviceName, ipv4, duration); } else { this.tracEE.saveParentSpan(spanName, serviceName, ipv4, duration); } }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { // for non-200 response, deal with the custom error messages if (! Response.Status.Family.SUCCESSFUL.equals(responseContext.getStatusInfo().getFamily())) { MetaData metaData = MetaData.builder() .httpRequestMetaData(getRequestMetaData(requestContext)) .httpResponseMetaData(getResponseMetaData(responseContext)) .gotAnswer(true) .targetName(serviceDefinition.getName()) .build(); if (Response.Status.NOT_FOUND.getStatusCode() == responseContext.getStatus()) { throw new ExternalResourceNotFoundException(metaData); } throw new ExternalResourceException(metaData); } }
@Override public void filter(final ClientRequestContext clientRequestContext, final ClientResponseContext clientResponseContext) throws IOException { this.logger.debug("HTTP {} Response from {}: {} {}.", clientRequestContext.getMethod(), clientRequestContext.getUri(), clientResponseContext.getStatus(), clientResponseContext.getStatusInfo().getReasonPhrase()); final String responseEntity = getResponseEntity(clientResponseContext); if (clientResponseContext.getStatus() == 400) { if (responseEntity.contains("invalid_token")) { // Zonky is dumb and throws 400 when it should throw 401 clientResponseContext.setStatus(401); } } responseHeaders = clientResponseContext.getHeaders().entrySet().stream() .filter(e -> e.getValue().size() > 0) .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().get(0))); }
@Test public void response() throws IOException { final String key = UUID.randomUUID().toString(); final String key2 = UUID.randomUUID().toString(); final String value = UUID.randomUUID().toString(); final MultivaluedMap<String, String> map = new MultivaluedMapImpl<>(); map.add(key, value); map.addAll(key2, Collections.emptyList()); final ClientRequestContext ctx = Mockito.mock(ClientRequestContext.class); final ClientResponseContext ctx2 = Mockito.mock(ClientResponseContext.class); Mockito.when(ctx2.getHeaders()).thenReturn(map); Mockito.when(ctx2.getStatusInfo()).thenReturn(Mockito.mock(Response.StatusType.class)); final RoboZonkyFilter filter = new RoboZonkyFilter(); filter.filter(ctx, ctx2); SoftAssertions.assertSoftly(softly -> { softly.assertThat(filter.getLastResponseHeader(key)).contains(value); softly.assertThat(filter.getLastResponseHeader(key2)).isEmpty(); }); }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { if (LOG.isTraceEnabled()) { LOG.trace("Response status: {} {}", responseContext.getStatus(), responseContext.getStatusInfo().toString()); LOG.trace("Response headers: {}", responseContext.getHeaders()); InputStream stream = responseContext.getEntityStream(); ByteArrayOutputStream result = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length; while ((length = stream.read(buffer)) != -1) { result.write(buffer, 0, length); } stream.close(); LOG.trace("Response body: {}", result.toString("UTF-8")); responseContext.setEntityStream(new ByteArrayInputStream(result.toByteArray())); } }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { SpanWrapper spanWrapper = CastUtils .cast(requestContext.getProperty(PROPERTY_NAME), SpanWrapper.class); if (spanWrapper != null && !spanWrapper.isFinished()) { log.finest("Finishing client span"); if (spanDecorators != null) { for (ClientSpanDecorator decorator: spanDecorators) { decorator.decorateResponse(responseContext, spanWrapper.get()); } } spanWrapper.finish(); } }
@Override public void filter(ClientRequestContext request, ClientResponseContext response) throws IOException { StringBuilder debugMsgBuilder = new StringBuilder(); debugMsgBuilder.append("ClientRequest: ").append(request.getMethod()).append("\t"); debugMsgBuilder.append(request.getUri().toASCIIString()).append("\t"); appendObjectHeaders(debugMsgBuilder, "> ", request.getHeaders().entrySet()); appendStringHeaders(debugMsgBuilder, "< ", response.getHeaders().entrySet()); debugMsgBuilder.append(response.getStatusInfo()).append(", length=").append(response.getLength()).append(" "); Long requestStartTime = (Long) request.getProperty(PROPERTY_NANOS); if (requestStartTime != null) { debugMsgBuilder .append((System.nanoTime() - requestStartTime) / MILLISECONDS_PER_NANOSECOND) .append(" ms\t"); } LOG.debug(debugMsgBuilder.toString()); RequestLog.stopTiming(CLIENT_TOTAL_TIMER); }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { if (responseContext.getStatus() != Response.Status.OK.getStatusCode() && responseContext.hasEntity()) { try { final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); final Error error = (Error) unmarshaller.unmarshal(responseContext.getEntityStream()); final Response.ResponseBuilder builder = Response.status(responseContext.getStatusInfo()); builder.entity(error); // copy response headers for (Map.Entry<String, List<String>> header : responseContext.getHeaders().entrySet()) { builder.header(header.getKey(), header.getValue()); } throw new LinkedInException(error, builder.build()); } catch (JAXBException e) { // log and ignore LOG.warn("Unable to parse LinkedIn error: " + e.getMessage(), e); } } }
/** * Intercepts the client response flow and extract response information * to be published to the DAS server for tracing. */ @Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { long time = new Date().getTime(); TraceEvent traceEvent = (TraceEvent) requestContext.getProperty(TRACE_EVENT_ATTRIBUTE); if (traceEvent != null) { TraceEvent endTraceEvent = new TraceEvent( TracingConstants.CLIENT_TRACE_END, traceEvent.getTraceId(), traceEvent.getOriginId(), time ); endTraceEvent.setStatusCode(responseContext.getStatus()); TracingUtil.pushToDAS(endTraceEvent, dasUrl); } }
@Override public void filter(final ClientRequestContext requestContext, final ClientResponseContext responseContext) { try { // For non-200 response, log the custom error message. if (responseContext.getStatus() != Response.Status.OK.getStatusCode()) { if (responseContext.hasEntity()) { String error = CharStreams.toString( new InputStreamReader(responseContext.getEntityStream(), Charsets.UTF_8)); LOG.severe(error); System.err.println(error); } } } catch (Exception e) { // Silently pass. We don't want anything to fail because of this filter. LOG.warning("Error while checking response code: " + e.getMessage()); } }
private void stripResponse(ClientResponseContext responseContext) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); InputStream in = responseContext.getEntityStream(); final StringBuilder b = new StringBuilder(); try { if (in.available() > 0) { ReaderWriter.writeTo(in, out); StringBuffer sbuf = new StringBuffer(new String(out.toByteArray())); if (sbuf.indexOf(ALLOW_ILLEGAL_RESOURCE_CALL_PREFIX) == 0) { if (log.isDebugEnabled()) { log.debug("Stripping "+ALLOW_ILLEGAL_RESOURCE_CALL_PREFIX); } responseContext.setEntityStream(new ByteArrayInputStream(sbuf.substring(ALLOW_ILLEGAL_RESOURCE_CALL_PREFIX.length()).getBytes())); } else { responseContext.setEntityStream(new ByteArrayInputStream(out.toByteArray())); } // end if } // end if } catch (IOException ex) { throw new ContainerException(ex); } // end try/catch }
private void logResponse(ClientResponseContext responseContext) throws IOException { String responseBody = null; ByteArrayOutputStream out = new ByteArrayOutputStream(); InputStream in = responseContext.getEntityStream(); final StringBuilder b = new StringBuilder(); try { if (in.available() > 0) { ReaderWriter.writeTo(in, out); responseContext.setEntityStream(new ByteArrayInputStream(out.toByteArray())); responseBody = new String(out.toByteArray()); } // end if } catch (IOException ex) { throw new ContainerException(ex); } // end try/catch responseBody = (responseBody == null) ? "" : "\n"+responseBody; log.debug("\nClient Response:\nStatus: "+responseContext.getStatus()+ responseBody); }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { int status = responseContext.getStatus(); switch (status) { case 200: case 201: case 204: return; case 304: throw new NotModifiedException(getBodyAsMessage(responseContext)); case 400: throw new BadRequestException(getBodyAsMessage(responseContext)); case 401: throw new UnauthorizedException(getBodyAsMessage(responseContext)); case 404: throw new NotFoundException(getBodyAsMessage(responseContext)); case 406: throw new NotAcceptableException(getBodyAsMessage(responseContext)); case 409: throw new ConflictException(getBodyAsMessage(responseContext)); case 500: throw new InternalServerErrorException(getBodyAsMessage(responseContext)); default: throw new DockerException(getBodyAsMessage(responseContext), status); } }
public RestException build(final RestFailure failure, final ClientResponseContext responseContext) { final Constructor<RestException> constructor = getExceptionConstructor(failure); final RestException exception; if (constructor != null) { exception = buildKnown(constructor, failure); } else { exception = buildUnknown(failure); } // Copy the information from the failure+response to the newly-built exception exception.setFailure(failure); exception.setCausedByRemote(true); exception.setResponseContext(responseContext); exception.setHttpCode(responseContext.getStatus()); exception.setErrorCode(failure.errorCode); return exception; }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { // TODO - add other non-error responses here if (responseContext.getStatus() != Response.Status.OK.getStatusCode() && responseContext.getStatus() != Response.Status.CREATED.getStatusCode()) { if (responseContext.hasEntity()) { // get the "real" error message Error error = _MAPPER.readValue(responseContext.getEntityStream(), Error.class); Response.Status status = Response.Status.fromStatusCode(responseContext.getStatus()); MaxinetWebException maxinetException; switch (status) { case INTERNAL_SERVER_ERROR: maxinetException = new MaxinetInternalException(error.getMessage(), responseContext.getStatus()); break; case BAD_REQUEST: maxinetException = new MaxinetClientException(error.getMessage(), responseContext.getStatus()); break; default: maxinetException = new MaxinetWebException(error.getMessage(), responseContext.getStatus()); } throw maxinetException; } } }
@Override public void filter(ClientRequestContext request, ClientResponseContext response) throws IOException { logResponse(request, response); if (!isSuccess(response)) { logResponseBody(response); throw new NewRelicClientException(request, response); } }
private void logResponse(ClientRequestContext request, ClientResponseContext response) { LOG.info("{} {}: {} {}", request.getMethod(), request.getUri(), response.getStatus(), response.getStatusInfo().getReasonPhrase()); }
private void logResponseBody(ClientResponseContext response) { try { LOG.info("{}", IOUtils.toString(response.getEntityStream(), StandardCharsets.UTF_8)); } catch (IOException e) { LOG.error("Failed to log response body", e); } }
private static String formatMessage(ClientRequestContext request, ClientResponseContext response) { String method = request.getMethod(); String url = request.getUri().toString(); int statusCode = response.getStatus(); String statusText = response.getStatusInfo().getReasonPhrase(); return String.format("%s %s: %d %s", method, url, statusCode, statusText); }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { try { Span span = (Span) requestContext.getProperty(CLIENT_SPAN_CONTEXT_KEY); if (span != null) { Tags.HTTP_STATUS.set(span, responseContext.getStatus()); span.finish(); } } catch (Exception e) { LOGGER.error("Client Tracing Filter failed:", e); } }
@Test public void test() throws Exception { TracerTestImpl tracer = new TracerTestImpl(); TraceClientFilter tcf = new TraceClientFilter(); tcf.setTracer(tracer); MultivaluedMap<String, Object> headerAccess = new MultivaluedHashMap<>(); ClientRequestContext requestContext = Mockito.mock(ClientRequestContext.class); Mockito.when(requestContext.getUri()).thenReturn(new URI("https://example.com:7110/some/path")); Mockito.when(requestContext.getMethod()).thenReturn("GET"); Mockito.when(requestContext.getHeaders()).thenReturn(headerAccess); Mockito.when(requestContext.getEntityAnnotations()).thenReturn(new Annotation[]{}); tcf.filter(requestContext); Assert.assertNotNull(tracer.getCurrentSpan()); ClientResponseContext responseContext = Mockito.mock(ClientResponseContext.class); tcf.filter(requestContext, responseContext); Assert.assertNull(tracer.getCurrentSpan()); Span span = tracer.getCapturedSpan(); Assert.assertEquals("service", span.getService()); Assert.assertEquals("example.com:7110", span.getResource()); Assert.assertEquals("GET /some/path", span.getOperation()); Assert.assertEquals(Long.parseUnsignedLong((String)headerAccess.getFirst(TracerImpl.TRACE_ID)), span.getTraceId()); Assert.assertEquals(Long.parseUnsignedLong((String)headerAccess.getFirst(TracerImpl.SPAN_ID)), span.getSpanId()); }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { Long totalMillis = null; Long startNanos = (Long) requestContext.getProperty(PROPERTYNAME); if (startNanos != null) { long totalNanos = System.nanoTime() - startNanos; totalMillis = totalNanos / 1_000_000; } log.info(getCallSignature(requestContext) + " response: " + responseContext.getStatus() + ", millis: " + totalMillis); }
private HttpResponseMetaData getResponseMetaData(ClientResponseContext responseContext) throws IOException { Map<String, String> headers = FormatUtil.MultiMapAsStringMap(responseContext.getHeaders()); HttpResponseMetaData.HttpResponseMetaDataBuilder builder = HttpResponseMetaData.builder() .status(responseContext.getStatus()) .headers(headers); if (responseContext.hasEntity()) { String body; // setUp the "real" error message try (BufferedReader buffer = new BufferedReader(new InputStreamReader(responseContext.getEntityStream(), "UTF-8"))) { body = buffer.lines().collect(Collectors.joining("\n")); } try { ProblemResponse problem = mapper.readValue(body, ProblemResponse.class); if (problemWasParsed(problem)) { builder.problemResponse(problem) .incidentReferenceId(problem.incidentReferenceId); } } catch (JsonParseException | JsonMappingException e) { //ignore } if (builder.build().problemResponse == null) { builder.response(body); } } return builder.build(); }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { if (logger.isDebugEnabled()) { logger.debug("Response status: " + responseContext.getStatus() + " - " + responseContext.getStatusInfo()); } if (logger.isTraceEnabled() && responseContext.hasEntity()) { logResponseBody(responseContext); } }
private void logResponseBody(ClientResponseContext responseContext) throws IOException { Charset charset = MessageUtils.getCharset(responseContext.getMediaType()); InputStream entityStream = responseContext.getEntityStream(); byte[] bodyBytes = readInputStreamBytes(entityStream); responseContext.setEntityStream(new ByteArrayInputStream(bodyBytes)); logger.trace("Response body: " + new String(bodyBytes, charset)); }
private static boolean shouldLogEntity(final ClientResponseContext responseCtx) { if (!responseCtx.hasEntity()) { return false; } else if (responseCtx.getStatus() < 400) { return Settings.INSTANCE.isDebugHttpResponseLoggingEnabled(); } else { return true; } }
private String getResponseEntity(final ClientResponseContext clientResponseContext) throws IOException { if (shouldLogEntity(clientResponseContext)) { final InterceptingInputStream s = new InterceptingInputStream(clientResponseContext.getEntityStream()); clientResponseContext.setEntityStream(s); logger.debug("Response body is: {}", s.getContents()); return s.getContents(); } else { return ""; } }
@Test public void changes400to401() throws IOException { final int expectedCode = 400; final ClientRequestContext ctx = Mockito.mock(ClientRequestContext.class); final ClientResponseContext ctx2 = Mockito.mock(ClientResponseContext.class); final ZonkyApiToken token = new ZonkyApiToken("", "", 299); Mockito.when(ctx2.hasEntity()).thenReturn(true); Mockito.when(ctx2.getHeaders()).thenReturn(new MultivaluedMapImpl<>()); Mockito.when(ctx2.getEntityStream()).thenReturn(c(token)); Mockito.when(ctx2.getStatusInfo()).thenReturn(Response.Status.fromStatusCode(expectedCode)); Mockito.when(ctx2.getStatus()).thenReturn(expectedCode); final RoboZonkyFilter filter = new AuthenticatedFilter(token); filter.filter(ctx, ctx2); Mockito.verify(ctx2, Mockito.times(1)).setStatus(401); }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) { Timer.Context requestTimerContext = (Timer.Context) requestContext.getProperty(TIMER_PROPERTY); // TODO: this timing does not take into account reading response // content... May need to add additional interceptor for that. long timeNanos = requestTimerContext.stop(); LOGGER.info("Client request finished. Status: {}, time: {} ms.", responseContext.getStatus(), timeNanos / 1000000); }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { try { handler.handle(new ClientResponseContextAdapter(responseContext), (RequestRecord) requestContext .getProperty(REQ_METRICS_KEY)); } catch (Exception ex) { LoggerFactory.getLogger(RequestMetricsClientResponseFilter.class).error("Can't handle client response", ex); } }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { boolean needDecrypt = AuthenticationVariable.getAuthenticationVariable().isCrypt(); URI uriInfo = requestContext.getUri(); String path = uriInfo.getPath(); boolean docRequest = path.endsWith("/swagger"); if (needDecrypt && !(docRequest && BaseConfiguration.IS_DEBUG)) { InputStream entityStream = responseContext.getEntityStream(); BufferedReader br = new BufferedReader(new InputStreamReader(entityStream)); String line = ""; StringBuilder sb = new StringBuilder(); while ((line = br.readLine()) != null) { sb.append(line); } String context = sb.toString(); String key = AuthenticationVariable.getAuthenticationVariable().getKey(); Assert.notNullString(key, "鉴权秘钥获取失败!", HttpStatus.SC_UNAUTHORIZED, JahhanErrorCode.NO_AUTHORITY); context = aesCrypto.decrypt(context, key); ByteArrayOutputStream out = new ByteArrayOutputStream(); try { out.write(context.getBytes()); ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); responseContext.setEntityStream(in); } catch (Exception e) { JahhanException.throwException(JahhanErrorCode.UNKNOW_ERROR, "未知错误", e); } finally { out.close(); } } }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { long elapsed = timer.get().elapsed(TimeUnit.MILLISECONDS); responseContext.getHeaders().add(HEADER_REQUEST_ID, requestId.get()); logger.info(format("[%s] - %s to %s ended - total time %dms", requestId.get(), requestContext.getMethod(), requestContext.getUri(), elapsed)); requestId.remove(); timer.get().stop(); timer.remove(); }
@Override public void filter(@Nonnull ClientRequestContext requestContext, @Nonnull ClientResponseContext responseContext) throws TemporaryAllow, TemporaryDisallow { final Response.StatusType statusInfo = responseContext.getStatusInfo(); handleStatusCode(statusInfo); handleStatus(statusInfo); handleFamily(statusInfo); }
@Override public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { level.log(logger, "Response: [{} {}] {} {}", requestContext.getMethod(), requestContext.getUri(), responseContext.getStatusInfo(), responseContext.getHeaders()); }
@Override public void filter(@Nonnull ClientRequestContext requestContext, @Nonnull ClientResponseContext responseContext) throws IOException { if (isValidRedirect(requestContext, responseContext)) { final URI location = getAbsoluteRedirectLocation(requestContext, responseContext); if (isRedirectWithinLimits(requestContext, location)) { followRedirect(requestContext, responseContext, location); } } }
private boolean isValidRedirect(ClientRequestContext requestContext, ClientResponseContext responseContext) { if (responseContext.getStatusInfo().getFamily() != Response.Status.Family.REDIRECTION) { log.debug("No redirect to follow:", requestContext.getUri()); return false; } if (responseContext.getLocation() == null) { log.warn("Missing redirect location in response for: {}", requestContext.getUri()); return false; } return true; }