Skip to content

Commit

Permalink
Merge pull request #5 from multiplexd/feature-http-proxy
Browse files Browse the repository at this point in the history
Add HTTP proxy support for akka-http HTTP requests
  • Loading branch information
CO2-Codes authored Apr 3, 2021
2 parents 56e4471 + 9583714 commit d68f086
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 7 deletions.
13 changes: 13 additions & 0 deletions example.conf
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ link-listener {
}

youtube-api-key = "" // Optional, if set, tries to parse youtube link titles using the youtube API which seems more stable than the website

use-http-proxy = true // Optional, if set, will use the default akka http proxy settings for all non-youtube/non-twitter http requests

// Additionally, akka needs to be told the proxy server's host and port.
// For example, putting the following configuration in "akka.conf"
//
// akka.http.client.proxy.https {
// host = "127.0.0.1"
// port = 8888
// }
//
// and adding "-Dconfig.file=akka.conf" to the JVM command line will result
// in akka using the HTTP proxy listening on port 8888 on localhost.
}

pronoun-listener {
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/codes/co2/ircbot/config/BotConfiguration.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ case class GeneralConfig(

case class TwitterApi(consumerToken: ConsumerToken, accessToken: AccessToken)

case class LinkListenerConfig(boldTitles: Option[Boolean], twitterApi: Option[TwitterApi], youtubeApiKey: Option[String])
case class LinkListenerConfig(boldTitles: Option[Boolean], twitterApi: Option[TwitterApi], youtubeApiKey: Option[String], useHttpProxy: Option[Boolean])

case class AdminListenerConfig(helpText: String, puppetMasters: Option[Seq[String]])

Expand All @@ -50,7 +50,7 @@ object BotConfiguration {
.at("link-listener").load[LinkListenerConfig]
.fold(failures => {
log.info(s"Could not load link-listener config, reason ${failures.toList.map(_.description)} Using default config.")
LinkListenerConfig(None, None, None)
LinkListenerConfig(None, None, None, None)
}, success => success)

def loadAdminListenerConfig(path: Path): AdminListenerConfig = ConfigSource.default(ConfigSource.file(path))
Expand Down
9 changes: 5 additions & 4 deletions src/main/scala/codes/co2/ircbot/http/HttpClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package codes.co2.ircbot.http
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import akka.http.scaladsl.settings.ConnectionPoolSettings
import akka.stream.scaladsl.Sink
import akka.util.ByteString
import org.slf4j.{Logger, LoggerFactory}
Expand All @@ -14,7 +15,7 @@ class HttpClient(implicit system: ActorSystem) {
val log: Logger = LoggerFactory.getLogger(getClass)
implicit val ec: ExecutionContext = system.dispatcher

def getTitle(url: String): Future[Option[String]] = {
def getTitle(url: String)(implicit s: ConnectionPoolSettings): Future[Option[String]] = {
getPage(url).map(pageOpt => pageOpt.flatMap(page =>
{
val titleOpt = TitleParser.findTitle(page)
Expand All @@ -23,8 +24,8 @@ class HttpClient(implicit system: ActorSystem) {
}))
}

def getPage(url: String, alreadyRedirected: Boolean = false): Future[Option[String]] = {
Http().singleRequest(HttpRequest(uri = url))
def getPage(url: String, alreadyRedirected: Boolean = false)(implicit s: ConnectionPoolSettings): Future[Option[String]] = {
Http().singleRequest(HttpRequest(uri = url), settings = s)
.flatMap(response => {
val result = response.status match {
case status if status.isRedirection() && !alreadyRedirected =>
Expand Down Expand Up @@ -71,7 +72,7 @@ class HttpClient(implicit system: ActorSystem) {
).runWith(Sink.fold(ByteString.empty)(_ ++ _)).map(byteString => Some(byteString.utf8String))
}

private def redirect(url: String, response: HttpResponse) = {
private def redirect(url: String, response: HttpResponse)(implicit s: ConnectionPoolSettings) = {
response.headers.find(header => header.is("location")).map(
header => {
log.info(s"redirecting from $url to ${header.value}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package codes.co2.ircbot.listeners.links

import akka.actor.ActorSystem
import akka.http.scaladsl.ClientTransport
import akka.http.scaladsl.settings.{ConnectionPoolSettings, ClientConnectionSettings}
import codes.co2.ircbot.config.{GeneralConfig, LinkListenerConfig}
import codes.co2.ircbot.http.{HttpClient, TitleParser}
import codes.co2.ircbot.listeners.GenericListener
Expand All @@ -19,10 +22,17 @@ import scala.jdk.CollectionConverters._
import scala.util.control.NonFatal

class LinkListener(httpClient: HttpClient, config: LinkListenerConfig, generalConfig: GeneralConfig)(implicit
ec: ExecutionContext
ec: ExecutionContext,
system: ActorSystem
) extends GenericListener(generalConfig) {
val log: Logger = LoggerFactory.getLogger(getClass)

implicit val httpSettings: ConnectionPoolSettings = if (config.useHttpProxy.getOrElse(false)) {
ConnectionPoolSettings(system)
.withConnectionSettings(ClientConnectionSettings(system)
.withTransport(ClientTransport.httpsProxy()))
} else ConnectionPoolSettings(system)

val twitterClientOpt: Option[TwitterRestClient] =
config.twitterApi.map { twitterApi =>
log.info("Starting twitter client.")
Expand Down

0 comments on commit d68f086

Please sign in to comment.