First commit ;)

diff --git a/LICENSE b/LICENSE
index 37ec93a..11b015b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -176,7 +176,7 @@ recommend that a file or class name and description of purpose be included on
 the same "printed page" as the copyright notice for easier identification within
 third-party archives.

-   Copyright [yyyy] [name of copyright owner]
+   Copyright 2013 Juliano Martinez <juliano@martinez.io>

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..be9e44a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,5 @@
+all: install
+
+install:
+	go get -v github.com/ncode/hot-potato-router/...
+	go build -o bin/hpr hpr.go
diff --git a/config/hpr.yml b/config/hpr.yml
new file mode 100644
index 0000000..dd4695d
--- /dev/null
+++ b/config/hpr.yml
@@ -0,0 +1,11 @@
+hpr:
+    http_addr: :80
+    http_fd:
+    https_addr:
+    https_fd:
+    cert_file:
+    key_file:
+    probe_interval:
+
+redis:
+	server_list: 127.0.0.1:6379
diff --git a/hpr.go b/hpr.go
new file mode 100644
index 0000000..4200ed7
--- /dev/null
+++ b/hpr.go
@@ -0,0 +1,140 @@
+/*
+   Copyright 2013 Juliano Martinez <juliano@martinez.io>
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+      Based on http://github.com/nf/webfront
+
+   @author: Juliano Martinez
+*/
+
+package main
+
+import (
+	"crypto/tls"
+	"github.com/fiorix/go-redis/redis"
+	hpr_utils "github.com/ncode/hot-potato-router/utils"
+	"log"
+	"net"
+	"net/http"
+	"net/http/httputil"
+	"os"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+var (
+	cfg = hpr_utils.NewConfig()
+	rc  = redis.New(cfg.Options["redis"]["server_list"])
+)
+
+func main() {
+	flag.Parse()
+	s, err := NewServer(*ruleFile, *pollInterval)
+	if err != nil {
+		log.Fatal(err)
+	}
+	http_fd, _ := strconv.Atoi(cfg.Options["hpr"]["http_fd"])
+	https_fd, _ := strconv.Atoi(cfg.Options["hpr"]["https_fd"])
+	if https_fd >= 3 || *httpsAddr != "" {
+		cert, err := tls.LoadX509KeyPair(cfg.Options["hpr"]["cert_file"], cfg.Options["hpr"]["key_file"])
+		if err != nil {
+			log.Fatal(err)
+		}
+		c := &tls.Config{Certificates: []tls.Certificate{cert}}
+		l := tls.NewListener(listen(https_fd, cfg.Options["hpr"]["https_addr"]), c)
+		go func() {
+			log.Fatal(http.Serve(l, s))
+		}()
+	}
+	log.Fatal(http.Serve(listen(http_fd, cfg.Options["hpr"]["https_addr"]), s))
+}
+
+func listen(fd int, addr string) net.Listener {
+	var l net.Listener
+	var err error
+	if fd >= 3 {
+		l, err = net.FileListener(os.NewFile(uintptr(fd), "http"))
+	} else {
+		l, err = net.Listen("tcp", addr)
+	}
+	if err != nil {
+		log.Fatal(err)
+	}
+	return l
+}
+
+type Server struct {
+	mu    sync.RWMutex
+	last  time.Time
+	proxy map[string][]Proxy
+}
+
+type Proxy struct {
+	Backend string
+	handler http.Handler
+}
+
+func NewServer(probe time.Duration) (*Server, error) {
+	s := new(Server)
+	s.proxy = make(map[string]http.Handler)
+	go s.probe_backends(probe)
+	return s, nil
+}
+
+func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	if h := s.handler(r); h != nil {
+		h.ServeHTTP(w, r)
+		return
+	}
+	http.Error(w, "Not found.", http.StatusNotFound)
+}
+
+func (s *Server) handler(req *http.Request) http.Handler {
+	s.mu.RLock()
+	defer s.mu.RUnlock()
+	h := req.Host
+	if i := strings.Index(h, ":"); i >= 0 {
+		h = h[:i]
+	}
+
+	_, ok := s.proxy[h]
+	if !ok {
+		v, _ := rc.Get(h)
+		s.proxy[h] = makeHandler(v)
+	}
+	return s.proxy[h]
+}
+
+func (s *Server) probe_backends(probe time.Duration) {
+	for {
+		s.mu.Lock()
+		s.last = mtime
+		s.mu.Unlock()
+		time.Sleep(probe)
+	}
+}
+
+func makeHandler(f string) http.Handler {
+	if f != "" {
+		return &httputil.ReverseProxy{
+			Director: func(req *http.Request) {
+				req.URL.Scheme = "http"
+				req.URL.Host = f
+			},
+		}
+	}
+	return nil
+}
diff --git a/utils/check.go b/utils/check.go
new file mode 100644
index 0000000..1d3e1b8
--- /dev/null
+++ b/utils/check.go
@@ -0,0 +1,40 @@
+package utils
+
+import (
+	"fmt"
+	"log"
+	"log/syslog"
+)
+
+var (
+	_log, s_err = syslog.New(syslog.LOG_ERR, "cloudboss")
+)
+
+func Check(err error, message string) {
+	check(err, message, false)
+}
+
+func CheckPanic(err error, message string) {
+	check(err, message, true)
+}
+
+func Log(message string) {
+	CheckPanic(s_err, "Unable to write syslog message")
+	_log.Info(message)
+	defer _log.Close()
+}
+
+func check(err error, message string, _panic bool) {
+	if err != nil {
+		msg := fmt.Sprintf("%s: %s", message, err)
+		if s_err != nil {
+			log.Fatalln("Unable to write syslog message")
+		}
+		_log.Warning(msg)
+		defer _log.Close()
+		log.Fatalln(msg)
+		if _panic {
+			panic(msg)
+		}
+	}
+}
diff --git a/utils/config.go b/utils/config.go
new file mode 100644
index 0000000..6635cef
--- /dev/null
+++ b/utils/config.go
@@ -0,0 +1,27 @@
+package utils
+
+import (
+	"io/ioutil"
+	"launchpad.net/goyaml"
+	"os"
+	"strings"
+)
+
+type Config struct {
+	Options map[string]map[string]string
+}
+
+func NewConfig() Config {
+	cfg := Config{}
+
+	config_file := os.Getenv("HPR_CONF")
+	if strings.EqualFold(config_file, "") {
+		config_file = "/etc/hpr/hpr.yml"
+	}
+	f, err := ioutil.ReadFile(config_file)
+	CheckPanic(err, "Unable to open YAML file")
+
+	err = goyaml.Unmarshal(f, &cfg.Options)
+	CheckPanic(err, "Unable to parse YAML file")
+	return cfg
+}