Skip to content

Commit c5654a1

Browse files
authored
Merge pull request #585 from arnaudgeiser/master
Better handling of REQUEST_URI_TOO_LONG/REQUEST_HEADER_FIELDS_TOO_LARGE
2 parents 2c882f8 + db5ab62 commit c5654a1

File tree

2 files changed

+49
-16
lines changed

2 files changed

+49
-16
lines changed

src/aleph/http/server.clj

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
[clojure.tools.logging :as log]
88
[clojure.string :as str]
99
[manifold.deferred :as d]
10-
[manifold.stream :as s])
10+
[manifold.stream :as s])
1111
(:import
1212
[java.util
1313
EnumSet
@@ -30,11 +30,12 @@
3030
ChannelHandlerContext
3131
ChannelHandler
3232
ChannelPipeline]
33-
[io.netty.channel.embedded EmbeddedChannel]
3433
[io.netty.handler.stream ChunkedWriteHandler]
3534
[io.netty.handler.timeout
3635
IdleState
3736
IdleStateEvent]
37+
[io.netty.handler.codec
38+
TooLongFrameException]
3839
[io.netty.handler.codec.http
3940
DefaultFullHttpResponse
4041
HttpContent HttpHeaders HttpUtil
@@ -52,7 +53,6 @@
5253
TextWebSocketFrame
5354
BinaryWebSocketFrame
5455
CloseWebSocketFrame
55-
WebSocketFrame
5656
WebSocketFrameAggregator]
5757
[io.netty.handler.codec.http.websocketx.extensions.compression
5858
WebSocketServerCompressionHandler]
@@ -215,15 +215,31 @@
215215
(defn invalid-request? [^HttpRequest req]
216216
(-> req .decoderResult .isFailure))
217217

218-
(defn reject-invalid-request [ctx ^HttpRequest req]
219-
(d/chain
220-
(netty/write-and-flush ctx
221-
(DefaultFullHttpResponse.
222-
HttpVersion/HTTP_1_1
218+
(defn- ^HttpResponseStatus cause->status [^Throwable cause]
219+
(if (instance? TooLongFrameException cause)
220+
(let [message (.getMessage cause)]
221+
(cond
222+
(.startsWith message "An HTTP line is larger than")
223223
HttpResponseStatus/REQUEST_URI_TOO_LONG
224-
(-> req .decoderResult .cause .getMessage netty/to-byte-buf)))
225-
netty/wrap-future
226-
(fn [_] (netty/close ctx))))
224+
225+
(.startsWith message "HTTP header is larger than")
226+
HttpResponseStatus/REQUEST_HEADER_FIELDS_TOO_LARGE
227+
228+
:else
229+
HttpResponseStatus/BAD_REQUEST))
230+
HttpResponseStatus/BAD_REQUEST))
231+
232+
(defn reject-invalid-request [ctx ^HttpRequest req]
233+
(let [cause (-> req .decoderResult .cause)
234+
status (cause->status cause)]
235+
(d/chain
236+
(netty/write-and-flush ctx
237+
(DefaultFullHttpResponse.
238+
HttpVersion/HTTP_1_1
239+
status
240+
(-> cause .getMessage netty/to-byte-buf)))
241+
netty/wrap-future
242+
(fn [_] (netty/close ctx)))))
227243

228244
(defn ring-handler
229245
[ssl? handler rejected-handler executor buffer-capacity]

test/aleph/http_test.clj

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
(ns aleph.http-test
2-
(:use
3-
[clojure test])
42
(:require
3+
[clojure.string :as str]
4+
[clojure.test :refer [deftest testing is]]
55
[aleph
66
[http :as http]
77
[netty :as netty]
8-
[flow :as flow]]
8+
[flow :as flow]
9+
[tcp :as tcp]]
910
[byte-streams :as bs]
1011
[manifold.deferred :as d]
1112
[manifold.stream :as s])
@@ -253,9 +254,25 @@
253254
(apply d/zip)
254255
deref))))
255256

256-
(deftest test-overly-long-request
257+
(deftest test-overly-long-url
258+
(let [long-url (apply str "http://localhost:" port "/" (repeat 1e4 "a"))]
259+
(with-handler basic-handler
260+
(is (= 414 (:status @(http-get long-url)))))))
261+
262+
(deftest test-overly-long-header
263+
(let [url (str "http://localhost:" port)
264+
long-header-value (apply str (repeat 1e5 "a"))
265+
opts {:headers {"X-Long" long-header-value}}]
266+
(with-handler basic-handler
267+
(is (= 431 (:status @(http-get url opts)))))))
268+
269+
(deftest test-invalid-http-version-format
257270
(with-handler basic-handler
258-
(= 414 @(http-get (apply str "http://localhost:" port "/" (repeat 1e4 "a"))))))
271+
(let [client @(tcp/client {:host "localhost" :port port})
272+
_ @(s/put! client "GET / HTTP-1,1\r\n\r\n")
273+
response (bs/to-string @(s/take! client))]
274+
(is (str/starts-with? response "HTTP/1.1 400"))
275+
(s/close! client))))
259276

260277
(deftest test-echo
261278
(with-handler basic-handler

0 commit comments

Comments
 (0)