Skip to content

Commit

Permalink
RDF MimeTypes, HttpSig, jsld examples
Browse files Browse the repository at this point in the history
  • Loading branch information
bblfish committed Mar 26, 2021
1 parent ae77221 commit f3ed53e
Show file tree
Hide file tree
Showing 12 changed files with 1,155 additions and 39 deletions.
30 changes: 24 additions & 6 deletions src/main/scala/run/cosy/Solid.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,23 @@ import akka.Done
import akka.actor.CoordinatedShutdown
import akka.actor.typed.scaladsl.{ActorContext, Behaviors, LoggerOps}
import akka.actor.typed.{ActorRef, ActorSystem, Behavior, PostStop, Scheduler}
import akka.http.scaladsl.settings.ParserSettings
import akka.http.scaladsl.Http
import akka.http.scaladsl.Http.ServerBinding
import akka.http.scaladsl.model.Uri.Path.{Empty, Segment, Slash}
import akka.http.scaladsl.model
import akka.http.scaladsl.model.{HttpResponse, Uri}
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.server.Directives.{complete, extract, extractRequestContext}
import akka.http.scaladsl.server.{RequestContext, Route, RouteResult}
import akka.http.scaladsl.settings.ServerSettings
import akka.http.scaladsl.util.FastFuture
import akka.util.Timeout
import cats.data.NonEmptyList
import com.typesafe.config.{Config, ConfigFactory}
import run.cosy.http.RDFMediaTypes
import run.cosy.http.auth.HttpSig
import run.cosy.http.auth.HttpSig.{Agent, PublicKeyAlgo}
import run.cosy.ldp.ResourceRegistry
import run.cosy.ldp.fs.BasicContainer

