Skip to content

Commit 2f96f9f

Browse files
committed
webflux: contextPath not used while behind a load balancer/reverse proxy. fixes #1109
1 parent 63f15b5 commit 2f96f9f

File tree

10 files changed

+61
-53
lines changed

10 files changed

+61
-53
lines changed

springdoc-openapi-common/src/main/java/org/springdoc/ui/AbstractSwaggerWelcome.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ public abstract class AbstractSwaggerWelcome implements InitializingBean {
6565
*/
6666
protected String apiDocsUrl;
6767

68+
/**
69+
* The Context path.
70+
*/
71+
protected String contextPath;
72+
6873
/**
6974
* Instantiates a new Abstract swagger welcome.
7075
*
@@ -103,13 +108,12 @@ protected String buildUrl(String contextPath, String docsUrl) {
103108
/**
104109
* Build config url.
105110
*
106-
* @param contextPath the context path
107111
* @param uriComponentsBuilder the uri components builder
108112
*/
109-
protected void buildConfigUrl(String contextPath, UriComponentsBuilder uriComponentsBuilder) {
113+
protected void buildConfigUrl( UriComponentsBuilder uriComponentsBuilder) {
110114
if (StringUtils.isEmpty(swaggerUiConfig.getConfigUrl())) {
111-
apiDocsUrl = StringUtils.defaultIfEmpty(apiDocsUrl, buildApiDocUrl(contextPath));
112-
swaggerConfigUrl = StringUtils.defaultIfEmpty(swaggerConfigUrl, buildSwaggerConfigUrl(contextPath));
115+
apiDocsUrl = buildApiDocUrl();
116+
swaggerConfigUrl = buildSwaggerConfigUrl();
113117
swaggerUiConfigParameters.setConfigUrl(swaggerConfigUrl);
114118
if (CollectionUtils.isEmpty(swaggerUiConfigParameters.getUrls())) {
115119
String swaggerUiUrl = swaggerUiConfig.getUrl();
@@ -190,22 +194,15 @@ protected void calculateUiRootCommon(StringBuilder sbUrl, StringBuilder[] sbUrls
190194
/**
191195
* Build api doc url string.
192196
*
193-
* @param contextPath the context path
194197
* @return the string
195198
*/
196-
protected String buildApiDocUrl(String contextPath) {
197-
return this.apiDocsUrl;
198-
}
199+
protected abstract String buildApiDocUrl();
199200

200201
/**
201202
* Build swagger config url string.
202203
*
203-
* @param contextPath the context path
204-
* @return the string
205204
*/
206-
protected String buildSwaggerConfigUrl(String contextPath) {
207-
return this.swaggerConfigUrl;
208-
}
205+
protected abstract String buildSwaggerConfigUrl();
209206

210207
/**
211208
* Gets oauth2 redirect url.

springdoc-openapi-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerWelcomeActuator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,13 @@ protected void calculateUiRootPath(StringBuilder... sbUrls) {
8181
}
8282

8383
@Override
84-
protected String buildApiDocUrl(String contextPath) {
84+
protected String buildApiDocUrl() {
8585
return buildUrl(contextPath + webEndpointProperties.getBasePath(), DEFAULT_API_DOCS_ACTUATOR_URL);
8686
}
8787

8888
@Override
89-
protected String buildSwaggerConfigUrl(String contextPath) {
90-
return contextPath + webEndpointProperties.getBasePath()
89+
protected String buildSwaggerConfigUrl() {
90+
return contextPath + webEndpointProperties.getBasePath()
9191
+ DEFAULT_PATH_SEPARATOR + DEFAULT_SWAGGER_UI_ACTUATOR_PATH
9292
+ DEFAULT_PATH_SEPARATOR + SWAGGGER_CONFIG_FILE;
9393
}

springdoc-openapi-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerWelcomeCommon.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ public SwaggerWelcomeCommon(SwaggerUiConfigProperties swaggerUiConfig, SpringDoc
3939
* @return the response entity
4040
*/
4141
protected ResponseEntity<Void> redirectToUi(HttpServletRequest request) {
42-
buildConfigUrl(request.getContextPath(), ServletUriComponentsBuilder.fromCurrentContextPath());
43-
String sbUrl = request.getContextPath() + swaggerUiConfigParameters.getUiRootPath() + SWAGGER_UI_URL;
42+
buildFromCurrentContextPath(request);
43+
String sbUrl = contextPath + swaggerUiConfigParameters.getUiRootPath() + SWAGGER_UI_URL;
4444
UriComponentsBuilder uriBuilder = getUriComponentsBuilder(sbUrl);
4545

4646
// forward all queryParams from original request
@@ -58,7 +58,7 @@ protected ResponseEntity<Void> redirectToUi(HttpServletRequest request) {
5858
* @return the map
5959
*/
6060
protected Map<String, Object> openapiJson(HttpServletRequest request) {
61-
buildConfigUrl(request.getContextPath(), ServletUriComponentsBuilder.fromCurrentContextPath());
61+
buildFromCurrentContextPath(request);
6262
return swaggerUiConfigParameters.getConfigParameters();
6363
}
6464

@@ -69,4 +69,14 @@ protected void calculateOauth2RedirectUrl(UriComponentsBuilder uriComponentsBuil
6969
.path(swaggerUiConfigParameters.getUiRootPath())
7070
.path(getOauth2RedirectUrl()).build().toString());
7171
}
72+
73+
/**
74+
* From current context path.
75+
*
76+
* @param request the request
77+
*/
78+
private void buildFromCurrentContextPath(HttpServletRequest request) {
79+
contextPath = request.getContextPath();
80+
buildConfigUrl(ServletUriComponentsBuilder.fromCurrentContextPath());
81+
}
7282
}

springdoc-openapi-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerWelcomeWebMvc.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,12 @@ protected String buildUrl(String contextPath, final String docsUrl) {
111111
}
112112

113113
@Override
114-
protected String buildApiDocUrl(String contextPath) {
114+
protected String buildApiDocUrl() {
115115
return buildUrl(contextPath, springDocConfigProperties.getApiDocs().getPath());
116116
}
117117

118118
@Override
119-
protected String buildSwaggerConfigUrl(String contextPath) {
119+
protected String buildSwaggerConfigUrl() {
120120
return apiDocsUrl + DEFAULT_PATH_SEPARATOR + SWAGGGER_CONFIG_FILE;
121121
}
122122
}

springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app18/HelloController.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818

1919
package test.org.springdoc.ui.app18;
2020

21+
import javax.validation.Valid;
22+
import javax.validation.constraints.Size;
23+
2124
import org.springframework.web.bind.annotation.GetMapping;
2225
import org.springframework.web.bind.annotation.RequestParam;
2326
import org.springframework.web.bind.annotation.RestController;
2427

25-
import javax.validation.Valid;
26-
import javax.validation.constraints.Size;
27-
2828
@RestController
2929
public class HelloController {
3030

springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
4040
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
4141
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
42-
import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties;
4342
import org.springframework.context.annotation.Bean;
4443
import org.springframework.context.annotation.Configuration;
4544
import org.springframework.context.annotation.Lazy;
@@ -66,15 +65,14 @@ public class SwaggerConfig implements WebFluxConfigurer {
6665
* @param swaggerUiConfig the swagger ui config
6766
* @param springDocConfigProperties the spring doc config properties
6867
* @param swaggerUiConfigParameters the swagger ui config parameters
69-
* @param optionalWebFluxProperties the optional web flux properties
7068
* @param requestMappingHandlerMapping the request mapping handler mapping
7169
* @return the swagger welcome web flux
7270
*/
7371
@Bean
7472
@ConditionalOnMissingBean
7573
@ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true)
76-
SwaggerWelcomeWebFlux swaggerWelcome(SwaggerUiConfigProperties swaggerUiConfig, SpringDocConfigProperties springDocConfigProperties,SwaggerUiConfigParameters swaggerUiConfigParameters, Optional<WebFluxProperties> optionalWebFluxProperties, RequestMappingInfoHandlerMapping requestMappingHandlerMapping) {
77-
return new SwaggerWelcomeWebFlux(swaggerUiConfig,springDocConfigProperties,swaggerUiConfigParameters,optionalWebFluxProperties,requestMappingHandlerMapping);
74+
SwaggerWelcomeWebFlux swaggerWelcome(SwaggerUiConfigProperties swaggerUiConfig, SpringDocConfigProperties springDocConfigProperties,SwaggerUiConfigParameters swaggerUiConfigParameters, RequestMappingInfoHandlerMapping requestMappingHandlerMapping) {
75+
return new SwaggerWelcomeWebFlux(swaggerUiConfig,springDocConfigProperties,swaggerUiConfigParameters,requestMappingHandlerMapping);
7876
}
7977

8078
/**

springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerWelcomeActuator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,12 @@ protected void calculateOauth2RedirectUrl(UriComponentsBuilder uriComponentsBuil
129129
}
130130

131131
@Override
132-
protected String buildApiDocUrl(String contextPath) {
132+
protected String buildApiDocUrl() {
133133
return buildUrl(contextPath + webEndpointProperties.getBasePath(), DEFAULT_API_DOCS_ACTUATOR_URL);
134134
}
135135

136136
@Override
137-
protected String buildSwaggerConfigUrl(String contextPath) {
137+
protected String buildSwaggerConfigUrl() {
138138
return contextPath + webEndpointProperties.getBasePath()
139139
+ DEFAULT_PATH_SEPARATOR + DEFAULT_SWAGGER_UI_ACTUATOR_PATH
140140
+ DEFAULT_PATH_SEPARATOR + SWAGGGER_CONFIG_FILE;

springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerWelcomeCommon.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public SwaggerWelcomeCommon(SwaggerUiConfigProperties swaggerUiConfig, SpringDoc
7272
* @return the mono
7373
*/
7474
protected Mono<Void> redirectToUi(ServerHttpRequest request, ServerHttpResponse response) {
75-
String contextPath = this.fromCurrentContextPath(request);
75+
this.buildFromCurrentContextPath(request);
7676
String sbUrl = this.buildUrl(contextPath, swaggerUiConfigParameters.getUiRootPath() + springDocConfigProperties.getWebjars().getPrefix() + SWAGGER_UI_URL);
7777
UriComponentsBuilder uriBuilder = getUriComponentsBuilder(sbUrl);
7878
response.setStatusCode(HttpStatus.FOUND);
@@ -87,7 +87,7 @@ protected Mono<Void> redirectToUi(ServerHttpRequest request, ServerHttpResponse
8787
* @return the swagger ui config
8888
*/
8989
protected Map<String, Object> getSwaggerUiConfig(ServerHttpRequest request) {
90-
this.fromCurrentContextPath(request);
90+
this.buildFromCurrentContextPath(request);
9191
return swaggerUiConfigParameters.getConfigParameters();
9292
}
9393

@@ -97,13 +97,12 @@ protected Map<String, Object> getSwaggerUiConfig(ServerHttpRequest request) {
9797
* @param request the request
9898
* @return the string
9999
*/
100-
private String fromCurrentContextPath(ServerHttpRequest request) {
101-
String contextPath = request.getPath().contextPath().value();
100+
private void buildFromCurrentContextPath(ServerHttpRequest request) {
101+
contextPath = request.getPath().contextPath().value();
102102
String url = UriComponentsBuilder.fromHttpRequest(request).toUriString();
103103
if (!AntPathMatcher.DEFAULT_PATH_SEPARATOR.equals(request.getPath().toString()))
104104
url = url.replace(request.getPath().toString(), "");
105-
buildConfigUrl(contextPath, UriComponentsBuilder.fromUriString(url));
106-
return contextPath;
105+
buildConfigUrl(UriComponentsBuilder.fromUriString(url));
107106
}
108107

109108
}

springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerWelcomeWebFlux.java

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import java.util.List;
2525
import java.util.Map;
2626
import java.util.Map.Entry;
27-
import java.util.Optional;
2827
import java.util.Set;
2928

3029
import javax.annotation.PostConstruct;
@@ -36,7 +35,6 @@
3635
import org.springdoc.core.SwaggerUiConfigProperties;
3736
import reactor.core.publisher.Mono;
3837

39-
import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties;
4038
import org.springframework.http.MediaType;
4139
import org.springframework.http.server.reactive.ServerHttpRequest;
4240
import org.springframework.http.server.reactive.ServerHttpResponse;
@@ -53,6 +51,7 @@
5351
import static org.springdoc.core.Constants.SWAGGER_CONFIG_URL;
5452
import static org.springdoc.core.Constants.SWAGGER_UI_PATH;
5553
import static org.springdoc.core.Constants.SWAGGGER_CONFIG_FILE;
54+
import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR;
5655

5756
/**
5857
* The type Swagger welcome.
@@ -62,29 +61,27 @@
6261
public class SwaggerWelcomeWebFlux extends SwaggerWelcomeCommon {
6362

6463
/**
65-
* The Webflux base path.
64+
* The Request mapping handler mapping.
6665
*/
67-
private String webfluxBasePath = StringUtils.EMPTY;
66+
private final RequestMappingInfoHandlerMapping requestMappingHandlerMapping;
6867

6968
/**
70-
* The Request mapping handler mapping.
69+
* The Path prefix.
7170
*/
72-
private final RequestMappingInfoHandlerMapping requestMappingHandlerMapping;
71+
private String pathPrefix;
7372

7473
/**
7574
* Instantiates a new Swagger welcome.
7675
*
7776
* @param swaggerUiConfig the swagger ui config
7877
* @param springDocConfigProperties the spring doc config properties
7978
* @param swaggerUiConfigParameters the swagger ui config parameters
80-
* @param webFluxPropertiesOptional the web flux properties
8179
* @param requestMappingHandlerMapping the request mapping handler mapping
8280
*/
83-
public SwaggerWelcomeWebFlux(SwaggerUiConfigProperties swaggerUiConfig, SpringDocConfigProperties springDocConfigProperties, SwaggerUiConfigParameters swaggerUiConfigParameters,
84-
Optional<WebFluxProperties> webFluxPropertiesOptional, RequestMappingInfoHandlerMapping requestMappingHandlerMapping) {
81+
public SwaggerWelcomeWebFlux(SwaggerUiConfigProperties swaggerUiConfig, SpringDocConfigProperties springDocConfigProperties,
82+
SwaggerUiConfigParameters swaggerUiConfigParameters, RequestMappingInfoHandlerMapping requestMappingHandlerMapping) {
8583
super(swaggerUiConfig, springDocConfigProperties, swaggerUiConfigParameters);
8684
this.requestMappingHandlerMapping = requestMappingHandlerMapping;
87-
webFluxPropertiesOptional.ifPresent(webFluxProperties -> webfluxBasePath = webFluxProperties.getBasePath());
8885
}
8986

9087
/**
@@ -100,10 +97,8 @@ private void init() {
10097
Set<PathPattern> patterns = patternsRequestCondition.getPatterns();
10198
for (PathPattern pathPattern : patterns) {
10299
String operationPath = pathPattern.getPatternString();
103-
if (operationPath.endsWith(SWAGGGER_CONFIG_FILE))
104-
swaggerConfigUrl = StringUtils.defaultString(webfluxBasePath) + operationPath;
105-
else if (operationPath.endsWith(springDocConfigProperties.getApiDocs().getPath()))
106-
apiDocsUrl = StringUtils.defaultString(webfluxBasePath) + operationPath;
100+
if (operationPath.endsWith(springDocConfigProperties.getApiDocs().getPath()))
101+
pathPrefix = operationPath.replace(springDocConfigProperties.getApiDocs().getPath(), StringUtils.EMPTY);
107102
}
108103
}
109104
}
@@ -145,8 +140,18 @@ protected void calculateUiRootPath(StringBuilder... sbUrls) {
145140
@Override
146141
protected void calculateOauth2RedirectUrl(UriComponentsBuilder uriComponentsBuilder) {
147142
if ((oauthPrefix == null && !swaggerUiConfigParameters.isValidUrl(swaggerUiConfigParameters.getOauth2RedirectUrl())) || springDocConfigProperties.isCacheDisabled()) {
148-
this.oauthPrefix = uriComponentsBuilder.path(webfluxBasePath).path(swaggerUiConfigParameters.getUiRootPath()).path(webJarsPrefixUrl);
143+
this.oauthPrefix = uriComponentsBuilder.path(contextPath).path(swaggerUiConfigParameters.getUiRootPath()).path(webJarsPrefixUrl);
149144
swaggerUiConfigParameters.setOauth2RedirectUrl(this.oauthPrefix.path(getOauth2RedirectUrl()).build().toString());
150145
}
151146
}
147+
148+
@Override
149+
protected String buildApiDocUrl() {
150+
return buildUrl(this.contextPath + this.pathPrefix, springDocConfigProperties.getApiDocs().getPath());
151+
}
152+
153+
@Override
154+
protected String buildSwaggerConfigUrl() {
155+
return this.apiDocsUrl + DEFAULT_PATH_SEPARATOR + SWAGGGER_CONFIG_FILE;
156+
}
152157
}

springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app18/SpringDocApp18Test.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
"server.port=9018",
4141
"springdoc.swagger-ui.path=/documentation/swagger-ui.html",
4242
"springdoc.api-docs.path=/documentation/v3/api-docs",
43-
"spring.webflux.base-path=/test",
4443
"springdoc.webjars.prefix= /webjars-pref" })
4544
class SpringDocApp18Test extends AbstractCommonTest {
4645

@@ -59,7 +58,7 @@ void init(){
5958
}
6059

6160
@Test
62-
public void testIndexActuator() throws Exception {
61+
public void testIndex() throws Exception {
6362
HttpStatus httpStatusMono = webClient.get().uri("/test/documentation/swagger-ui.html")
6463
.exchangeToMono(clientResponse -> Mono.just(clientResponse.statusCode())).block();
6564
assertThat(httpStatusMono).isEqualTo(HttpStatus.FOUND);

0 commit comments

Comments
 (0)