protected SdkHttpFullRequest toSignableRequest()

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);
    }