Merge pull request #17767 from spray/w/various-small-improvements
Various small improvements
This commit is contained in:
commit
e70b8c3e48
6 changed files with 109 additions and 24 deletions
|
|
@ -28,6 +28,14 @@ public abstract class HttpCookie {
|
|||
false, false,
|
||||
Util.<String>scalaNone());
|
||||
}
|
||||
public static HttpCookie create(String name, String value, Option<String> domain, Option<String> path) {
|
||||
return new akka.http.scaladsl.model.headers.HttpCookie(
|
||||
name, value,
|
||||
Util.<akka.http.scaladsl.model.DateTime>scalaNone(), Util.scalaNone(),
|
||||
domain.asScala(), path.asScala(),
|
||||
false, false,
|
||||
Util.<String>scalaNone());
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
public static HttpCookie create(
|
||||
String name,
|
||||
|
|
@ -49,4 +57,39 @@ public abstract class HttpCookie {
|
|||
httpOnly,
|
||||
extension.asScala());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this HttpCookie instance with the given expiration set.
|
||||
*/
|
||||
public abstract HttpCookie withExpires(DateTime dateTime);
|
||||
|
||||
/**
|
||||
* Returns a copy of this HttpCookie instance with the given max age set.
|
||||
*/
|
||||
public abstract HttpCookie withMaxAge(long maxAge);
|
||||
|
||||
/**
|
||||
* Returns a copy of this HttpCookie instance with the given domain set.
|
||||
*/
|
||||
public abstract HttpCookie withDomain(String domain);
|
||||
|
||||
/**
|
||||
* Returns a copy of this HttpCookie instance with the given path set.
|
||||
*/
|
||||
public abstract HttpCookie withPath(String path);
|
||||
|
||||
/**
|
||||
* Returns a copy of this HttpCookie instance with the given secure flag set.
|
||||
*/
|
||||
public abstract HttpCookie withSecure(boolean secure);
|
||||
|
||||
/**
|
||||
* Returns a copy of this HttpCookie instance with the given http-only flag set.
|
||||
*/
|
||||
public abstract HttpCookie withHttpOnly(boolean httpOnly);
|
||||
|
||||
/**
|
||||
* Returns a copy of this HttpCookie instance with the given extension set.
|
||||
*/
|
||||
public abstract HttpCookie withExtension(String extension);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,8 @@ package akka.http.javadsl.model.headers;
|
|||
public abstract class RawHeader extends akka.http.scaladsl.model.HttpHeader {
|
||||
public abstract String name();
|
||||
public abstract String value();
|
||||
|
||||
public static RawHeader create(String name, String value) {
|
||||
return new akka.http.scaladsl.model.headers.RawHeader(name, value);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
package akka.http.scaladsl.model.headers
|
||||
|
||||
import akka.http.javadsl.model.headers
|
||||
import akka.parboiled2.CharPredicate
|
||||
import akka.japi.{ Option ⇒ JOption }
|
||||
import akka.http.scaladsl.model.DateTime
|
||||
|
|
@ -77,6 +78,20 @@ final case class HttpCookie(
|
|||
def getMaxAge: JOption[java.lang.Long] = maxAge.asJava
|
||||
/** Java API */
|
||||
def getExpires: JOption[jm.DateTime] = expires.asJava
|
||||
/** Java API */
|
||||
def withExpires(dateTime: jm.DateTime): headers.HttpCookie = copy(expires = Some(dateTime.asScala))
|
||||
/** Java API */
|
||||
def withDomain(domain: String): headers.HttpCookie = copy(domain = Some(domain))
|
||||
/** Java API */
|
||||
def withPath(path: String): headers.HttpCookie = copy(path = Some(path))
|
||||
/** Java API */
|
||||
def withMaxAge(maxAge: Long): headers.HttpCookie = copy(maxAge = Some(maxAge))
|
||||
/** Java API */
|
||||
def withSecure(secure: Boolean): headers.HttpCookie = copy(secure = secure)
|
||||
/** Java API */
|
||||
def withHttpOnly(httpOnly: Boolean): headers.HttpCookie = copy(httpOnly = httpOnly)
|
||||
/** Java API */
|
||||
def withExtension(extension: String): headers.HttpCookie = copy(extension = Some(extension))
|
||||
}
|
||||
|
||||
object HttpCookie {
|
||||
|
|
|
|||
|
|
@ -53,16 +53,16 @@ class PathDirectivesSpec extends RoutingSpec with Inside {
|
|||
val test = testFor(pathPrefix("ab[cd]+".r) { echoCaptureAndUnmatchedPath })
|
||||
"reject [/bar]" in test()
|
||||
"reject [/ab/cd]" in test()
|
||||
"reject [/abcdef]" in test("abcd:ef")
|
||||
"reject [/abcdd/ef]" in test("abcdd:/ef")
|
||||
"accept [/abcdef]" in test("abcd:ef")
|
||||
"accept [/abcdd/ef]" in test("abcdd:/ef")
|
||||
}
|
||||
|
||||
"""pathPrefix("ab(cd)".r)""" should {
|
||||
val test = testFor(pathPrefix("ab(cd)+".r) { echoCaptureAndUnmatchedPath })
|
||||
"reject [/bar]" in test()
|
||||
"reject [/ab/cd]" in test()
|
||||
"reject [/abcdef]" in test("cd:ef")
|
||||
"reject [/abcde/fg]" in test("cd:e/fg")
|
||||
"accept [/abcdef]" in test("cd:ef")
|
||||
"accept [/abcde/fg]" in test("cd:e/fg")
|
||||
}
|
||||
|
||||
"pathPrefix(regex)" should {
|
||||
|
|
@ -132,40 +132,40 @@ class PathDirectivesSpec extends RoutingSpec with Inside {
|
|||
val test = testFor(pathPrefix(separateOnSlashes("a/b")) { echoUnmatchedPath })
|
||||
"accept [/a/b]" in test("")
|
||||
"accept [/a/b/]" in test("/")
|
||||
"accept [/a/c]" in test()
|
||||
"reject [/a/c]" in test()
|
||||
}
|
||||
"""pathPrefix(separateOnSlashes("abc"))""" should {
|
||||
val test = testFor(pathPrefix(separateOnSlashes("abc")) { echoUnmatchedPath })
|
||||
"accept [/abc]" in test("")
|
||||
"accept [/abcdef]" in test("def")
|
||||
"accept [/ab]" in test()
|
||||
"reject [/ab]" in test()
|
||||
}
|
||||
|
||||
"""pathPrefixTest("a" / Segment ~ Slash)""" should {
|
||||
val test = testFor(pathPrefixTest("a" / Segment ~ Slash) { echoCaptureAndUnmatchedPath })
|
||||
"accept [/a/bc/]" in test("bc:/a/bc/")
|
||||
"accept [/a/bc]" in test()
|
||||
"accept [/a/]" in test()
|
||||
"reject [/a/bc]" in test()
|
||||
"reject [/a/]" in test()
|
||||
}
|
||||
|
||||
"""pathSuffix("edit" / Segment)""" should {
|
||||
val test = testFor(pathSuffix("edit" / Segment) { echoCaptureAndUnmatchedPath })
|
||||
"accept [/orders/123/edit]" in test("123:/orders/")
|
||||
"accept [/orders/123/ed]" in test()
|
||||
"accept [/edit]" in test()
|
||||
"reject [/orders/123/ed]" in test()
|
||||
"reject [/edit]" in test()
|
||||
}
|
||||
|
||||
"""pathSuffix("foo" / "bar" ~ "baz")""" should {
|
||||
val test = testFor(pathSuffix("foo" / "bar" ~ "baz") { echoUnmatchedPath })
|
||||
"accept [/orders/barbaz/foo]" in test("/orders/")
|
||||
"accept [/orders/bazbar/foo]" in test()
|
||||
"reject [/orders/bazbar/foo]" in test()
|
||||
}
|
||||
|
||||
"pathSuffixTest(Slash)" should {
|
||||
val test = testFor(pathSuffixTest(Slash) { echoUnmatchedPath })
|
||||
"accept [/]" in test("/")
|
||||
"accept [/foo/]" in test("/foo/")
|
||||
"accept [/foo]" in test()
|
||||
"reject [/foo]" in test()
|
||||
}
|
||||
|
||||
"""pathPrefix("foo" | "bar")""" should {
|
||||
|
|
@ -242,6 +242,20 @@ class PathDirectivesSpec extends RoutingSpec with Inside {
|
|||
}
|
||||
}
|
||||
|
||||
"""rawPathPrefix(Slash ~ "a" / Segment ~ Slash)""" should {
|
||||
val test = testFor(rawPathPrefix(Slash ~ "a" / Segment ~ Slash) { echoCaptureAndUnmatchedPath })
|
||||
"accept [/a/bc/]" in test("bc:")
|
||||
"reject [/a/bc]" in test()
|
||||
"reject [/ab/]" in test()
|
||||
}
|
||||
|
||||
"""rawPathPrefixTest(Slash ~ "a" / Segment ~ Slash)""" should {
|
||||
val test = testFor(rawPathPrefixTest(Slash ~ "a" / Segment ~ Slash) { echoCaptureAndUnmatchedPath })
|
||||
"accept [/a/bc/]" in test("bc:/a/bc/")
|
||||
"reject [/a/bc]" in test()
|
||||
"reject [/ab/]" in test()
|
||||
}
|
||||
|
||||
"PathMatchers" should {
|
||||
{
|
||||
val test = testFor(path(Rest.tmap { case Tuple1(s) ⇒ Tuple1(s.split('-').toList) }) { echoComplete })
|
||||
|
|
@ -270,8 +284,17 @@ class PathDirectivesSpec extends RoutingSpec with Inside {
|
|||
|
||||
case class testFor(route: Route) {
|
||||
def apply(expectedResponse: String = null): String ⇒ Unit = exampleString ⇒
|
||||
"\\[([^\\]]+)\\]".r.findFirstMatchIn(exampleString) match {
|
||||
case Some(uri) ⇒ Get(uri.group(1)) ~> route ~> check {
|
||||
"""(accept|reject)\s+\[([^\]]+)\]""".r.findFirstMatchIn(exampleString) match {
|
||||
case Some(uri) ⇒
|
||||
uri.group(1) match {
|
||||
case "accept" if expectedResponse eq null ⇒
|
||||
failTest("Example '" + exampleString + "' was missing an expectedResponse")
|
||||
case "reject" if expectedResponse ne null ⇒
|
||||
failTest("Example '" + exampleString + "' had an expectedResponse")
|
||||
case _ ⇒
|
||||
}
|
||||
|
||||
Get(uri.group(2)) ~> route ~> check {
|
||||
if (expectedResponse eq null) handled shouldEqual false
|
||||
else responseAs[String] shouldEqual expectedResponse
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ object PathMatcher extends ImplicitPathMatcherConstruction {
|
|||
else Unmatched
|
||||
}
|
||||
|
||||
/** Provoke implicit conversions to PathMatcher to be applied */
|
||||
def apply[L](magnet: PathMatcher[L]): PathMatcher[L] = magnet
|
||||
|
||||
implicit class PathMatcher1Ops[T](matcher: PathMatcher1[T]) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ package akka.http.scaladsl.unmarshalling
|
|||
|
||||
import scala.collection.immutable
|
||||
import scala.collection.immutable.VectorBuilder
|
||||
import scala.concurrent.ExecutionContext
|
||||
import akka.util.ByteString
|
||||
import akka.event.{ NoLogging, LoggingAdapter }
|
||||
import akka.stream.impl.fusing.IteratorInterpreter
|
||||
|
|
@ -21,9 +20,9 @@ import HttpCharsets._
|
|||
|
||||
trait MultipartUnmarshallers {
|
||||
|
||||
implicit def defaultMultipartGeneralUnmarshaller(implicit ec: ExecutionContext, log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.General] =
|
||||
implicit def defaultMultipartGeneralUnmarshaller(implicit log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.General] =
|
||||
multipartGeneralUnmarshaller(`UTF-8`)
|
||||
def multipartGeneralUnmarshaller(defaultCharset: HttpCharset)(implicit ec: ExecutionContext, log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.General] =
|
||||
def multipartGeneralUnmarshaller(defaultCharset: HttpCharset)(implicit log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.General] =
|
||||
multipartUnmarshaller[Multipart.General, Multipart.General.BodyPart, Multipart.General.BodyPart.Strict](
|
||||
mediaRange = `multipart/*`,
|
||||
defaultContentType = ContentTypes.`text/plain` withCharset defaultCharset,
|
||||
|
|
@ -32,7 +31,7 @@ trait MultipartUnmarshallers {
|
|||
createStrictBodyPart = Multipart.General.BodyPart.Strict,
|
||||
createStrict = Multipart.General.Strict)
|
||||
|
||||
implicit def multipartFormDataUnmarshaller(implicit ec: ExecutionContext, log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.FormData] =
|
||||
implicit def multipartFormDataUnmarshaller(implicit log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.FormData] =
|
||||
multipartUnmarshaller[Multipart.FormData, Multipart.FormData.BodyPart, Multipart.FormData.BodyPart.Strict](
|
||||
mediaRange = `multipart/form-data`,
|
||||
defaultContentType = ContentTypes.`application/octet-stream`,
|
||||
|
|
@ -41,9 +40,9 @@ trait MultipartUnmarshallers {
|
|||
createStrictBodyPart = (entity, headers) ⇒ Multipart.General.BodyPart.Strict(entity, headers).toFormDataBodyPart.get,
|
||||
createStrict = (_, parts) ⇒ Multipart.FormData.Strict(parts))
|
||||
|
||||
implicit def defaultMultipartByteRangesUnmarshaller(implicit ec: ExecutionContext, log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.ByteRanges] =
|
||||
implicit def defaultMultipartByteRangesUnmarshaller(implicit log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.ByteRanges] =
|
||||
multipartByteRangesUnmarshaller(`UTF-8`)
|
||||
def multipartByteRangesUnmarshaller(defaultCharset: HttpCharset)(implicit ec: ExecutionContext, log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.ByteRanges] =
|
||||
def multipartByteRangesUnmarshaller(defaultCharset: HttpCharset)(implicit log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.ByteRanges] =
|
||||
multipartUnmarshaller[Multipart.ByteRanges, Multipart.ByteRanges.BodyPart, Multipart.ByteRanges.BodyPart.Strict](
|
||||
mediaRange = `multipart/byteranges`,
|
||||
defaultContentType = ContentTypes.`text/plain` withCharset defaultCharset,
|
||||
|
|
@ -57,7 +56,7 @@ trait MultipartUnmarshallers {
|
|||
createBodyPart: (BodyPartEntity, List[HttpHeader]) ⇒ BP,
|
||||
createStreamed: (MultipartMediaType, Source[BP, Any]) ⇒ T,
|
||||
createStrictBodyPart: (HttpEntity.Strict, List[HttpHeader]) ⇒ BPS,
|
||||
createStrict: (MultipartMediaType, immutable.Seq[BPS]) ⇒ T)(implicit ec: ExecutionContext, log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[T] =
|
||||
createStrict: (MultipartMediaType, immutable.Seq[BPS]) ⇒ T)(implicit log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[T] =
|
||||
Unmarshaller { implicit ec ⇒
|
||||
entity ⇒
|
||||
if (entity.contentType.mediaType.isMultipart && mediaRange.matches(entity.contentType.mediaType)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue