Add portRequest url handler property (#1449)

* Add portRequest url handler property

The option server.forward-headers-strategy=NATIVE allow to dynamicly
generate link based on X-Forwarded-Proto header.
Unfortunately Hawkbit artifact use a custom url handler.
This PR allow to serve artifacts on http and https in the same time.

Signed-off-by: Florian Bezannier <florian.bezannier@hotmail.fr>

* docs: use server.forward-headers-strategy option

---------

Signed-off-by: Florian Bezannier <florian.bezannier@hotmail.fr>
This commit is contained in:
Florian BEZANNIER
2023-10-19 11:04:23 +02:00
committed by GitHub
parent 44e7a72be3
commit dafc08304d
4 changed files with 30 additions and 8 deletions

View File

@@ -100,14 +100,10 @@ Nginx doesn't support obtaining the issuer hash without addons. Therefore, in th
There are also some configurations that you need update when you deployed your hawkbit service.
You need to add the given download settings to your hawkBit configurations so that hawkBit can generate the URLs according to the https that the client will use to download. If you're deploying hawkBit as a Docker container, add these configurations as environmental values in the docker-compose.yml file. Don't forget to replace "hostname" with your actual hostname.
You need to add the given setting to your hawkBit configurations so that hawkBit can generate the URLs according to the https that the client will use to download. If you're deploying hawkBit as a Docker container, add these configurations as environmental values in the docker-compose.yml file.
```
hawkbit.artifact.url.protocols.download-http.rel=download-http
hawkbit.artifact.url.protocols.download-http.hostname=hawkbit.dev.example
hawkbit.artifact.url.protocols.download-http.protocol=https
hawkbit.artifact.url.protocols.download-http.supports=DMF,DDI
hawkbit.artifact.url.protocols.download-http.ref={protocol}://{hostnameRequest}/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}
server.forward-headers-strategy=NATIVE
```
2. In Hawkbit's UI section, under system configuration, make sure to select *Allow targets to authenticate via a certificate authenticated by a reverse proxy* and input the fixed issuer hash as "Hawkbit". This can be whetever you have configured in the nginx configuration in `proxy_set_header X-Ssl-Issuer-Hash-1` below.

View File

@@ -15,7 +15,7 @@ hawkbit.artifact.url.protocols.download-http.ip=127.0.0.1
hawkbit.artifact.url.protocols.download-http.protocol=http
hawkbit.artifact.url.protocols.download-http.port=8080
hawkbit.artifact.url.protocols.download-http.supports=DMF,DDI
hawkbit.artifact.url.protocols.download-http.ref={protocol}://{hostnameRequest}:{portRequest}/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}
hawkbit.artifact.url.protocols.download-http.ref={protocolRequest}://{hostnameRequest}:{portRequest}/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}
hawkbit.artifact.url.protocols.md5sum-http.rel=md5sum-http
hawkbit.artifact.url.protocols.md5sum-http.protocol=${hawkbit.artifact.url.protocols.download-http.protocol}
hawkbit.artifact.url.protocols.md5sum-http.hostname=${hawkbit.artifact.url.protocols.download-http.hostname}
@@ -29,4 +29,4 @@ hawkbit.artifact.url.protocols.download-cdn-http.ip=127.0.0.1
hawkbit.artifact.url.protocols.download-cdn-http.protocol=http
hawkbit.artifact.url.protocols.download-cdn-http.port=8080
hawkbit.artifact.url.protocols.download-cdn-http.supports=MGMT
hawkbit.artifact.url.protocols.download-cdn-http.ref={protocol}://{hostnameRequest}:{portRequest}/rest/v1/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}
hawkbit.artifact.url.protocols.download-cdn-http.ref={protocolRequest}://{hostnameRequest}:{portRequest}/rest/v1/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}

View File

@@ -54,6 +54,7 @@ public class PropertyBasedArtifactUrlHandler implements ArtifactUrlHandler {
private static final String TARGET_ID_BASE62_PLACEHOLDER = "targetIdBase62";
private static final String HOSTNAME_REQUEST_PLACEHOLDER = "hostnameRequest";
private static final String PORT_REQUEST_PLACEHOLDER = "portRequest";
private static final String PROTOCOL_REQUEST_PLACEHOLDER = "protocolRequest";
private static final String HOSTNAME_WITH_DOMAIN_REQUEST_PLACEHOLDER = "domainRequest";
private static final String ARTIFACT_FILENAME_PLACEHOLDER = "artifactFileName";
private static final String ARTIFACT_SHA1_PLACEHOLDER = "artifactSHA1";
@@ -118,11 +119,13 @@ public class PropertyBasedArtifactUrlHandler implements ArtifactUrlHandler {
final URI requestUri) {
final Map<String, String> replaceMap = new HashMap<>();
replaceMap.put(IP_PLACEHOLDER, protocol.getIp());
replaceMap.put(HOSTNAME_PLACEHOLDER, protocol.getHostname());
replaceMap.put(HOSTNAME_REQUEST_PLACEHOLDER, getRequestHost(protocol, requestUri));
replaceMap.put(PORT_REQUEST_PLACEHOLDER, getRequestPort(protocol, requestUri));
replaceMap.put(HOSTNAME_WITH_DOMAIN_REQUEST_PLACEHOLDER, computeHostWithRequestDomain(protocol, requestUri));
replaceMap.put(PROTOCOL_REQUEST_PLACEHOLDER, getRequestProtocol(protocol, requestUri));
replaceMap.put(CONTEXT_PATH, contextPath);
@@ -166,6 +169,14 @@ public class PropertyBasedArtifactUrlHandler implements ArtifactUrlHandler {
return Optional.ofNullable(requestUri.getHost()).orElse(protocol.getHostname());
}
private static String getRequestProtocol(final UrlProtocol protocol, final URI requestUri) {
if (requestUri == null) {
return protocol.getProtocol();
}
return Optional.ofNullable(requestUri.getScheme()).orElse(protocol.getProtocol());
}
private static String getPort(final UrlProtocol protocol) {
return ObjectUtils.isEmpty(protocol.getPort()) ? null : String.valueOf(protocol.getPort());
}

View File

@@ -142,6 +142,21 @@ public class PropertyBasedArtifactUrlHandlerTest {
assertThat(urls).containsExactly(new ArtifactUrl(TEST_PROTO.toUpperCase(), TEST_REL, TEST_PROTO + "://"
+ testHost + ":5683/fws/" + TENANT + "/" + TARGETID_BASE62 + "/" + ARTIFACTID_BASE62));
}
@Test
@Description("Verfies that the protocol of the statically defined hostname is replaced with the protocol of the request.")
public void urlGenerationWithProtocolFromRequest() throws URISyntaxException {
final String testHost = "ddi.host.com";
final UrlProtocol proto = new UrlProtocol();
proto.setRef("{protocolRequest}://{hostname}:{port}/fws/{tenant}/{targetIdBase62}/{artifactIdBase62}");
properties.getProtocols().put("download-http", proto);
final List<ArtifactUrl> urls = urlHandlerUnderTest.getUrls(placeholder, ApiType.DDI,
new URI("https://" + testHost));
assertThat(urls).containsExactly(new ArtifactUrl("http".toUpperCase(), "download-http",
"https://localhost:8080/fws/" + TENANT + "/" + TARGETID_BASE62 + "/" + ARTIFACTID_BASE62));
}
@Test
@Description("Verfies that the port of the statically defined hostname is replaced with the port of the request.")