common/app/implicits/Requests.scala (90 lines of code) (raw):
package implicits
import com.gu.facia.client.models.{
EU27Territory,
NZTerritory,
TargetedTerritory,
USEastCoastTerritory,
USWestCoastTerritory,
AUVictoriaTerritory,
AUQueenslandTerritory,
AUNewSouthWalesTerritory,
}
import conf.Configuration
import play.api.mvc.RequestHeader
sealed trait RequestFormat
case object HtmlFormat extends RequestFormat
case object JsonFormat extends RequestFormat
case object EmailFormat extends RequestFormat
case object AmpFormat extends RequestFormat
case object AppsFormat extends RequestFormat
case class TerritoryHeader(territory: TargetedTerritory, headerString: String)
object GUHeaders {
val TERRITORY_HEADER = "X-GU-Territory"
}
trait Requests {
val EMAIL_SUFFIX = "/email"
val HEADLINE_SUFFIX = "/headline.txt"
val EMAIL_JSON_SUFFIX = ".emailjson"
val EMAIL_TXT_SUFFIX = ".emailtxt"
val territoryHeaders: List[TerritoryHeader] = List(
TerritoryHeader(EU27Territory, EU27Territory.id),
TerritoryHeader(NZTerritory, NZTerritory.id),
TerritoryHeader(USEastCoastTerritory, USEastCoastTerritory.id),
TerritoryHeader(USWestCoastTerritory, USWestCoastTerritory.id),
TerritoryHeader(AUVictoriaTerritory, AUVictoriaTerritory.id),
TerritoryHeader(AUQueenslandTerritory, AUQueenslandTerritory.id),
TerritoryHeader(AUNewSouthWalesTerritory, AUNewSouthWalesTerritory.id),
)
implicit class RichRequestHeader(r: RequestHeader) {
def getParameter(name: String): Option[String] = r.queryString.get(name).flatMap(_.headOption)
def getParameters(name: String): Seq[String] = r.queryString.getOrElse(name, Nil)
def getIntParameter(name: String): Option[Int] = getParameter(name).map(_.toInt)
def getBooleanParameter(name: String): Option[Boolean] = getParameter(name).map(_.toBoolean)
def getRequestFormat: RequestFormat =
if (isJson) JsonFormat
else if (isEmail) EmailFormat
else if (isAmp) AmpFormat
else if (isApps) AppsFormat
else HtmlFormat
lazy val isJson: Boolean = r.getQueryString("callback").isDefined || r.path.endsWith(".json")
lazy val isEmailJson: Boolean = r.path.endsWith(EMAIL_JSON_SUFFIX)
lazy val isEmailTxt: Boolean = r.path.endsWith(EMAIL_TXT_SUFFIX)
lazy val isLazyLoad: Boolean =
r.getQueryString("lazy-load").isDefined && !r.getQueryString("lazy-load").contains("false")
lazy val isRss: Boolean = r.path.endsWith("/rss")
lazy val isAmp: Boolean = r
.getQueryString("amp")
.isDefined || (!r.host.isEmpty && r.host == Configuration.amp.host) || r.getQueryString("dcr").contains("amp")
lazy val isApps: Boolean = r.getQueryString("dcr").contains("apps")
lazy val isEmail: Boolean = r.getQueryString("format").exists(_.contains("email")) || r.path.endsWith(
EMAIL_SUFFIX,
) || isEmailJson || isEmailTxt
lazy val isHeadlineText: Boolean =
r.getQueryString("format").contains("email-headline") || r.path.endsWith(HEADLINE_SUFFIX)
lazy val isModified = isJson || isRss || isEmail || isHeadlineText
lazy val pathWithoutModifiers: String =
if (isEmail) r.path.stripSuffix(EMAIL_SUFFIX)
else r.path.stripSuffix("/all")
lazy val hasParameters: Boolean = r.queryString.nonEmpty
lazy val isHealthcheck: Boolean =
r.headers.keys.exists(_ equalsIgnoreCase "X-Gu-Management-Healthcheck") || r.path == "/_healthcheck"
lazy val rawQueryStringOption: Option[String] = if (r.rawQueryString.nonEmpty) Some(r.rawQueryString) else None
// This is a header reliably set by jQuery for AJAX requests used in facia-tool
lazy val isXmlHttpRequest: Boolean = r.headers.get("X-Requested-With").contains("XMLHttpRequest")
lazy val isCrosswordFront: Boolean = r.path.endsWith("/crosswords")
lazy val campaignCode: Option[String] = r.getQueryString("CMP")
lazy val isAdFree: Boolean = r.headers.keys.exists(_ equalsIgnoreCase "X-Gu-Commercial-Ad-Free")
lazy val referrer: Option[String] = r.headers.get("referer")
// the X-GU-Territory header is used by the facia app to determine whether or not to render containers
// targeted only at a specific region e.g. a new zealand-only container
lazy val territories: List[TargetedTerritory] = r.headers
.get(GUHeaders.TERRITORY_HEADER)
.map { r =>
territoryHeaders.filter(th => r.contains(th.headerString)).map(_.territory)
}
.getOrElse(List())
// dotcom-rendering (DCR) parameters
lazy val forceDCROff: Boolean = r.getQueryString("dcr").contains("false")
// don't check for .contains(true) so people can be lazy
lazy val forceDCR: Boolean = r.getQueryString("dcr").isDefined && !forceDCROff
lazy val forceLiveOff: Boolean = r.getQueryString("live").contains("false")
lazy val forceLive: Boolean = r.getQueryString("live").isDefined && !forceLiveOff
// slot machine
lazy val slotMachineFlags = r.getQueryString("slot-machine-flags").getOrElse("")
}
}
object Requests extends Requests