Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@
language : scala

scala:
- 2.11.8
- 2.12.1
- 2.11.12
- 2.12.10
- 2.13.1

cache:
directories:
- $HOME/.ivy2
- $HOME/.sbt

jdk:
- oraclejdk8
- openjdk8

script:
- sbt ++$TRAVIS_SCALA_VERSION -Dfile.encoding=UTF8 "project allProtocols" test
- sbt -Dfile.encoding=UTF8 "project allProtocols" "++$TRAVIS_SCALA_VERSION test"


9 changes: 5 additions & 4 deletions asn1/src/main/scala/spinoco/protocol/asn/ber/package.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package spinoco.protocol.asn
package spinoco.protocol
package asn

import scodec.bits.{BitVector, ByteVector}
import scodec.codecs.DiscriminatorCodec
Expand All @@ -23,11 +24,11 @@ package object ber {
Attempt.failure(Err.insufficientBits(8, bits.size))
} else {
Attempt.fromEither(
bits.acquire(2).right.flatMap{classTagBits =>
Try(BerClass(classTagBits.toInt(false))).toOption.toRight("Could not get class tag from: " + classTagBits).right.flatMap{ classTag =>
bits.acquire(2).flatMap{classTagBits =>
Try(BerClass(classTagBits.toInt(false))).toOption.toRight("Could not get class tag from: " + classTagBits).flatMap{ classTag =>
val constructed = bits.get(2)
val remaining = bits.drop(3)
remaining.acquire(5).right.flatMap { numberTagBits =>
remaining.acquire(5).flatMap { numberTagBits =>
val numberTag = numberTagBits.toInt(false)
if (numberTag >= 31) Left("Tag number can only be 0 - 30, the extended identifier octets are not supported")
else Right(DecodeResult(Identifier(classTag, constructed, numberTag), remaining.drop(5)))
Expand Down
6 changes: 3 additions & 3 deletions asn1/src/test/scala/spinoco/protocol/asn/ber/BerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ object BerSpec extends Properties("BER"){
}

property("length.less.127") = protect {
verify(Option(120l), BitVector.fromInt(0x78, 8))(length)
verify(Option(120L), BitVector.fromInt(0x78, 8))(length)
}

property("length.128") = protect {
verify(Option(128l), BitVector.fromInt(0x8180, 16))(length)
verify(Option(128L), BitVector.fromInt(0x8180, 16))(length)
}

property("length.3383") = protect {
// Tests proper encoding of "D37" <- partial octet
verify(Option(3383l), BitVector.fromInt(0x820D37 , 24))(length)
verify(Option(3383L), BitVector.fromInt(0x820D37 , 24))(length)
}

property("length.long-max") = protect {
Expand Down
53 changes: 33 additions & 20 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ lazy val contributors = Seq(
, "d6y" -> "Richard Dallaway"
)

val Scala211 = "2.11.12"
val Scala212 = "2.12.10"
val Scala213 = "2.13.1"

lazy val commonSettings = Seq(
organization := "com.spinoco",
scalaVersion := "2.12.1",
crossScalaVersions := Seq("2.11.8", "2.12.1"),
scalaVersion := Scala212,
crossScalaVersions := Seq(Scala211, Scala212, Scala213),
scalacOptions ++= Seq(
"-feature",
"-deprecation",
Expand All @@ -22,17 +25,18 @@ lazy val commonSettings = Seq(
"-language:existentials",
"-language:postfixOps",
"-Xfatal-warnings",
"-Yno-adapted-args",
"-Ywarn-value-discard",
"-Ywarn-unused-import"
),
) ++ (CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 11 | 12)) => Seq("-Yno-adapted-args", "-Ywarn-value-discard", "-Ywarn-unused-import")
case Some((2, 13)) => Seq("-Wvalue-discard", "-Wunused:imports")
case _ => Seq.empty
}),
scalacOptions in (Compile, console) ~= {_.filterNot("-Ywarn-unused-import" == _)},
scalacOptions in (Test, console) <<= (scalacOptions in (Compile, console)),
scalacOptions in (Test, console) := (scalacOptions in (Compile, console)).value,
libraryDependencies ++= Seq(
"org.scodec" %% "scodec-bits" % "1.1.5"
, "org.scodec" %% "scodec-core" % "1.10.3"
, "org.scalatest" %% "scalatest" % "3.0.0" % "test"
, "org.scalacheck" %% "scalacheck" % "1.13.4" % "test"
"org.scodec" %% "scodec-bits" % "1.1.12"
, "org.scodec" %% "scodec-core" % "1.11.4"
, "org.scalatest" %% "scalatest" % "3.0.8" % Test
, "org.scalacheck" %% "scalacheck" % "1.14.0" % Test
),
scmInfo := Some(ScmInfo(url("https://github.com/Spinoco/protocol"), "git@github.com:Spinoco/protocol.git")),
homepage := None,
Expand Down Expand Up @@ -102,9 +106,9 @@ lazy val releaseSettings = Seq(
)

lazy val noPublish = Seq(
publish := (),
publishLocal := (),
publishSigned := (),
publish := {},
publishLocal := {},
publishSigned := {},
publishArtifact := false
)

Expand All @@ -115,6 +119,15 @@ lazy val common =
.settings(
name := "protocol-common"
)
.settings(
unmanagedSourceDirectories in Compile += {
val sourceDir = (sourceDirectory in Compile).value
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, n)) if n <= 12 => sourceDir / "scala-2.13-"
case _ => sourceDir / "scala-2.13+"
}
}
)

lazy val mime =
project.in(file("mime"))
Expand Down Expand Up @@ -148,7 +161,6 @@ lazy val stun =
)
.dependsOn(common)


lazy val webSocket =
project.in(file("websocket"))
.settings(commonSettings)
Expand All @@ -165,9 +177,6 @@ lazy val http =
)
.dependsOn(common, mime)




lazy val sdp =
project.in(file("sdp"))
.settings(commonSettings)
Expand All @@ -186,10 +195,11 @@ lazy val kafka =
project.in(file("kafka"))
.settings(commonSettings)
.settings(
crossScalaVersions := Seq(Scala211, Scala212),
name := "protocol-kafka"
, libraryDependencies ++= Seq(
"org.xerial.snappy" % "snappy-java" % "1.1.2.1" // for supporting a Snappy compression of message sets
, "org.apache.kafka" %% "kafka" % "0.10.2.0" % "test"
"org.xerial.snappy" % "snappy-java" % "1.1.7.3" // for supporting a Snappy compression of message sets
, "org.apache.kafka" %% "kafka" % "0.10.2.2" % Test
)
).dependsOn(
common
Expand All @@ -216,6 +226,9 @@ lazy val allProtocols =
project.in(file("."))
.settings(commonSettings)
.settings(noPublish)
.settings(
crossScalaVersions := Seq.empty
)
.aggregate(
common
, mime
Expand Down
13 changes: 13 additions & 0 deletions common/src/main/scala-2.11/spinoco/protocol/package.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package spinoco

package object protocol {

implicit class RightBiasedEither[A, B](val either: Either[A, B]) extends AnyVal {
def map[B1](f: B => B1): Either[A, B1] = either.right.map(f)
def flatMap[A1 >: A, B1](f: B => Either[A1, B1]): Either[A1, B1] = either.right.flatMap(f)
def toOption: Option[B] = either match {
case Right(b) => Some(b)
case _ => None
}
}
}
3 changes: 3 additions & 0 deletions common/src/main/scala-2.12/spinoco/protocol/package.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package spinoco

package object protocol {}
3 changes: 3 additions & 0 deletions common/src/main/scala-2.13+/spinoco/protocol/package.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package spinoco

package object protocol {}
6 changes: 2 additions & 4 deletions common/src/main/scala/spinoco/protocol/common/codec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import scala.concurrent.duration.{FiniteDuration, TimeUnit}
import util.attemptFromEither
import util.attempt

import scala.collection.GenTraversable

object codec {


Expand Down Expand Up @@ -653,15 +651,15 @@ object codec {


/** will encode a collection of `A` with min size of at least `sz` **/
def minItems[A, F[_] <: GenTraversable[_]](sz:Int)(codec: Codec[F[A]]): Codec[F[A]] = {
def minItems[A, F[_] <: Iterable[_]](sz:Int)(codec: Codec[F[A]]): Codec[F[A]] = {
guard(codec){ fa =>
if (fa.size >= sz) None
else Some(Err(s"Expected at least $sz items, got ${fa.size}"))
}
}

/** will encode a collection of `A` with at max size of `sz` **/
def maxItems[A, F[_] <: GenTraversable[_]](sz:Int)(codec: Codec[F[A]]): Codec[F[A]] = {
def maxItems[A, F[_] <: Iterable[_]](sz:Int)(codec: Codec[F[A]]): Codec[F[A]] = {
guard(codec){ fa =>
if (fa.size <= sz) None
else Some(Err(s"Expected at max $sz items, got ${fa.size}"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package spinoco.protocol.common

import org.scalatest.{FreeSpec, Matchers}
import org.scalatest.concurrent.{Eventually, TimeLimitedTests}
import org.scalatest.prop.GeneratorDrivenPropertyChecks
import org.scalatest.time.SpanSugar._
import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks

/**
* Created by pach on 23/07/16.
*/
class ProtocolSpec extends FreeSpec
with GeneratorDrivenPropertyChecks
with ScalaCheckDrivenPropertyChecks
with Matchers
with TimeLimitedTests
with Eventually {
Expand Down
2 changes: 1 addition & 1 deletion http/src/main/scala/spinoco/protocol/http/Uri.scala
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ object Uri {
}
Path(
initialSlash = trimmed.startsWith("/")
, segments = segments
, segments = segments.toIndexedSeq
, trailingSlash = trimmed.endsWith("/") && segments.nonEmpty
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import spinoco.protocol.mime.ContentType._
import spinoco.protocol.mime.MediaType.CustomMediaType
import spinoco.protocol.mime._

import scala.collection.immutable.ListMap
import scala.concurrent.duration._


Expand Down Expand Up @@ -195,7 +196,7 @@ property("Accept-Ranges Header") = secure {
, Authorization(HttpCredentials.OAuthToken("Bearer", "mF_9.B5f-4.1JqM"))
, "Authorization: Bearer mF_9.B5f-4.1JqM")
, ("Authorization: Digest username=\"Mufasa\",\n realm=\"testrealm@host.com\",\n nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\",\n uri=\"/dir/index.html\",\n qop=auth,\n nc=00000001,\n cnonce=\"0a4f113b\",\n response=\"6629fae49393a05397450978507c4ef1\",\n opaque=\"5ccc069c403ebaf9f0171e9517f40e41\""
, Authorization(HttpCredentials.DigestHttpCredentials("Digest", Map(
, Authorization(HttpCredentials.DigestHttpCredentials("Digest", ListMap(
"username" -> "Mufasa"
, "realm" -> "testrealm@host.com"
, "nonce" -> "dcd98b7102dd2f0e8b11d0f600bfb0c093"
Expand All @@ -206,7 +207,7 @@ property("Accept-Ranges Header") = secure {
, "response" -> "6629fae49393a05397450978507c4ef1"
, "opaque" -> "5ccc069c403ebaf9f0171e9517f40e41"
)))
, "Authorization: Digest nc=00000001, nonce=dcd98b7102dd2f0e8b11d0f600bfb0c093, username=Mufasa, uri=\"/dir/index.html\", cnonce=0a4f113b, qop=auth, response=6629fae49393a05397450978507c4ef1, opaque=5ccc069c403ebaf9f0171e9517f40e41, realm=\"testrealm@host.com\"")
, "Authorization: Digest username=Mufasa, realm=\"testrealm@host.com\", nonce=dcd98b7102dd2f0e8b11d0f600bfb0c093, uri=\"/dir/index.html\", qop=auth, nc=00000001, cnonce=0a4f113b, response=6629fae49393a05397450978507c4ef1, opaque=5ccc069c403ebaf9f0171e9517f40e41")
))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import scodec.bits.BitVector
import scodec.{Attempt, Codec}
import scodec.codecs._
import shapeless.{::, HNil}
import shapeless.Typeable.simpleTypeable
import spinoco.protocol.kafka._
import spinoco.protocol.common.util._
import spinoco.protocol.kafka.Request.{FetchRequest, MetadataRequest, OffsetsRequest, ProduceRequest}
import spinoco.protocol.kafka.Response.{FetchResponse, MetadataResponse, OffsetResponse, ProduceResponse}


object MessageCodec {
Expand All @@ -26,14 +28,13 @@ object MessageCodec {
/** decodes concrete response **/
def responseCodecFor(version: ProtocolVersion.Value, apiKey:ApiKey.Value):Codec[Response] = {
apiKey match {
case ApiKey.FetchRequest => FetchCodec.responseCodec(version).upcast
case ApiKey.MetadataRequest => MetadataCodec.metadataResponseCodec.upcast
case ApiKey.ProduceRequest => ProduceCodec.produceResponseCodec(version).upcast
case ApiKey.OffsetRequest => OffsetCodec.responseCodec(version).upcast
case ApiKey.FetchRequest => FetchCodec.responseCodec(version).upcast(simpleTypeable(classOf[FetchResponse]))
case ApiKey.MetadataRequest => MetadataCodec.metadataResponseCodec.upcast(simpleTypeable(classOf[MetadataResponse]))
case ApiKey.ProduceRequest => ProduceCodec.produceResponseCodec(version).upcast(simpleTypeable(classOf[ProduceResponse]))
case ApiKey.OffsetRequest => OffsetCodec.responseCodec(version).upcast(simpleTypeable(classOf[OffsetResponse]))
}
}


object impl {

val apiKeyCodec:Codec[ApiKey.Value] =
Expand Down Expand Up @@ -103,12 +104,12 @@ object MessageCodec {
requestHeaderCodec.flatZip[Request] {
case api :: version :: _ =>
api match {
case ApiKey.ProduceRequest => ProduceCodec.requestCodec.upcast
case ApiKey.FetchRequest => FetchCodec.requestCodec(version).upcast
case ApiKey.MetadataRequest => MetadataCodec.requestCodec.upcast
case ApiKey.OffsetRequest => OffsetCodec.requestCodec(version).upcast
case ApiKey.ProduceRequest => ProduceCodec.requestCodec.upcast(simpleTypeable(classOf[ProduceRequest]))
case ApiKey.FetchRequest => FetchCodec.requestCodec(version).upcast(simpleTypeable(classOf[FetchRequest]))
case ApiKey.MetadataRequest => MetadataCodec.requestCodec.upcast(simpleTypeable(classOf[MetadataRequest]))
case ApiKey.OffsetRequest => OffsetCodec.requestCodec(version).upcast(simpleTypeable(classOf[OffsetsRequest]))
}
}.xmap(decode _ tupled,encode)
}.xmap(decode _ tupled, encode)
}

}
Expand Down
2 changes: 1 addition & 1 deletion ldap/src/main/scala/spinoco/protocol/ldap/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ package object ldap {
if (bits == trueVector) Right(true)
else Right(false)
}
.right.map{ case (remaining, value) => DecodeResult(value, remaining)}
.map{ case (remaining, value) => DecodeResult(value, remaining)}
.left.map(err => Err("Could not decode LDAP boolean due to: " + err))
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package spinoco.protocol.ldap
package spinoco.protocol
package ldap

import org.scalacheck.Prop._
import org.scalacheck.{Prop, Properties}
Expand Down Expand Up @@ -29,7 +30,7 @@ object LDAPMessageSpec extends Properties("LDAPMessage"){
, BindRequest(
3
, LdapDN.decode("dc=admin").require
, BindRequest.Simple(ByteVector.encodeUtf8("admin").right.get)
, BindRequest.Simple(ByteVector.encodeUtf8("admin").toOption.get)
)
, None
), BitVector.fromValidHex("30190201016014020103040864633d61646d696e800561646d696e"))(LdapMessage.codec)
Expand Down Expand Up @@ -65,7 +66,7 @@ object LDAPMessageSpec extends Properties("LDAPMessage"){
, sizeLimit = 50
, timeLimit = 0
, typesOnly = false
, filter = Filter.And(Set(Filter.Present(AttributeDescription.Recognised(AttributeDescription.AttributeType.commonName)), Filter.SubstringFilter(AttributeDescription.TextDescriptor("sn"), SubStrings(Some(SubStrings.Initial(ByteVector.encodeUtf8("J").right.get)), Vector.empty, None))))
, filter = Filter.And(Set(Filter.Present(AttributeDescription.Recognised(AttributeDescription.AttributeType.commonName)), Filter.SubstringFilter(AttributeDescription.TextDescriptor("sn"), SubStrings(Some(SubStrings.Initial(ByteVector.encodeUtf8("J").toOption.get)), Vector.empty, None))))
, attributes = Vector(
AttributeSelector.Description(AttributeDescription.Recognised(AttributeDescription.AttributeType.commonName))
, AttributeSelector.Description(AttributeDescription.TextDescriptor("sn"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ object `Auto-Submitted` extends DefaultHeaderDescription[`Auto-Submitted`] {
Attempt.fromEither(
Try(AutoType.withName(a)).toOption
.toRight(Err("Could not parse Auto-Submitted header due to invalid tpe: " + a))
.right.map(`Auto-Submitted`(_))
.map(`Auto-Submitted`(_))
)
}
, b => {
Expand All @@ -34,4 +34,4 @@ object `Auto-Submitted` extends DefaultHeaderDescription[`Auto-Submitted`] {



}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ object `Return-Path` extends DefaultHeaderDescription[`Return-Path`] {
`Return-Path`(s0.trim)
}
}
, rp => '<' + rp.path + '>'
, rp => s"<${rp.path}>"
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package spinoco.protocol.mail.header.codec
import scodec.bits.BitVector
import scodec.codecs._
import scodec.{Attempt, Codec, Err}
import spinoco.protocol.common.codec._
import spinoco.protocol.common.codec.{quotedString => _, _}
import spinoco.protocol.mail.EmailAddress

/**
Expand Down
Loading