File tree Expand file tree Collapse file tree 2 files changed +63
-0
lines changed
src/io/iohk/scalanet/peergroup
ut/src/io/iohk/scalanet/peergroup Expand file tree Collapse file tree 2 files changed +63
-0
lines changed Original file line number Diff line number Diff line change
1
+ package io .iohk .scalanet .peergroup
2
+
3
+ import java .io .{BufferedReader , InputStreamReader }
4
+ import java .net .{InetAddress , URL }
5
+
6
+ import monix .eval .Task
7
+ import scala .util .control .NonFatal
8
+
9
+ /** Resolve the external address based on a list of URLs that each return the IP of the caller. */
10
+ class ExternalAddressResolver (urls : List [String ]) {
11
+ def resolve : Task [Option [InetAddress ]] =
12
+ ExternalAddressResolver .checkUrls(urls)
13
+ }
14
+
15
+ object ExternalAddressResolver {
16
+ val default = new ExternalAddressResolver (List (" http://checkip.amazonaws.com" , " http://bot.whatismyipaddress.com" ))
17
+
18
+ /** Retrieve the external address from a URL that returns a single line containing the IP. */
19
+ def checkUrl (url : String ): Task [InetAddress ] = Task .async { cb =>
20
+ try {
21
+ val ipCheckUrl = new URL (url)
22
+ val in : BufferedReader = new BufferedReader (new InputStreamReader (ipCheckUrl.openStream()))
23
+ cb.onSuccess(InetAddress .getByName(in.readLine()))
24
+ } catch {
25
+ case NonFatal (ex) => cb.onError(ex)
26
+ }
27
+ }
28
+
29
+ /** Try multiple URLs until an IP address is found. */
30
+ def checkUrls (urls : List [String ]): Task [Option [InetAddress ]] = {
31
+ if (urls.isEmpty) {
32
+ Task .now(None )
33
+ } else {
34
+ checkUrl(urls.head).attempt.flatMap {
35
+ case Left (_) =>
36
+ checkUrls(urls.tail)
37
+ case Right (value) =>
38
+ Task .now(Some (value))
39
+ }
40
+ }
41
+ }
42
+ }
Original file line number Diff line number Diff line change
1
+ package io .iohk .scalanet .peergroup
2
+
3
+ import org .scalatest ._
4
+ import scala .concurrent .duration ._
5
+ import monix .execution .Scheduler .Implicits .global
6
+
7
+ class ExternalAddressResolverSpec extends FlatSpec with Matchers {
8
+
9
+ behavior of " ExternalAddressResolver"
10
+
11
+ it should " resolve the external IP" in {
12
+ val maybeAddress = ExternalAddressResolver .default.resolve.runSyncUnsafe(5 .seconds)
13
+
14
+ maybeAddress should not be empty
15
+ maybeAddress.get.isLoopbackAddress shouldBe false
16
+ }
17
+
18
+ it should " return None if all resolutions fail" in {
19
+ ExternalAddressResolver .checkUrls(List (" " , " 404.html" )).runSyncUnsafe(1 .seconds) shouldBe empty
20
+ }
21
+ }
You can’t perform that action at this time.
0 commit comments