Skip to content

Commit 3ee3c24

Browse files
committed
Handle REQUEST_URI_TOO_LONG/REQUEST_HEADER_FIELDS_TOO_LARGE
1 parent 49fce37 commit 3ee3c24

File tree

2 files changed

+48
-19
lines changed

2 files changed

+48
-19
lines changed

src/aleph/http/server.clj

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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 ^String (.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 & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
(ns aleph.http-test
2-
(:use
3-
[clojure test])
42
(:require
5-
[clojure.java.io :as io]
3+
[clojure.string :as str]
4+
[clojure.test :refer [deftest testing is]]
65
[aleph
76
[http :as http]
87
[netty :as netty]
9-
[flow :as flow]]
8+
[flow :as flow]
9+
[tcp :as tcp]]
1010
[byte-streams :as bs]
1111
[manifold.deferred :as d]
1212
[manifold.stream :as s])
1313
(:import
14-
[java.util.concurrent
15-
Executors]
1614
[java.io
17-
File
18-
ByteArrayInputStream]
15+
File]
1916
[java.util.zip
2017
GZIPInputStream
2118
ZipException]
@@ -251,8 +248,24 @@
251248
deref))))
252249

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

257270
(deftest test-echo
258271
(with-handler basic-handler

0 commit comments

Comments
 (0)