diff --git a/spring-boot-modules/spring-boot-5/pom.xml b/spring-boot-modules/spring-boot-5/pom.xml index 0f5fd41bf388..a10f11b12f04 100644 --- a/spring-boot-modules/spring-boot-5/pom.xml +++ b/spring-boot-modules/spring-boot-5/pom.xml @@ -57,7 +57,7 @@ - 4.0.2 + 4.1.1 6.0.0 1.5.18 3.0.0-M7 diff --git a/spring-boot-modules/spring-boot-5/src/main/java/com/baeldung/forwardheaders/ForwardHeadersApplication.java b/spring-boot-modules/spring-boot-5/src/main/java/com/baeldung/forwardheaders/ForwardHeadersApplication.java new file mode 100644 index 000000000000..ce1e608f1b89 --- /dev/null +++ b/spring-boot-modules/spring-boot-5/src/main/java/com/baeldung/forwardheaders/ForwardHeadersApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.forwardheaders; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(scanBasePackages = "com.baeldung.forwardheaders") +public class ForwardHeadersApplication { + + public static void main(String[] args) { + SpringApplication.run(ForwardHeadersApplication.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-5/src/main/java/com/baeldung/forwardheaders/TestController.java b/spring-boot-modules/spring-boot-5/src/main/java/com/baeldung/forwardheaders/TestController.java new file mode 100644 index 000000000000..2a1718efa3e3 --- /dev/null +++ b/spring-boot-modules/spring-boot-5/src/main/java/com/baeldung/forwardheaders/TestController.java @@ -0,0 +1,30 @@ +package com.baeldung.forwardheaders; + +import jakarta.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class TestController { + + private static final Logger LOGGER = LoggerFactory.getLogger(TestController.class); + + @GetMapping("/test") + public ResponseEntity test(HttpServletRequest request) { + LOGGER.info(""" + scheme : {} + Remote Host IP : {} + Remote Port : {} + Server Name : {} + Server Port : {} + Request URL : {}""", request.getScheme(), request.getRemoteHost(), request.getRemotePort(), request.getServerName(), request.getServerPort(), + request.getRequestURL()); + + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/spring-boot-modules/spring-boot-5/src/main/resources/application-framework.yml b/spring-boot-modules/spring-boot-5/src/main/resources/application-framework.yml new file mode 100644 index 000000000000..2a628f82f585 --- /dev/null +++ b/spring-boot-modules/spring-boot-5/src/main/resources/application-framework.yml @@ -0,0 +1,2 @@ +server: + forward-headers-strategy: FRAMEWORK \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-5/src/main/resources/application-native.yml b/spring-boot-modules/spring-boot-5/src/main/resources/application-native.yml new file mode 100644 index 000000000000..2c01898f85b4 --- /dev/null +++ b/spring-boot-modules/spring-boot-5/src/main/resources/application-native.yml @@ -0,0 +1,17 @@ +server: + forward-headers-strategy: NATIVE + tomcat: + remoteip: + remote-ip-header: X-Forwarded-For + protocol-header: X-Forwarded-Proto + host-header: X-Forwarded-Host + port-header: X-Forwarded-Port + trusted-proxies: 172\.(1[6-9]|2\d|3[0-1])\.\d{1,3}\.\d{1,3} + accesslog: + enabled: true + request-attributes-enabled: true + directory: /app/logs + prefix: access_log + suffix: .log + pattern: '%h %l %u %t "%r" %s %b "%{X-Forwarded-Host}i" "%{X-Forwarded-For}i" "%{X-Forwarded-Proto}i"' + rotate: false \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-5/src/main/resources/application-none.yml b/spring-boot-modules/spring-boot-5/src/main/resources/application-none.yml new file mode 100644 index 000000000000..32daac51472f --- /dev/null +++ b/spring-boot-modules/spring-boot-5/src/main/resources/application-none.yml @@ -0,0 +1,2 @@ +server: + forward-headers-strategy: NONE diff --git a/spring-boot-modules/spring-boot-5/src/main/resources/application.yml b/spring-boot-modules/spring-boot-5/src/main/resources/application.yml new file mode 100644 index 000000000000..8cb5da84c64c --- /dev/null +++ b/spring-boot-modules/spring-boot-5/src/main/resources/application.yml @@ -0,0 +1,6 @@ +server: + port: 8081 + +spring: + application: + name: backend-app \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-5/src/test/java/com/baeldung/forwardheaders/TestControllerLiveTest.java b/spring-boot-modules/spring-boot-5/src/test/java/com/baeldung/forwardheaders/TestControllerLiveTest.java new file mode 100644 index 000000000000..31b6e568f6aa --- /dev/null +++ b/spring-boot-modules/spring-boot-5/src/test/java/com/baeldung/forwardheaders/TestControllerLiveTest.java @@ -0,0 +1,33 @@ +package com.baeldung.forwardheaders; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.test.web.servlet.client.RestTestClient;; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +class TestControllerLiveTest { + + private RestTestClient restTestClient; + + @LocalServerPort + private int port; + + @BeforeEach + void setUp() { + restTestClient = RestTestClient + .bindToServer() + .baseUrl("http://localhost:" + port) + .build(); + } + + @Test + void givenTestApiIsRunning_whenGetTestIsCalled_thenReturnOkWithNoContent() { + restTestClient.get() + .uri("/test") + .exchange() + .expectStatus().isOk() + .expectBody().isEmpty(); + } +} diff --git a/spring-boot-modules/spring-boot-5/src/test/resources/docker/Dockerfile b/spring-boot-modules/spring-boot-5/src/test/resources/docker/Dockerfile new file mode 100644 index 000000000000..631e6fbf0163 --- /dev/null +++ b/spring-boot-modules/spring-boot-5/src/test/resources/docker/Dockerfile @@ -0,0 +1,7 @@ +FROM eclipse-temurin:21-jre-alpine + +WORKDIR /app +COPY target/spring-boot-5-0.0.1-SNAPSHOT.jar backend-app.jar + +EXPOSE 8081 +ENTRYPOINT ["java", "-jar", "backend-app.jar"] \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-5/src/test/resources/docker/default/docker-compose.yml b/spring-boot-modules/spring-boot-5/src/test/resources/docker/default/docker-compose.yml new file mode 100644 index 000000000000..fcff2f3d5cbb --- /dev/null +++ b/spring-boot-modules/spring-boot-5/src/test/resources/docker/default/docker-compose.yml @@ -0,0 +1,23 @@ +services: + backend-app: + build: + context: ../../../../../ + dockerfile: ./src/test/resources/docker/Dockerfile + container_name: backend-app + environment: + - SPRING_PROFILES_ACTIVE= + expose: + - "8081" + + + nginx: + image: nginx:1.31.3-alpine + container_name: nginx-proxy + volumes: + - ../../nginx/nginx.conf:/etc/nginx/nginx.conf:ro + - ../../nginx/certs:/etc/nginx/certs:ro + ports: + - "443:443" + depends_on: + - backend-app + diff --git a/spring-boot-modules/spring-boot-5/src/test/resources/docker/framework/docker-compose.yml b/spring-boot-modules/spring-boot-5/src/test/resources/docker/framework/docker-compose.yml new file mode 100644 index 000000000000..309e0ea10aef --- /dev/null +++ b/spring-boot-modules/spring-boot-5/src/test/resources/docker/framework/docker-compose.yml @@ -0,0 +1,22 @@ +services: + backend-app: + build: + context: ../../../../../ + dockerfile: ./src/test/resources/docker/Dockerfile + container_name: backend-app + environment: + - SPRING_PROFILES_ACTIVE=framework + expose: + - "8081" + + nginx: + image: nginx:1.31.3-alpine + container_name: nginx-proxy + volumes: + - ../../nginx/nginx.conf:/etc/nginx/nginx.conf:ro + - ../../nginx/certs:/etc/nginx/certs:ro + ports: + - "443:443" + depends_on: + - backend-app + diff --git a/spring-boot-modules/spring-boot-5/src/test/resources/docker/native/docker-compose.yml b/spring-boot-modules/spring-boot-5/src/test/resources/docker/native/docker-compose.yml new file mode 100644 index 000000000000..166b51ceecbc --- /dev/null +++ b/spring-boot-modules/spring-boot-5/src/test/resources/docker/native/docker-compose.yml @@ -0,0 +1,22 @@ +services: + backend-app: + build: + context: ../../../../../ + dockerfile: ./src/test/resources/docker/Dockerfile + container_name: backend-app + environment: + - SPRING_PROFILES_ACTIVE=native + expose: + - "8081" + + nginx: + image: nginx:1.31.3-alpine + container_name: nginx-proxy + volumes: + - ../../nginx/nginx.conf:/etc/nginx/nginx.conf:ro + - ../../nginx/certs:/etc/nginx/certs:ro + ports: + - "443:443" + depends_on: + - backend-app + diff --git a/spring-boot-modules/spring-boot-5/src/test/resources/docker/none/docker-compose.yml b/spring-boot-modules/spring-boot-5/src/test/resources/docker/none/docker-compose.yml new file mode 100644 index 000000000000..f7936ef74b0a --- /dev/null +++ b/spring-boot-modules/spring-boot-5/src/test/resources/docker/none/docker-compose.yml @@ -0,0 +1,23 @@ +services: + backend-app: + build: + context: ../../../../../ + dockerfile: ./src/test/resources/docker/Dockerfile + container_name: backend-app + environment: + - SPRING_PROFILES_ACTIVE=none + expose: + - "8081" + + + nginx: + image: nginx:1.31.3-alpine + container_name: nginx-proxy + volumes: + - ../../nginx/nginx.conf:/etc/nginx/nginx.conf:ro + - ../../nginx/certs:/etc/nginx/certs:ro + ports: + - "443:443" + depends_on: + - backend-app + diff --git a/spring-boot-modules/spring-boot-5/src/test/resources/nginx/nginx.conf b/spring-boot-modules/spring-boot-5/src/test/resources/nginx/nginx.conf new file mode 100644 index 000000000000..2d386a012153 --- /dev/null +++ b/spring-boot-modules/spring-boot-5/src/test/resources/nginx/nginx.conf @@ -0,0 +1,44 @@ +worker_processes auto; + +events { + worker_connections 1024; +} + +http { + + map $remote_addr $forwarded_for { + ~: "\"[$remote_addr]:$remote_port\""; + default "\"$remote_addr:$remote_port\""; + } + + map $server_addr $forwarded_by { + ~: "\"[$server_addr]:$server_port\""; + default "\"$server_addr:$server_port\""; + } + + server { + listen 443 ssl; + server_name api.example.com; + + ssl_certificate /etc/nginx/certs/api.example.com.crt; + ssl_certificate_key /etc/nginx/certs/api.example.com.key; + ssl_protocols TLSv1.2 TLSv1.3; + + location /myapp/ { + proxy_pass http://backend-app:8081/; + + proxy_set_header Host $host; + + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Forwarded-Prefix /myapp; + + proxy_set_header Forwarded "for=$forwarded_for;by=$forwarded_by;host=$host;proto=$scheme"; + + proxy_http_version 1.1; + proxy_set_header Connection ""; + } + } +}