From 128b7f87b9b60ae6bfe938523bfac7461c744a41 Mon Sep 17 00:00:00 2001 From: Chris Baxter Date: Fri, 22 Jan 2016 09:50:33 -0500 Subject: [PATCH] !htt #19388 Removing use of InetAddress.getByName * Remove String apply methods for RemoteAddress (both scala and java) * Added unit test to show that hostnames in the address are treated as invalid by the parser * Added a unit test to show that invalid xff is added as a RawHeader instead of model class --- .../http/javadsl/model/RemoteAddress.java | 3 --- .../http/scaladsl/model/RemoteAddress.scala | 3 --- .../http/scaladsl/model/headers/headers.scala | 3 +-- .../engine/parsing/HttpHeaderParserSpec.scala | 4 ++++ .../impl/model/parser/HttpHeaderSpec.scala | 21 ++++++++++++------- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/akka-http-core/src/main/java/akka/http/javadsl/model/RemoteAddress.java b/akka-http-core/src/main/java/akka/http/javadsl/model/RemoteAddress.java index c8edb0539a..e20d5281e2 100644 --- a/akka-http-core/src/main/java/akka/http/javadsl/model/RemoteAddress.java +++ b/akka-http-core/src/main/java/akka/http/javadsl/model/RemoteAddress.java @@ -26,9 +26,6 @@ public abstract class RemoteAddress { public static RemoteAddress create(InetSocketAddress address) { return akka.http.scaladsl.model.RemoteAddress.apply(address); } - public static RemoteAddress create(String address) { - return akka.http.scaladsl.model.RemoteAddress.apply(address); - } public static RemoteAddress create(byte[] address) { return akka.http.scaladsl.model.RemoteAddress.apply(address); } diff --git a/akka-http-core/src/main/scala/akka/http/scaladsl/model/RemoteAddress.scala b/akka-http-core/src/main/scala/akka/http/scaladsl/model/RemoteAddress.scala index dedb49b8d8..9b99daad2f 100644 --- a/akka-http-core/src/main/scala/akka/http/scaladsl/model/RemoteAddress.scala +++ b/akka-http-core/src/main/scala/akka/http/scaladsl/model/RemoteAddress.scala @@ -45,9 +45,6 @@ object RemoteAddress { def isUnknown = false } - def apply(s: String): RemoteAddress = - try IP(InetAddress.getByName(s)) catch { case _: UnknownHostException ⇒ Unknown } - def apply(a: InetAddress, port: Option[Int] = None): IP = IP(a, port) def apply(a: InetSocketAddress): IP = IP(a.getAddress, Some(a.getPort)) diff --git a/akka-http-core/src/main/scala/akka/http/scaladsl/model/headers/headers.scala b/akka-http-core/src/main/scala/akka/http/scaladsl/model/headers/headers.scala index ed73cd3729..0fcedf76a7 100644 --- a/akka-http-core/src/main/scala/akka/http/scaladsl/model/headers/headers.scala +++ b/akka-http-core/src/main/scala/akka/http/scaladsl/model/headers/headers.scala @@ -896,8 +896,7 @@ final case class `WWW-Authenticate`(challenges: immutable.Seq[HttpChallenge]) ex } // http://en.wikipedia.org/wiki/X-Forwarded-For -object `X-Forwarded-For` extends ModeledCompanion[`X-Forwarded-For`] { - def apply(first: String, more: String*): `X-Forwarded-For` = apply(RemoteAddress(first), more.map(RemoteAddress(_)): _*) +object `X-Forwarded-For` extends ModeledCompanion[`X-Forwarded-For`] { def apply(first: RemoteAddress, more: RemoteAddress*): `X-Forwarded-For` = apply(immutable.Seq(first +: more: _*)) implicit val addressesRenderer = Renderer.defaultSeqRenderer[RemoteAddress] // cache } diff --git a/akka-http-core/src/test/scala/akka/http/impl/engine/parsing/HttpHeaderParserSpec.scala b/akka-http-core/src/test/scala/akka/http/impl/engine/parsing/HttpHeaderParserSpec.scala index 6425656459..aac82738bc 100644 --- a/akka-http-core/src/test/scala/akka/http/impl/engine/parsing/HttpHeaderParserSpec.scala +++ b/akka-http-core/src/test/scala/akka/http/impl/engine/parsing/HttpHeaderParserSpec.scala @@ -128,6 +128,10 @@ class HttpHeaderParserSpec extends WordSpec with Matchers with BeforeAndAfterAll parseAndCache("Origin: localhost:8080\r\nx")() shouldEqual RawHeader("origin", "localhost:8080") } + "parse and cache an X-Forwarded-For with a hostname in it as a RawHeader" in new TestSetup() { + parseAndCache("X-Forwarded-For: 1.2.3.4, akka.io\r\nx")() shouldEqual RawHeader("x-forwarded-for", "1.2.3.4, akka.io") + } + "parse and cache a raw header" in new TestSetup(primed = false) { insert("hello: bob", 'Hello) val (ixA, headerA) = parseLine("Fancy-Pants: foo\r\nx") diff --git a/akka-http-core/src/test/scala/akka/http/impl/model/parser/HttpHeaderSpec.scala b/akka-http-core/src/test/scala/akka/http/impl/model/parser/HttpHeaderSpec.scala index 92e9781845..3bc7fc5799 100644 --- a/akka-http-core/src/test/scala/akka/http/impl/model/parser/HttpHeaderSpec.scala +++ b/akka-http-core/src/test/scala/akka/http/impl/model/parser/HttpHeaderSpec.scala @@ -17,6 +17,7 @@ import MediaRanges._ import HttpCharsets._ import HttpEncodings._ import HttpMethods._ +import java.net.InetAddress class HttpHeaderSpec extends FreeSpec with Matchers { val `application/vnd.spray` = MediaType.applicationBinary("vnd.spray", MediaType.Compressible) @@ -545,14 +546,14 @@ class HttpHeaderSpec extends FreeSpec with Matchers { } "X-Forwarded-For" in { - "X-Forwarded-For: 1.2.3.4" =!= `X-Forwarded-For`("1.2.3.4") - "X-Forwarded-For: 234.123.5.6, 8.8.8.8" =!= `X-Forwarded-For`("234.123.5.6", "8.8.8.8") - "X-Forwarded-For: 1.2.3.4, unknown" =!= `X-Forwarded-For`(RemoteAddress("1.2.3.4"), RemoteAddress.Unknown) - "X-Forwarded-For: 192.0.2.43, 2001:db8:cafe:0:0:0:0:17" =!= `X-Forwarded-For`("192.0.2.43", "2001:db8:cafe::17") - "X-Forwarded-For: 1234:5678:9abc:def1:2345:6789:abcd:ef00" =!= `X-Forwarded-For`("1234:5678:9abc:def1:2345:6789:abcd:ef00") - "X-Forwarded-For: 1234:567:9a:d:2:67:abc:ef00" =!= `X-Forwarded-For`("1234:567:9a:d:2:67:abc:ef00") + "X-Forwarded-For: 1.2.3.4" =!= `X-Forwarded-For`(remoteAddress("1.2.3.4")) + "X-Forwarded-For: 234.123.5.6, 8.8.8.8" =!= `X-Forwarded-For`(remoteAddress("234.123.5.6"), remoteAddress("8.8.8.8")) + "X-Forwarded-For: 1.2.3.4, unknown" =!= `X-Forwarded-For`(remoteAddress("1.2.3.4"), RemoteAddress.Unknown) + "X-Forwarded-For: 192.0.2.43, 2001:db8:cafe:0:0:0:0:17" =!= `X-Forwarded-For`(remoteAddress("192.0.2.43"), remoteAddress("2001:db8:cafe::17")) + "X-Forwarded-For: 1234:5678:9abc:def1:2345:6789:abcd:ef00" =!= `X-Forwarded-For`(remoteAddress("1234:5678:9abc:def1:2345:6789:abcd:ef00")) + "X-Forwarded-For: 1234:567:9a:d:2:67:abc:ef00" =!= `X-Forwarded-For`(remoteAddress("1234:567:9a:d:2:67:abc:ef00")) "X-Forwarded-For: 2001:db8:85a3::8a2e:370:7334" =!=> "2001:db8:85a3:0:0:8a2e:370:7334" - "X-Forwarded-For: 1:2:3:4:5:6:7:8" =!= `X-Forwarded-For`("1:2:3:4:5:6:7:8") + "X-Forwarded-For: 1:2:3:4:5:6:7:8" =!= `X-Forwarded-For`(remoteAddress("1:2:3:4:5:6:7:8")) "X-Forwarded-For: ::2:3:4:5:6:7:8" =!=> "0:2:3:4:5:6:7:8" "X-Forwarded-For: ::3:4:5:6:7:8" =!=> "0:0:3:4:5:6:7:8" "X-Forwarded-For: ::4:5:6:7:8" =!=> "0:0:0:4:5:6:7:8" @@ -574,6 +575,10 @@ class HttpHeaderSpec extends FreeSpec with Matchers { "X-Forwarded-For: 1:2:3:4:5::7:8" =!=> "1:2:3:4:5:0:7:8" "X-Forwarded-For: 1:2:3:4:5:6::8" =!=> "1:2:3:4:5:6:0:8" "X-Forwarded-For: ::" =!=> "0:0:0:0:0:0:0:0" + "X-Forwarded-For: 1.2.3.4, akka.io" =!= + ErrorInfo( + "Illegal HTTP header 'X-Forwarded-For': Invalid input 'k', expected HEXDIG, h8, ':', ch16o or cc (line 1, column 11)", + "1.2.3.4, akka.io\n ^") } "RawHeader" in { @@ -663,4 +668,6 @@ class HttpHeaderSpec extends FreeSpec with Matchers { val info = result.errors.head fail(s"Input `${header.header}` failed to parse:\n${info.summary}\n${info.detail}") } + + def remoteAddress(ip: String) = RemoteAddress(InetAddress.getByName(ip)) }