Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Requiring cognitect.aws.client.api from user ns fails #60

Closed
potetm opened this issue Feb 20, 2019 · 1 comment
Closed

Requiring cognitect.aws.client.api from user ns fails #60

potetm opened this issue Feb 20, 2019 · 1 comment
Labels
bug Something isn't working

Comments

@potetm
Copy link

potetm commented Feb 20, 2019

If you have a deps.edn:

{:paths ["src"]
 :deps {com.cognitect.aws/api {:mvn/version "0.8.253"}
        org.clojure/clojure {:mvn/version "1.9.0"}}}

and a src/user.clj:

(ns user
 (:require [cognitect.aws.client.api :as aws]))

The following command:

clj -r

Fails with

Exception in thread "main" java.lang.ExceptionInInitializerError
	at clojure.main.<clinit>(main.java:20)
Caused by: java.lang.ClassNotFoundException: clojure.edn, compiling:(cognitect/aws/service.clj:25:3)

It appears that there are a few places that use clojure.edn without requiring it. This works most of the time, but not if you have requires (or transient requires) in your user ns.

@dchelimsky dchelimsky added the bug Something isn't working label Feb 20, 2019
@dchelimsky
Copy link
Contributor

Released in 0.8.266

scottbale pushed a commit that referenced this issue Dec 23, 2024
Problem:

We can't control some HTTP headers (or pseudo-headers in HTTP/2) directly, like `Host` (in HTTP/1.1) or `:authority` (in HTTP/2), because these headers are managed by JDK's HttpClient. However, the value of these headers must be predictable, because they affect the output of AWS4-HMAC-SHA256 (i.e. `Host` is a signed header).

HTTP/2 requires the `:authority` pseudo-header to be present, and its value is used by AWS to verify the signature (instead of the `Host` header from HTTP/1.1).

There is a small difference in behavior in JDK's HttpClient when issuing an HTTP/1.1 vs an HTTP/2 request:
- for HTTP/1.1 requests, the `Host` header is derived from an InetSocketAddress and is never included if it matches the default port for the protocol [1]
- for HTTP/2 requests, the `:authority` header is derived from a URI, and it's always included if it was explicitly set (even if the explicitly set value matches the default port for the protocol) [2]

We explicitly set the port for all requests to 443, and this small difference between HTTP/1.1 and HTTP/2 clients causes invalid signatures on HTTP/2 services [3].

Solution:

Do not include the default port in the URI generated when using JDK's HttpClient. This generates the correct signature in HTTP/1.1 (using `Host`) and in HTTP/2 (using `:authority`) requests.

[1] https://github.com/openjdk/jdk/blob/890adb6410dab4606a4f26a942aed02fb2f55387/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java#L237-L241
[2] https://github.com/openjdk/jdk/blob/890adb6410dab4606a4f26a942aed02fb2f55387/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java#L818-L822
[3] #261
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants