Refactor environment and nginx configuration for improved API routing and proxy handling
This commit is contained in:
@@ -1,141 +0,0 @@
|
||||
package fr.gameovergne.api.controller.prestashop;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.client.HttpStatusCodeException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/ps")
|
||||
public class PrestashopProxyController {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(PrestashopProxyController.class);
|
||||
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
private final String baseUrl; // ex : https://shop.gameovergne.fr
|
||||
private final String basicAuth; // base64 SANS le "Basic "
|
||||
|
||||
public PrestashopProxyController(
|
||||
@Value("${prestashop.base-url}") String baseUrl,
|
||||
@Value("${prestashop.basic-auth}") String basicAuth
|
||||
) {
|
||||
this.baseUrl = baseUrl;
|
||||
this.basicAuth = basicAuth;
|
||||
}
|
||||
|
||||
// =============== Helpers ===============
|
||||
|
||||
private String extractPath(HttpServletRequest request) {
|
||||
// /api/ps/products/446 -> /products/446
|
||||
String fullPath = request.getRequestURI();
|
||||
String contextPath = request.getContextPath(); // souvent ""
|
||||
String relative = fullPath.substring(contextPath.length());
|
||||
return relative.replaceFirst("^/api/ps", "");
|
||||
}
|
||||
|
||||
private String readBody(HttpServletRequest request) throws IOException {
|
||||
try (BufferedReader reader = request.getReader()) {
|
||||
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
|
||||
}
|
||||
}
|
||||
|
||||
private ResponseEntity<String> forward(HttpServletRequest request,
|
||||
HttpMethod method,
|
||||
String bodyIfAny) {
|
||||
String path = extractPath(request);
|
||||
String rawQuery = request.getQueryString();
|
||||
|
||||
UriComponentsBuilder builder = UriComponentsBuilder
|
||||
.fromHttpUrl(baseUrl)
|
||||
.path("/api")
|
||||
.path(path);
|
||||
|
||||
if (rawQuery != null && !rawQuery.isBlank()) {
|
||||
builder.query(rawQuery); // on garde EXACTEMENT la query envoyée par Angular
|
||||
}
|
||||
|
||||
String url = builder.build(true).toUriString();
|
||||
log.info("[PrestaProxy] {} {}", method.name(), url);
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
|
||||
// Auth Presta (cachée côté backend)
|
||||
headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
|
||||
|
||||
// On propage Accept/Content-Type du front pour garder le même comportement qu’en dev
|
||||
String accept = request.getHeader(HttpHeaders.ACCEPT);
|
||||
if (accept != null) {
|
||||
headers.set(HttpHeaders.ACCEPT, accept);
|
||||
}
|
||||
|
||||
String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
|
||||
if (contentType != null) {
|
||||
headers.set(HttpHeaders.CONTENT_TYPE, contentType);
|
||||
}
|
||||
|
||||
HttpEntity<String> entity = new HttpEntity<>(bodyIfAny, headers);
|
||||
|
||||
try {
|
||||
ResponseEntity<String> response = restTemplate.exchange(
|
||||
url,
|
||||
method,
|
||||
entity,
|
||||
String.class
|
||||
);
|
||||
|
||||
// On renvoie EXACTEMENT le status + headers + body de Presta au front
|
||||
return ResponseEntity
|
||||
.status(response.getStatusCode())
|
||||
.headers(response.getHeaders())
|
||||
.body(response.getBody());
|
||||
|
||||
} catch (HttpStatusCodeException ex) {
|
||||
// On propage aussi les erreurs Presta (4xx/5xx) sans les transformer en 500 Spring
|
||||
HttpHeaders respHeaders = ex.getResponseHeaders() != null
|
||||
? ex.getResponseHeaders()
|
||||
: new HttpHeaders();
|
||||
|
||||
log.error("[PrestaProxy] {} {} -> HTTP {}",
|
||||
method.name(), url, ex.getStatusCode().value());
|
||||
|
||||
return ResponseEntity
|
||||
.status(ex.getStatusCode())
|
||||
.headers(respHeaders)
|
||||
.body(ex.getResponseBodyAsString());
|
||||
}
|
||||
}
|
||||
|
||||
// =============== Routes ===============
|
||||
|
||||
@GetMapping("/**")
|
||||
public ResponseEntity<String> proxyGet(HttpServletRequest request) {
|
||||
return forward(request, HttpMethod.GET, null);
|
||||
}
|
||||
|
||||
@DeleteMapping("/**")
|
||||
public ResponseEntity<String> proxyDelete(HttpServletRequest request) {
|
||||
return forward(request, HttpMethod.DELETE, null);
|
||||
}
|
||||
|
||||
@PostMapping("/**")
|
||||
public ResponseEntity<String> proxyPost(HttpServletRequest request) throws IOException {
|
||||
String body = readBody(request); // XML ou JSON, on ne touche à rien
|
||||
return forward(request, HttpMethod.POST, body);
|
||||
}
|
||||
|
||||
@PutMapping("/**")
|
||||
public ResponseEntity<String> proxyPut(HttpServletRequest request) throws IOException {
|
||||
String body = readBody(request);
|
||||
return forward(request, HttpMethod.PUT, body);
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,31 @@ server {
|
||||
|
||||
server_name _;
|
||||
|
||||
# Angular packagé par Nginx (classique)
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# SPA Angular : toutes les routes front -> index.html
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
|
||||
# === Proxy vers PrestaShop (équivalent proxy.conf.json "/ps") ===
|
||||
location /ps/ {
|
||||
# /ps/... -> https://shop.gameovergne.fr/api/...
|
||||
proxy_pass https://shop.gameovergne.fr/api/;
|
||||
|
||||
# changeOrigin: true
|
||||
proxy_set_header Host shop.gameovergne.fr;
|
||||
|
||||
# Auth Basic comme dans ton proxy.conf.json Angular
|
||||
proxy_set_header Authorization "Basic MkFRUEcxM01KOFgxMTdVNkZKNU5HSFBTOTNIRTM0QUI=";
|
||||
|
||||
# HTTPS correct (SNI)
|
||||
proxy_ssl_server_name on;
|
||||
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export const environment = {
|
||||
production: true,
|
||||
apiUrl: 'https://dev.vincent-guillet.fr/gameovergne-api/api',
|
||||
psUrl: 'https://dev.vincent-guillet.fr/gameovergne-api/api/ps'
|
||||
psUrl: '/ps'
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export const environment = {
|
||||
production: false,
|
||||
apiUrl: 'http://localhost:3000/api',
|
||||
psUrl: 'http://localhost:3000/api/ps'
|
||||
psUrl: 'ps'
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user