in src/main/java/com/amazonaws/neptune/auth/NeptuneNettyHttpSigV4Signer.java [101:177]
protected SdkHttpFullRequest toSignableRequest(final FullHttpRequest request)
throws NeptuneSigV4SignerException {
// make sure the request is not null and contains the minimal required set of information
checkNotNull(request, "The request must not be null");
checkNotNull(request.uri(), "The request URI must not be null");
checkNotNull(request.method(), "The request method must not be null");
// convert the headers to the internal API format
final HttpHeaders headers = request.headers();
final Map<String, List<String>> headersInternal = new HashMap<>();
String hostName = "";
// we don't want to add the Host header as the Signer always adds the host header.
for (String header : headers.names()) {
// Skip adding the Host header as the signing process will add one.
if (!header.equalsIgnoreCase(HOST)) {
headersInternal.put(header, Arrays.asList(headers.get(header)));
} else {
hostName = headers.get(header);
}
}
// convert the parameters to the internal API format
final URI uri = URI.create(request.uri());
final String queryStr = uri.getQuery();
final Map<String, List<String>> parametersInternal = new HashMap<>(extractParametersFromQueryString(queryStr));
// carry over the entity (or an empty entity, if no entity is provided)
final InputStream content;
final ByteBuf contentBuffer = request.content();
boolean hasContent = false;
try {
if (contentBuffer != null && contentBuffer.isReadable()) {
hasContent = true;
contentBuffer.retain();
byte[] bytes = new byte[contentBuffer.readableBytes()];
contentBuffer.getBytes(contentBuffer.readerIndex(), bytes);
content = new ByteArrayInputStream(bytes);
} else {
content = new StringEntity("").getContent();
}
} catch (UnsupportedEncodingException e) {
throw new NeptuneSigV4SignerException("Encoding of the input string failed", e);
} catch (IOException e) {
throw new NeptuneSigV4SignerException("IOException while accessing entity content", e);
} finally {
if (hasContent) {
contentBuffer.release();
}
}
if (StringUtils.isEmpty(hostName)) {
// try to extract hostname from the uri since hostname was not provided in the header.
final String authority = uri.getAuthority();
if (authority == null) {
throw new NeptuneSigV4SignerException("Unable to identify host information,"
+ " either hostname should be provided in the uri or should be passed as a header");
}
hostName = authority;
}
// Gremlin websocket requests don't contain protocol information. Here, http:// doesn't have any consequence
// other than letting the signer work with a full valid uri. The protocol is not used anywhere in signing.
final URI endpointUri = URI.create("http://" + hostName);
return convertToSignableRequest(
request.method().name(),
endpointUri,
uri.getPath(),
headersInternal,
parametersInternal,
content);
}