Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Rapid prototyping HTTP toolkit based on Netty. Supports container-style jars, multi-hosting, REST primitives.
Java JavaScript Scala
branch: master

update

latest commit bea1168c7a
@briangu authored
Failed to load latest commit information.
core update
examples add js for signin
.gitignore update ignore
LICENSE update
README.md Update README.md
TODO.txt update poms
pom.xml

README.md

viper.io

Viper.io is a rapid prototyping toolkit on top of Netty. It's grown from many hackweeks/days and is remarkably easy to use to quickly build HTTP servers:

  • Virtual hosting (host multiple domains from the same process)
  • container-like jar loading for virtual servers
  • serve websites from jar resources (read-only websites, such as splash or product pages)
  • easy REST application development (biased towards data-driven clients via JSON)
  • SSL server support
  • Uploading and downloading of files directly to/from S3 using Netty
  • thin layer over Netty making it easy to extend

Maven

<dependency>
  <groupId>io.viper</groupId>
  <artifactId>io.viper.core</artifactId>
  <version>0.1.4</version>
</dependency>

Example

Check the examples src for more.

Hello World:

import io.viper.common.{Response, NestServer}

object HelloWorld extends NestServer(9080) {
  get("/hello") { args => Response("world") }
}

Static content served from embedded resources:

package io.viper.examples

import io.viper.common.{NestServer, ViperServer}

object StaticHost {
  def main(args: Array[String]) {
    NestServer.run(8080, new ViperServer("res:///static.com/"))
  }
}

Serve files directly to/from S3:

package io.viper.examples.files

import io.viper.common.{ViperServer, NestServer}
import io.viper.core.server.file.HttpChunkProxyHandler
import io.viper.core.server.file.s3.{S3StaticFileServerHandler, S3StandardChunkProxy}


object S3FileServer {
  def main(args: Array[String]) {
    var awsId = if (args.length > 2) args(0) else "awsId"
    var awsKey = if (args.length > 2) args(1) else "awsKey"
    var awsBucket = if (args.length > 2) args(2) else "awsBucket"

    NestServer.run(8080, new S3FileServer(awsId, awsKey, awsBucket, "localhost"))
  }
}

class S3FileServer(awsId: String, awsKey: String, awsBucket: String, downloadHostname: String) extends ViperServer("res:///s3server") {
  override def addRoutes {
    val proxy = new S3StandardChunkProxy(awsId, awsKey, awsBucket);
    val relayListener = new FileUploadChunkRelayEventListener(downloadHostname);
    addRoute(new HttpChunkProxyHandler("/u/", proxy, relayListener));

    addRoute(new S3StaticFileServerHandler("/d/$path", awsId, awsKey, awsBucket))
  }
}

File Server:

package io.viper.examples.files

import io.viper.core.server.file.{StaticFileServerHandler, HttpChunkProxyHandler, FileChunkProxy}
import io.viper.common.{StaticFileContentInfoProviderFactory, ViperServer, NestServer}


object FileServer {
  def main(args: Array[String]) {
    NestServer.run(9080, new FileServer("/tmp/uploads", "localhost"))
  }
}

class FileServer(uploadFileRoot: String, downloadHostname: String) extends ViperServer("res:///fileserver") {
  override def addRoutes {
    val proxy = new FileChunkProxy(uploadFileRoot)
    val relayListener = new FileUploadChunkRelayEventListener(downloadHostname)
    addRoute(new HttpChunkProxyHandler("/u/", proxy, relayListener))
    val provider = StaticFileContentInfoProviderFactory.create(this.getClass, uploadFileRoot)
    get("/d/$path", new StaticFileServerHandler(provider))
  }
}

The following shows how two domains can be hosted on port 80. The first, static.com, is a static content site that is hosted from embedded jar resources. The second, rest.com, is a service with REST handlers. This service can easily be expanded to support both static and REST by extending StaticFileServer and adding the REST resources.

package nest.router

import _root_.io.viper.core.server.router._
import io.viper.common.{NestServer, RestServer, StaticFileServer}
import java.util.Map
import org.json.JSONObject


object Main {
  def main(args: Array[String]) {
    val handler = new HostRouterHandler

    // Serve static.com from cached jar resources in the static.com directory
    handler.putRoute("static.com", new StaticFileServer("res:///static.com/"))

    // Serve REST handlers
    handler.putRoute("rest.com", new RestServer {
      def addRoutes {

        get("/hello", new RouteHandler {
          def exec(args: Map[String, String]): RouteResponse = new Utf8Response("world")
        })

        get("/echo/$something", new RouteHandler {
          def exec(args: Map[String, String]): RouteResponse = {
            val json = new JSONObject()
            json.put("hello", args.get("something"))
            new JsonResponse(json)
          }
        })
      }
    })

    NestServer.run(handler)
  }
}

Maven

<dependency>
    <groupId>io.viper</groupId>
    <artifactId>io.viper.core</artifactId>
    <version>0.1.4</version>
</dependency>
Something went wrong with that request. Please try again.