Add Remote Address to WebGraphQlRequest
This commit makes available the client remote address to various GraphQL request implementations. Closes gh-945
This commit is contained in:
@@ -78,7 +78,7 @@ final class WebGraphQlHandlerGraphQlTransport extends AbstractDirectGraphQlTrans
|
||||
protected Mono<ExecutionGraphQlResponse> executeInternal(ExecutionGraphQlRequest executionRequest) {
|
||||
|
||||
WebGraphQlRequest request = new WebGraphQlRequest(
|
||||
this.url, this.headers, null, Collections.emptyMap(), executionRequest,
|
||||
this.url, this.headers, null, null, Collections.emptyMap(), executionRequest,
|
||||
idGenerator.generateId().toString(), null);
|
||||
|
||||
return this.graphQlHandler.handleRequest(request).cast(ExecutionGraphQlResponse.class);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.graphql.server;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
@@ -58,8 +59,51 @@ public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements
|
||||
|
||||
private final MultiValueMap<String, HttpCookie> cookies;
|
||||
|
||||
@Nullable
|
||||
private final InetSocketAddress remoteAddress;
|
||||
|
||||
private final Map<String, Object> attributes;
|
||||
|
||||
/**
|
||||
* Create an instance.
|
||||
* @param uri the URL for the HTTP request or WebSocket handshake
|
||||
* @param headers the HTTP request headers
|
||||
* @param cookies the HTTP request cookies
|
||||
* @param remoteAddress the HTTP client remote address
|
||||
* @param attributes request attributes
|
||||
* @param body the deserialized content of the GraphQL request
|
||||
* @param id an identifier for the GraphQL request
|
||||
* @param locale the locale from the HTTP request, if any
|
||||
* @since 1.3.0
|
||||
*/
|
||||
public WebGraphQlRequest(URI uri, HttpHeaders headers, @Nullable MultiValueMap<String, HttpCookie> cookies,
|
||||
@Nullable InetSocketAddress remoteAddress, Map<String, Object> attributes,
|
||||
GraphQlRequest body, String id, @Nullable Locale locale) {
|
||||
this(uri, headers, cookies, remoteAddress, attributes, body.getDocument(),
|
||||
body.getOperationName(), body.getVariables(), body.getExtensions(), id, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of {@link #WebGraphQlRequest(URI, HttpHeaders, MultiValueMap, Map, GraphQlRequest, String, Locale)}
|
||||
* with a Map for the request body.
|
||||
* @param uri the URL for the HTTP request or WebSocket handshake
|
||||
* @param headers the HTTP request headers
|
||||
* @param cookies the HTTP request cookies
|
||||
* @param remoteAddress the HTTP client remote address
|
||||
* @param attributes request attributes
|
||||
* @param body the deserialized content of the GraphQL request
|
||||
* @param id an identifier for the GraphQL request
|
||||
* @param locale the locale from the HTTP request, if any
|
||||
* @since 1.3.0
|
||||
*/
|
||||
public WebGraphQlRequest(
|
||||
URI uri, HttpHeaders headers, @Nullable MultiValueMap<String, HttpCookie> cookies,
|
||||
@Nullable InetSocketAddress remoteAddress, Map<String, Object> attributes,
|
||||
Map<String, Object> body, String id, @Nullable Locale locale) {
|
||||
|
||||
this(uri, headers, cookies, remoteAddress, attributes, getQuery(body), getOperation(body),
|
||||
getMap(VARIABLES_KEY, body), getMap(EXTENSIONS_KEY, body), id, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance.
|
||||
@@ -71,12 +115,14 @@ public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements
|
||||
* @param id an identifier for the GraphQL request
|
||||
* @param locale the locale from the HTTP request, if any
|
||||
* @since 1.2.5
|
||||
* @deprecated since 1.3.0 in favor {@link #WebGraphQlRequest(URI, HttpHeaders, MultiValueMap, InetSocketAddress, Map, Map, String, Locale)}
|
||||
*/
|
||||
@Deprecated(since = "1.3.0", forRemoval = true)
|
||||
public WebGraphQlRequest(
|
||||
URI uri, HttpHeaders headers, @Nullable MultiValueMap<String, HttpCookie> cookies,
|
||||
Map<String, Object> attributes, GraphQlRequest body, String id, @Nullable Locale locale) {
|
||||
|
||||
this(uri, headers, cookies, attributes, body.getDocument(),
|
||||
this(uri, headers, cookies, null, attributes, body.getDocument(),
|
||||
body.getOperationName(), body.getVariables(), body.getExtensions(), id, locale);
|
||||
}
|
||||
|
||||
@@ -91,12 +137,14 @@ public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements
|
||||
* @param id an identifier for the GraphQL request
|
||||
* @param locale the locale from the HTTP request, if any
|
||||
* @since 1.1.3
|
||||
* @deprecated since 1.3.0 in favor {@link #WebGraphQlRequest(URI, HttpHeaders, MultiValueMap, InetSocketAddress, Map, Map, String, Locale)}
|
||||
*/
|
||||
@Deprecated(since = "1.3.0", forRemoval = true)
|
||||
public WebGraphQlRequest(
|
||||
URI uri, HttpHeaders headers, @Nullable MultiValueMap<String, HttpCookie> cookies,
|
||||
Map<String, Object> attributes, Map<String, Object> body, String id, @Nullable Locale locale) {
|
||||
|
||||
this(uri, headers, cookies, attributes, getQuery(body), getOperation(body),
|
||||
this(uri, headers, cookies, null, attributes, getQuery(body), getOperation(body),
|
||||
getMap(VARIABLES_KEY, body), getMap(EXTENSIONS_KEY, body), id, locale);
|
||||
}
|
||||
|
||||
@@ -127,24 +175,10 @@ public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements
|
||||
return (Map<String, Object>) value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance.
|
||||
* @param uri the URL for the HTTP request or WebSocket handshake
|
||||
* @param headers the HTTP request headers
|
||||
* @param body the deserialized content of the GraphQL request
|
||||
* @param id an identifier for the GraphQL request
|
||||
* @param locale the locale from the HTTP request, if any
|
||||
* @deprecated as of 1.1.3 in favor of
|
||||
* {@link #WebGraphQlRequest(URI, HttpHeaders, MultiValueMap, Map, GraphQlRequest, String, Locale)}
|
||||
*/
|
||||
@Deprecated(since = "1.1.3", forRemoval = true)
|
||||
public WebGraphQlRequest(URI uri, HttpHeaders headers, Map<String, Object> body, String id, @Nullable Locale locale) {
|
||||
this(uri, headers, null, Collections.emptyMap(), body, id, locale);
|
||||
}
|
||||
|
||||
private WebGraphQlRequest(
|
||||
URI uri, HttpHeaders headers, @Nullable MultiValueMap<String, HttpCookie> cookies,
|
||||
Map<String, Object> attributes, String document, @Nullable String operationName,
|
||||
@Nullable InetSocketAddress remoteAddress, Map<String, Object> attributes,
|
||||
String document, @Nullable String operationName,
|
||||
@Nullable Map<String, Object> variables, @Nullable Map<String, Object> extensions,
|
||||
String id, @Nullable Locale locale) {
|
||||
|
||||
@@ -156,6 +190,7 @@ public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements
|
||||
this.uri = UriComponentsBuilder.fromUri(uri).build(true);
|
||||
this.headers = headers;
|
||||
this.cookies = (cookies != null) ? CollectionUtils.unmodifiableMultiValueMap(cookies) : EMPTY_COOKIES;
|
||||
this.remoteAddress = remoteAddress;
|
||||
this.attributes = Collections.unmodifiableMap(attributes);
|
||||
}
|
||||
|
||||
@@ -182,6 +217,15 @@ public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements
|
||||
return this.cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the remote address of the client, if available.
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@Nullable
|
||||
public InetSocketAddress getRemoteAddress() {
|
||||
return this.remoteAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the request or WebSocket session attributes.
|
||||
* @since 1.1.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2023 the original author or authors.
|
||||
* Copyright 2020-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,8 +17,8 @@
|
||||
package org.springframework.graphql.server;
|
||||
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -41,24 +41,6 @@ public class WebSocketGraphQlRequest extends WebGraphQlRequest {
|
||||
private final WebSocketSessionInfo sessionInfo;
|
||||
|
||||
|
||||
/**
|
||||
* Create an instance.
|
||||
* @param uri the URL for the HTTP request or WebSocket handshake
|
||||
* @param headers the HTTP request headers
|
||||
* @param body the deserialized content of the GraphQL request
|
||||
* @param id the id from the GraphQL over WebSocket {@code "subscribe"} message
|
||||
* @param locale the locale from the HTTP request, if any
|
||||
* @param sessionInfo the WebSocket session id
|
||||
* @deprecated as of 1.1.3 in favor of the constructor with cookies
|
||||
*/
|
||||
@Deprecated(since = "1.1.3", forRemoval = true)
|
||||
public WebSocketGraphQlRequest(
|
||||
URI uri, HttpHeaders headers, Map<String, Object> body, String id, @Nullable Locale locale,
|
||||
WebSocketSessionInfo sessionInfo) {
|
||||
|
||||
this(uri, headers, null, Collections.emptyMap(), body, id, locale, sessionInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance.
|
||||
* @param uri the URL for the HTTP request or WebSocket handshake
|
||||
@@ -70,13 +52,36 @@ public class WebSocketGraphQlRequest extends WebGraphQlRequest {
|
||||
* @param locale the locale from the HTTP request, if any
|
||||
* @param sessionInfo the WebSocket session id
|
||||
* @since 1.1.3
|
||||
* @deprecated in favor of {@link #WebSocketGraphQlRequest(URI, HttpHeaders, MultiValueMap, InetSocketAddress, Map, Map, String, Locale, WebSocketSessionInfo)}
|
||||
*/
|
||||
@Deprecated(since = "1.3.0", forRemoval = true)
|
||||
public WebSocketGraphQlRequest(
|
||||
URI uri, HttpHeaders headers, @Nullable MultiValueMap<String, HttpCookie> cookies,
|
||||
Map<String, Object> attributes, Map<String, Object> body, String id, @Nullable Locale locale,
|
||||
WebSocketSessionInfo sessionInfo) {
|
||||
|
||||
super(uri, headers, cookies, attributes, body, id, locale);
|
||||
this(uri, headers, cookies, null, attributes, body, id, locale, sessionInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance.
|
||||
* @param uri the URL for the HTTP request or WebSocket handshake
|
||||
* @param headers the HTTP request headers
|
||||
* @param cookies the HTTP request cookies
|
||||
* @param remoteAddress the client remote address
|
||||
* @param attributes session attributes
|
||||
* @param body the deserialized content of the GraphQL request
|
||||
* @param id the id from the GraphQL over WebSocket {@code "subscribe"} message
|
||||
* @param locale the locale from the HTTP request, if any
|
||||
* @param sessionInfo the WebSocket session id
|
||||
* @since 1.3.0
|
||||
*/
|
||||
public WebSocketGraphQlRequest(
|
||||
URI uri, HttpHeaders headers, @Nullable MultiValueMap<String, HttpCookie> cookies,
|
||||
@Nullable InetSocketAddress remoteAddress, Map<String, Object> attributes, Map<String, Object> body,
|
||||
String id, @Nullable Locale locale, WebSocketSessionInfo sessionInfo) {
|
||||
|
||||
super(uri, headers, cookies, remoteAddress, attributes, body, id, locale);
|
||||
Assert.notNull(sessionInfo, "WebSocketSessionInfo is required");
|
||||
this.sessionInfo = sessionInfo;
|
||||
}
|
||||
|
||||
@@ -74,7 +74,8 @@ public class GraphQlHttpHandler extends AbstractGraphQlHttpHandler {
|
||||
.flatMap((body) -> {
|
||||
WebGraphQlRequest graphQlRequest = new WebGraphQlRequest(
|
||||
serverRequest.uri(), serverRequest.headers().asHttpHeaders(),
|
||||
serverRequest.cookies(), serverRequest.attributes(), body,
|
||||
serverRequest.cookies(), serverRequest.remoteAddress().orElse(null),
|
||||
serverRequest.attributes(), body,
|
||||
serverRequest.exchange().getRequest().getId(),
|
||||
serverRequest.exchange().getLocaleContext().getLocale());
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
@@ -70,7 +70,8 @@ public class GraphQlSseHandler extends AbstractGraphQlHttpHandler {
|
||||
.flatMap((body) -> {
|
||||
WebGraphQlRequest graphQlRequest = new WebGraphQlRequest(
|
||||
serverRequest.uri(), serverRequest.headers().asHttpHeaders(),
|
||||
serverRequest.cookies(), serverRequest.attributes(), body,
|
||||
serverRequest.cookies(), serverRequest.remoteAddress().orElse(null),
|
||||
serverRequest.attributes(), body,
|
||||
serverRequest.exchange().getRequest().getId(),
|
||||
serverRequest.exchange().getLocaleContext().getLocale());
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
@@ -172,7 +172,8 @@ public class GraphQlWebSocketHandler implements WebSocketHandler {
|
||||
}
|
||||
WebSocketGraphQlRequest request = new WebSocketGraphQlRequest(
|
||||
handshakeInfo.getUri(), handshakeInfo.getHeaders(), handshakeInfo.getCookies(),
|
||||
handshakeInfo.getAttributes(), payload, id, null, sessionInfo);
|
||||
handshakeInfo.getRemoteAddress(), handshakeInfo.getAttributes(),
|
||||
payload, id, null, sessionInfo);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Executing: " + request);
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ public class GraphQlHttpHandler extends AbstractGraphQlHttpHandler {
|
||||
|
||||
WebGraphQlRequest graphQlRequest = new WebGraphQlRequest(
|
||||
serverRequest.uri(), serverRequest.headers().asHttpHeaders(), initCookies(serverRequest),
|
||||
serverRequest.remoteAddress().orElse(null),
|
||||
serverRequest.attributes(), readBody(serverRequest), this.idGenerator.generateId().toString(),
|
||||
LocaleContextHolder.getLocale());
|
||||
|
||||
|
||||
@@ -69,7 +69,8 @@ public class GraphQlSseHandler extends AbstractGraphQlHttpHandler {
|
||||
|
||||
WebGraphQlRequest graphQlRequest = new WebGraphQlRequest(
|
||||
serverRequest.uri(), serverRequest.headers().asHttpHeaders(), initCookies(serverRequest),
|
||||
serverRequest.attributes(), readBody(serverRequest), this.idGenerator.generateId().toString(),
|
||||
serverRequest.remoteAddress().orElse(null), serverRequest.attributes(),
|
||||
readBody(serverRequest), this.idGenerator.generateId().toString(),
|
||||
LocaleContextHolder.getLocale());
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
@@ -230,7 +230,7 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub
|
||||
Assert.notNull(uri, "Expected handshake url");
|
||||
HttpHeaders headers = session.getHandshakeHeaders();
|
||||
WebSocketGraphQlRequest request = new WebSocketGraphQlRequest(
|
||||
uri, headers, null, session.getAttributes(), payload, id, null, state.getSessionInfo());
|
||||
uri, headers, null, session.getRemoteAddress(), session.getAttributes(), payload, id, null, state.getSessionInfo());
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Executing: " + request);
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public class TestWebSocketSession implements WebSocketSession {
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getRemoteAddress() {
|
||||
throw new UnsupportedOperationException();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user