Expand Down Expand Up @@ -46,10 +52,13 @@ object Solid {
given timeout: Scheduler = system.scheduler
given ec: ExecutionContext = ctx.executionContext

val ps = ParserSettings.forServer(system).withCustomMediaTypes(RDFMediaTypes.all :_*)
val serverSettings = ServerSettings(system).withParserSettings(ps)

val serverBinding = Http()
.newServerAt(uri.authority.host.address(), uri.authority.port)
.bind(solid.route)
.withSettings(serverSettings)
.bind(solid.routeLdp())

ctx.pipeToSelf(serverBinding) {
case Success(binding) =>
Expand All @@ -68,8 +77,6 @@ object Solid {
Started(binding)
case Failure(ex) => StartFailed(ex)
}



def running(binding: ServerBinding): Behavior[Run] =
Behaviors.receiveMessagePartial[Run] {
Expand Down Expand Up @@ -144,17 +151,28 @@ class Solid(
given timeout: Scheduler = sys.scheduler
given scheduler: Timeout = Timeout(5.second)

def fetch(uri: Uri): Future[PublicKeyAlgo] = ???

lazy val securedRoute: Route = extractRequestContext { (reqc: RequestContext) =>
HttpSig.httpSignature(reqc)(fetch).optional.tapply {
case Tuple1(Some(agent)) => routeLdp(agent)
case Tuple1(None) => routeLdp()
}
}

lazy val route: Route = (reqc: RequestContext) => {

def routeLdp(agent: Agent = new Agent{}): Route = (reqc: RequestContext) => {
val path = reqc.request.uri.path
import reqc.{given}
reqc.log.info("routing req " + reqc.request.uri)
val (remaining, actor): (List[String], ActorRef[BasicContainer.Cmd]) = registry.getActorRef(path)
.getOrElse((List[String](), rootRef))

def cmdFn(ref: ActorRef[HttpResponse]): BasicContainer.Cmd = remaining match {
case Nil => BasicContainer.Do(reqc.request,ref)
case head::tail => BasicContainer.Route(NonEmptyList(head,tail), reqc.request, ref)
case Nil => BasicContainer.Do(reqc.request, ref)
case head :: tail => BasicContainer.Route(NonEmptyList(head, tail), reqc.request, ref)
}

actor.ask[HttpResponse](cmdFn).map(RouteResult.Complete(_))
}

Expand Down
212 changes: 212 additions & 0 deletions src/main/scala/run/cosy/http/FileExtensions.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
package run.cosy.http

import akka.http.scaladsl.model.MediaTypes._
import akka.http.scaladsl.model.{HttpCharsets, MediaType, MediaTypes}

/**
* Sadly Akka's MediaType registry is not extensible, and the file extension names are often oddly chosen
* Todo: extend this so that servers can configure the extensions
**/
object FileExtensions {
val akkaMimeTypes = Seq(`application/atom+xml`,
`application/base64`,
`application/cbor`,
`application/gnutar`,
`application/java-archive`,
`application/javascript`,
`application/json`,
`application/json-patch+json`,
`application/merge-patch+json`,
`application/problem+json`,
`application/grpc+proto`,
`application/lha`,
`application/lzx`,
`application/msword`,
`application/octet-stream`,
`application/pdf`,
`application/postscript`,
`application/rss+xml`,
`application/soap+xml`,
`application/vnd.api+json`,
`application/vnd.google-earth.kml+xml`,
`application/vnd.google-earth.kmz`,
`application/vnd.ms-excel`,
`application/vnd.ms-excel.addin.macroEnabled.12`,
`application/vnd.ms-excel.sheet.binary.macroEnabled.12`,
`application/vnd.ms-excel.sheet.macroEnabled.12`,
`application/vnd.ms-excel.template.macroEnabled.12`,
`application/vnd.ms-fontobject`,
`application/vnd.ms-powerpoint`,
`application/vnd.ms-powerpoint.addin.macroEnabled.12`,
`application/vnd.ms-powerpoint.presentation.macroEnabled.12`,
`application/vnd.ms-powerpoint.slideshow.macroEnabled.12`,
`application/vnd.ms-word.document.macroEnabled.12`,
`application/vnd.ms-word.template.macroEnabled.12`,
`application/vnd.oasis.opendocument.chart`,
`application/vnd.oasis.opendocument.database`,
`application/vnd.oasis.opendocument.formula`,
`application/vnd.oasis.opendocument.graphics`,
`application/vnd.oasis.opendocument.image`,
`application/vnd.oasis.opendocument.presentation`,
`application/vnd.oasis.opendocument.spreadsheet`,
`application/vnd.oasis.opendocument.text`,
`application/vnd.oasis.opendocument.text-master`,
`application/vnd.oasis.opendocument.text-web`,
`application/vnd.openxmlformats-officedocument.presentationml.presentation`,
`application/vnd.openxmlformats-officedocument.presentationml.slide`,
`application/vnd.openxmlformats-officedocument.presentationml.slideshow`,
`application/vnd.openxmlformats-officedocument.presentationml.template`,
`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`,
`application/vnd.openxmlformats-officedocument.spreadsheetml.template`,
`application/vnd.openxmlformats-officedocument.wordprocessingml.document`,
`application/vnd.openxmlformats-officedocument.wordprocessingml.template`,
`application/x-7z-compressed`,
`application/x-ace-compressed`,
`application/x-apple-diskimage`,
`application/x-arc-compressed`,
`application/x-bzip`,
`application/x-bzip2`,
`application/x-chrome-extension`,
`application/x-compress`,
`application/x-compressed`,
`application/x-debian-package`,
`application/x-dvi`,
`application/x-font-truetype`,
`application/x-font-opentype`,
`application/x-gtar`,
`application/x-gzip`,
`application/x-latex`,
`application/x-rar-compressed`,
`application/x-redhat-package-manager`,
`application/x-shockwave-flash`,
`application/x-tar`,
`application/x-tex`,
`application/x-texinfo`,
`application/x-vrml`,
`application/x-www-form-urlencoded`,
`application/x-x509-ca-cert`,
`application/x-xpinstall`,
`application/xhtml+xml`,
`application/xml-dtd`,
`application/xml`,
`application/problem+xml`,
`application/zip`,
`audio/aiff`,
`audio/basic`,
`audio/midi`,
`audio/mod`,
`audio/mpeg`,
`audio/ogg`,
`audio/voc`,
`audio/vorbis`,
`audio/voxware`,
`audio/wav`,
`audio/x-realaudio`,
`audio/x-psid`,
`audio/xm`,
`audio/webm`,
`font/woff`,
`font/woff2`,
`image/gif`,
`image/jpeg`,
`image/pict`,
`image/png`,
`image/svg+xml`,
`image/svgz`,
`image/tiff`,
`image/x-icon`,
`image/x-ms-bmp`,
`image/x-pcx`,
`image/x-pict`,
`image/x-quicktime`,
`image/x-rgb`,
`image/x-xbitmap`,
`image/x-xpixmap`,
`image/webp`,
`message/http`,
`message/delivery-status`,
`message/rfc822`,
`multipart/mixed`,
`multipart/alternative`,
`multipart/related`,
`multipart/form-data`,
`multipart/signed`,
`multipart/encrypted`,
`multipart/byteranges`,
`text/asp`,
`text/cache-manifest`,
`text/calendar`,
`text/css`,
`text/csv`,
`text/event-stream`,
`text/html`,
`text/markdown`,
`text/mcf`,
`text/plain`,
`text/richtext`,
`text/tab-separated-values`,
`text/uri-list`,
`text/vnd.wap.wml`,
`text/vnd.wap.wmlscript`,
`text/x-asm`,
`text/x-c`,
`text/x-component`,
`text/x-h`,
`text/x-java-source`,
`text/x-pascal`,
`text/x-script`,
`text/x-scriptcsh`,
`text/x-scriptelisp`,
`text/x-scriptksh`,
`text/x-scriptlisp`,
`text/x-scriptperl`,
`text/x-scriptperl-module`,
`text/x-scriptphyton`,
`text/x-scriptrexx`,
`text/x-scriptscheme`,
`text/x-scriptsh`,
`text/x-scripttcl`,
`text/x-scripttcsh`,
`text/x-scriptzsh`,
`text/x-server-parsed-html`,
`text/x-setext`,
`text/x-sgml`,
`text/x-speech`,
`text/x-uuencode`,
`text/x-vcalendar`,
`text/x-vcard`,
`text/xml`,
`video/avs-video`,
`video/divx`,
`video/gl`,
`video/mp4`,
`video/mpeg`,
`video/ogg`,
`video/quicktime`,
`video/x-dv`,
`video/x-flv`,
`video/x-motion-jpeg`,
`video/x-ms-asf`,
`video/x-msvideo`,
`video/x-sgi-movie`,
`video/webm`
)


private[this] var extensionMap = Map.empty[String, MediaType]

for {m <- akkaMimeTypes ++ RDFMediaTypes.all} registerFileExtensions(m)

private def registerFileExtensions[T <: MediaType](mediaType: T): T =
mediaType.fileExtensions.foreach { ext =>
val lcExt = ext.toLowerCase
require(!extensionMap.contains(lcExt),
s"Extension '$ext' clash: media-types '${extensionMap(lcExt)}' and '$mediaType'")
extensionMap = extensionMap.updated(lcExt, mediaType)
}
mediaType

def forExtensionOption(ext: String): Option[MediaType] = extensionMap.get(ext.toLowerCase)
def forExtension(ext: String): MediaType = extensionMap.getOrElse(ext.toLowerCase, `application/octet-stream`)

}
15 changes: 13 additions & 2 deletions src/main/scala/run/cosy/http/RDFMediaTypes.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package run.cosy.http

import akka.actor.typed.ActorSystem
import akka.http.scaladsl.model.MediaTypes
import akka.http.scaladsl.model.MediaTypes.extensionMap
import akka.http.scaladsl.settings.ParserSettings

/**
* Media Types for RDF.
* Collected from the [[https://docs.aws.amazon.com/neptune/latest/userguide/sparql-media-type-support.html RDF media types used by SPARQL in Neptune]] document by Amazon.
Expand Down Expand Up @@ -39,7 +44,7 @@ object RDFMediaTypes {
/** The older version of n-quads was limited to US-ASCII and had a different mime type */
val `text/n-quads` = MediaType.customWithFixedCharset(
"text","n-quads",`US-ASCII`,
fileExtensions = List("nq")
fileExtensions = List("nqAscii")
)

/**
Expand Down Expand Up @@ -106,5 +111,11 @@ object RDFMediaTypes {
"application","sparql-results+xml",
fileExtensions = List("srx")
)


def all: Seq[MediaType] = Seq(`application/rdf+xml`, `application/n-triples`, `application/n-quads`,
`text/n-quads`,`text/turtle`,`application/trig`, `text/n3`,`application/ld+json`,
`application/sparql-results+json`, `application/sparql-results+xml`, `application/trix`
)


}
Loading

0 comments on commit f3ed53e

Please sign in to comment.