Initial go version commit
This commit is contained in:
commit
7a00c288b0
83
api.go
Normal file
83
api.go
Normal file
@ -0,0 +1,83 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type DispatchFunction func([]string, []byte) (interface{}, error)
|
||||
|
||||
var apiRouting = map[string]*(map[string]DispatchFunction){
|
||||
"version": &ApiVersionRouting,
|
||||
}
|
||||
|
||||
func ApiRouting(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("Handling %s request from %s: %s [%s]\n", r.Method, r.RemoteAddr, r.URL.Path, r.UserAgent())
|
||||
|
||||
// Extract URL arguments
|
||||
var sURL = strings.Split(r.URL.Path, "/")
|
||||
if sURL[len(sURL)-1] == "" && len(sURL) > 2 {
|
||||
// Remove trailing /
|
||||
sURL = sURL[:len(sURL)-1]
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
var ret interface{}
|
||||
var err error = nil
|
||||
|
||||
// Read the body
|
||||
if r.ContentLength < 0 || r.ContentLength > 10485760 {
|
||||
http.Error(w, "{errmsg:\"Request too large or request size unknown\"}", http.StatusRequestEntityTooLarge)
|
||||
return
|
||||
}
|
||||
var body []byte
|
||||
if r.ContentLength > 0 {
|
||||
tmp := make([]byte, 1024)
|
||||
for {
|
||||
n, err := r.Body.Read(tmp)
|
||||
for j := 0; j < n; j++ {
|
||||
body = append(body, tmp[j])
|
||||
}
|
||||
if err != nil || n <= 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Route request
|
||||
if len(sURL) > 2 {
|
||||
if h, ok := apiRouting[sURL[2]]; ok {
|
||||
if f, ok := (*h)[r.Method]; ok {
|
||||
ret, err = f(sURL[3:], body)
|
||||
} else {
|
||||
err = errors.New(fmt.Sprintf("Invalid action (%s) provided for %s.", r.Method, sURL[2]))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err = errors.New(fmt.Sprintf("No action provided for %s", sURL[1]))
|
||||
}
|
||||
|
||||
// Format response
|
||||
resStatus := http.StatusOK
|
||||
if err != nil {
|
||||
ret = map[string]string{"errmsg": err.Error()}
|
||||
resStatus = http.StatusBadRequest
|
||||
}
|
||||
|
||||
if ret == nil {
|
||||
ret = map[string]string{"errmsg": "Page not found"}
|
||||
resStatus = http.StatusNotFound
|
||||
}
|
||||
|
||||
if j, err := json.Marshal(ret); err != nil {
|
||||
http.Error(w, fmt.Sprintf("{errmsg:\"%q\"}", err), http.StatusInternalServerError)
|
||||
} else {
|
||||
w.WriteHeader(resStatus)
|
||||
w.Write(j)
|
||||
}
|
||||
}
|
9
api_version.go
Normal file
9
api_version.go
Normal file
@ -0,0 +1,9 @@
|
||||
package main
|
||||
|
||||
var ApiVersionRouting = map[string]DispatchFunction{
|
||||
"GET": showVersion,
|
||||
}
|
||||
|
||||
func showVersion(args []string, body []byte) (interface{}, error) {
|
||||
return map[string]interface{}{"version": 0.1}, nil
|
||||
}
|
1
contents/config.json
Normal file
1
contents/config.json
Normal file
@ -0,0 +1 @@
|
||||
{"name":"YouP0m"}
|
49
main.go
Normal file
49
main.go
Normal file
@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func readConfig(path string) (map[string]string, error) {
|
||||
var config map[string]string
|
||||
|
||||
if cnt_raw, err := ioutil.ReadFile(path); err != nil {
|
||||
return nil, err
|
||||
} else if err := json.Unmarshal(cnt_raw, &config); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return config, nil
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var port = flag.Int("port", 8080, "Listening port")
|
||||
var sitedir = flag.String("sitedir", "./contents/", "Directory containing site content and pictures")
|
||||
flag.Parse()
|
||||
|
||||
log.Println("Reading site configuration...")
|
||||
if config, err := readConfig(filepath.Join(*sitedir, "config.json")); err != nil {
|
||||
log.Fatal(err)
|
||||
os.Exit(1)
|
||||
} else {
|
||||
log.Println("Registering handlers...")
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("/favicon.ico", http.FileServer(http.Dir("./static/")))
|
||||
mux.Handle("/static/", http.FileServer(http.Dir("./")))
|
||||
mux.Handle("/doc/", http.FileServer(http.Dir("./")))
|
||||
mux.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(filepath.Join(*sitedir, "current")))))
|
||||
mux.HandleFunc("/api/", ApiRouting)
|
||||
mux.HandleFunc("/", SeeRouting)
|
||||
http.HandleFunc("/", mux.ServeHTTP)
|
||||
|
||||
log.Println(fmt.Sprintf("Site ready (n=%s), listening on port %d", config["name"], *port))
|
||||
http.ListenAndServe(fmt.Sprintf(":%d", *port), nil)
|
||||
}
|
||||
}
|
44
see.go
Normal file
44
see.go
Normal file
@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"html"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func SeeRouting(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("Handling request %s: %s\n", r.Method, r.URL.Path)
|
||||
|
||||
// Extract URL arguments
|
||||
var sURL = strings.Split(r.URL.Path, "/")
|
||||
if sURL[len(sURL)-1] == "" && len(sURL) > 2 {
|
||||
// Remove trailing /
|
||||
sURL = sURL[:len(sURL)-1]
|
||||
}
|
||||
|
||||
if len(sURL) < 3 {
|
||||
http.Error(w, "Please provide a valid hash", http.StatusForbidden)
|
||||
} else {
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
|
||||
w.Write([]byte(`<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OhSnap</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" media="all" href="/static/css/style.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<figure class="big">
|
||||
<img src="/images/` + html.EscapeString("1") + `.jpg" alt="` + html.EscapeString("name") + `">`))
|
||||
if "name" != "" {
|
||||
w.Write([]byte(`<figcaption>` + html.EscapeString("name") + `</figcaption>`))
|
||||
}
|
||||
w.Write([]byte(` </figure>
|
||||
</body>
|
||||
</html>
|
||||
`))
|
||||
}
|
||||
}
|
44
static/css/style.css
Normal file
44
static/css/style.css
Normal file
@ -0,0 +1,44 @@
|
||||
body {
|
||||
background: #222;
|
||||
color: #EEE;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
figure.big {
|
||||
display: table;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.big img {
|
||||
height: calc(100vh - 20px);
|
||||
max-width: 100vw;
|
||||
}
|
||||
|
||||
img
|
||||
{
|
||||
border-radius: 20px 0 20px 0;
|
||||
box-shadow: 0px 0px 10px #9AB;
|
||||
transition: box-shadow 1s ease-out;
|
||||
-moz-transition: box-shadow 1.23s ease-out;
|
||||
}
|
||||
img:hover
|
||||
{
|
||||
display: table-cell;
|
||||
box-shadow: 0px 0px 20px #FED;
|
||||
}
|
||||
|
||||
|
||||
.big figcaption
|
||||
{
|
||||
background: #656565;
|
||||
color: #FFF;
|
||||
font-weight: bold;
|
||||
margin: -100px auto;
|
||||
opacity: 0.65;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user