From e166f96094c3619c8cfb7c47f61fa600794340a6 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Tue, 25 Apr 2023 16:00:21 +0530 Subject: [PATCH] ssvm: fix post request header case mismatch (#7445) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #7442 With d74f64a2e16 key for the host header was changed to lowercase which is causing host be null while processing upload in SSVM Signed-off-by: Abhishek Kumar Co-authored-by: João Jandre <48719461+JoaoJandre@users.noreply.github.com> --- .../resource/HttpUploadServerHandler.java | 85 ++++++++++--------- .../resource/HttpUploadServerHandlerTest.java | 74 ++++++++++++++++ 2 files changed, 118 insertions(+), 41 deletions(-) create mode 100644 services/secondary-storage/server/src/test/java/org/apache/cloudstack/storage/resource/HttpUploadServerHandlerTest.java diff --git a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java index 8e3e4908dce..aec1560f411 100644 --- a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java +++ b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java @@ -18,16 +18,15 @@ package org.apache.cloudstack.storage.resource; import static io.netty.buffer.Unpooled.copiedBuffer; import static io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION; -import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH; import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE; import java.io.IOException; import java.net.URI; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import io.netty.handler.codec.DecoderException; import org.apache.cloudstack.storage.template.UploadEntity; import org.apache.cloudstack.utils.imagestore.ImageStoreUtil; import org.apache.commons.lang3.StringUtils; @@ -41,6 +40,7 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpContent; @@ -79,16 +79,46 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler getUploadRequestUsefulHeaders(HttpHeaders headers) { + Map headerMap = new HashMap<>(); + for (Entry entry : headers) { + UploadHeader headerType = UploadHeader.fromName(entry.getKey()); + if (headerType != null) { + headerMap.put(headerType, entry.getValue()); + } + } + for (UploadHeader type : UploadHeader.values()) { + logger.info(String.format("HEADER: %s=%s", type, headerMap.get(type))); + } + return headerMap; + } + public HttpUploadServerHandler(NfsSecondaryStorageResource storageResource) { this.storageResource = storageResource; } @@ -123,36 +153,8 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler entry : request.headers()) { - switch (entry.getKey()) { - case HEADER_SIGNATURE: - signature = entry.getValue(); - break; - case HEADER_METADATA: - metadata = entry.getValue(); - break; - case HEADER_EXPIRES: - expires = entry.getValue(); - break; - case HEADER_HOST: - hostname = entry.getValue(); - break; - case HttpHeaders.Names.CONTENT_LENGTH: - contentLength = Long.parseLong(entry.getValue()); - break; - } - } - logger.info("HEADER: signature=" + signature); - logger.info("HEADER: metadata=" + metadata); - logger.info("HEADER: expires=" + expires); - logger.info("HEADER: hostname=" + hostname); - logger.info("HEADER: content-length=" + contentLength); + Map headers = getUploadRequestUsefulHeaders(request.headers()); + long contentLength = headers.get(UploadHeader.CONTENT_LENGTH) != null ? Long.parseLong(headers.get(UploadHeader.CONTENT_LENGTH)) : 0; QueryStringDecoder decoderQuery = new QueryStringDecoder(uri); Map> uriAttributes = decoderQuery.parameters(); uuid = uriAttributes.get("uuid").get(0); @@ -160,9 +162,10 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler headers = httpUploadServerHandler.getUploadRequestUsefulHeaders(request); + Assert.assertEquals(hostHeaderValue, headers.get(HttpUploadServerHandler.UploadHeader.HOST)); + } + + @Test + public void testGetUploadRequestUsefulHeadersHeaderKeyDifferentCase() { + String host = "SomeHost"; + runGetUploadRequestUsefulHeadersTestForHost(HttpUploadServerHandler.UploadHeader.HOST.getName(), host); + runGetUploadRequestUsefulHeadersTestForHost(HttpUploadServerHandler.UploadHeader.HOST.getName().toUpperCase(), host); + runGetUploadRequestUsefulHeadersTestForHost("X-Forwarded-Host", host); + } + + @Test + public void testGetUploadRequestUsefulHeadersAllKeys() { + HttpHeaders request = new DefaultHttpHeaders(); + String sign = "Sign"; + String metadata = "met"; + String expires = "ex"; + String host = "SomeHost"; + long contentLength = 100L; + request.add("x-Signature", sign); + request.add("X-metadata", metadata); + request.add("X-EXPIRES", expires); + request.add("X-Forwarded-Host", host); + request.add(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(contentLength)); + Map headers = httpUploadServerHandler.getUploadRequestUsefulHeaders(request); + Assert.assertEquals(sign, headers.get(HttpUploadServerHandler.UploadHeader.SIGNATURE)); + Assert.assertEquals(metadata, headers.get(HttpUploadServerHandler.UploadHeader.METADATA)); + Assert.assertEquals(expires, headers.get(HttpUploadServerHandler.UploadHeader.EXPIRES)); + Assert.assertEquals(host, headers.get(HttpUploadServerHandler.UploadHeader.HOST)); + Assert.assertEquals(String.valueOf(contentLength), headers.get(HttpUploadServerHandler.UploadHeader.CONTENT_LENGTH)); + } +}