raphaëλ
raphaëλ

Reputation: 6523

spray-http redirect to other subdomain

I need to redirect all traffic without a subdomain to the www subdomain (e.g, foo.com->www.foo.com).

The code below is working, but i know redirecting code can be brittle and might bring security flaws.

Is this a proper way of achieving the above, or is there perhaps another set of directives i should use?

host("^(?!www).+".r) { h =>
  unmatchedPath { p =>
    schemeName { s =>
      redirect(s"$s://www.$h$p", StatusCodes.MovedPermanently)
    }
  }
}

Edit: changed StatusCodes.SeeOther to StatusCodes.MovedPermanently

Upvotes: 1

Views: 93

Answers (1)

raphaëλ
raphaëλ

Reputation: 6523

MY first error was using the wrong status code (StatusCodes.SeeOther instead of StatusCodes.MovedPermanently), the second was only using the path part of the url

The version below passing my set of tests (see further below):

host("^(?!www).+".r) { h =>
  unmatchedPath { p =>
    requestUri { s =>
      val r = s.withHost(s"www.$h")
      redirect(r, StatusCodes.MovedPermanently)
    }
  }
}

This passes the test below

"Redirect correctly" in {
    "request"                       | "redirect"                          |
    u("http://acme.com")            ! u("http://www.acme.com")            |
    u("http://foo.com")             ! u("http://www.foo.com")             |
    u("http://acme.com/search?a=1") ! u("http://www.acme.com/search?a=1") |
    u("http://acme.com/search#abc") ! u("http://www.acme.com/search#abc") |
    u("http://acme.com/service/")   ! u("http://www.acme.com/service/")   |
    u("https://acme.com")           ! u("https://www.acme.com")           |> { (a :java.net.URI, b :java.net.URI) => {
      Get(a.toString) ~> wholeRoute ~> check {
        status === MovedPermanently
        header("Location").get.value == b.toString
      }

    }
  }
}

Upvotes: 0

Related Questions