Some fixes

master
Андрей Иванов 2024-04-24 08:14:50 +03:00
parent 60bc6071f2
commit db142def3f
3 changed files with 106 additions and 97 deletions

View File

@ -0,0 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="run" type="GoApplicationRunConfiguration" factoryName="Go Application">
<module name="skimmer" />
<working_directory value="$PROJECT_DIR$" />
<kind value="DIRECTORY" />
<directory value="$PROJECT_DIR$/src" />
<filePath value="$PROJECT_DIR$" />
<method v="2" />
</configuration>
</component>

View File

@ -2,11 +2,13 @@ package main
import ( import (
"flag" "flag"
"fmt"
"git.tiburon.su/USEFULL/skimmer/skimmer" "git.tiburon.su/USEFULL/skimmer/skimmer"
) )
var ( var (
config = skimmer.Config{ config = skimmer.Config{
Address: "localhost:3000",
SessionSecret: "secret123", SessionSecret: "secret123",
RedisConfig: skimmer.RedisConfig{ RedisConfig: skimmer.RedisConfig{
RedisAddr: "127.0.0.1:6379", RedisAddr: "127.0.0.1:6379",
@ -27,5 +29,6 @@ func init() {
func main() { func main() {
flag.Parse() flag.Parse()
api := skimmer.GetApi(&config) api := skimmer.GetApi(&config)
api.Run() fmt.Printf("Open in brouser http://%s\n", config.Address)
api.RunOnAddr(config.Address)
} }

View File

@ -1,43 +1,41 @@
package skimmer package skimmer
import ( import (
"fmt"
"github.com/codegangsta/martini" "github.com/codegangsta/martini"
"github.com/codegangsta/martini-contrib/render" "github.com/codegangsta/martini-contrib/render"
"github.com/codegangsta/martini-contrib/sessions"
"net/http" "net/http"
"strconv" "strconv"
"github.com/codegangsta/martini-contrib/sessions"
"fmt"
) )
type ErrorMsg struct {
type ErrorMsg struct{
Error string `json:"error"` Error string `json:"error"`
} }
const ( const (
REQUEST_BODY_SIZE = 1024 * 30 REQUEST_BODY_SIZE = 1024 * 30
MAX_REQUEST_COUNT = 20 MAX_REQUEST_COUNT = 20
BIN_LIFETIME = 60 * 60 * 24 * 2 BIN_LIFETIME = 60 * 60 * 24 * 2
) )
type RedisConfig struct { type RedisConfig struct {
RedisAddr string RedisAddr string
RedisPassword string RedisPassword string
RedisPrefix string RedisPrefix string
} }
type Config struct { type Config struct {
SessionSecret string Address string
Storage string SessionSecret string
Storage string
RedisConfig RedisConfig
} }
func GetApi(config *Config) *martini.ClassicMartini { func GetApi(config *Config) *martini.ClassicMartini {
var storage Storage var storage Storage
switch config.Storage{ switch config.Storage {
case "redis": case "redis":
redisStorage := NewRedisStorage(config.RedisAddr, config.RedisPassword, config.RedisPassword, MAX_REQUEST_COUNT, BIN_LIFETIME) redisStorage := NewRedisStorage(config.RedisAddr, config.RedisPassword, config.RedisPassword, MAX_REQUEST_COUNT, BIN_LIFETIME)
redisStorage.StartCleaning(60) redisStorage.StartCleaning(60)
@ -47,7 +45,6 @@ func GetApi(config *Config) *martini.ClassicMartini {
memoryStorage.StartCleaning(60) memoryStorage.StartCleaning(60)
storage = memoryStorage storage = memoryStorage
} }
store := sessions.NewCookieStore([]byte(config.SessionSecret)) store := sessions.NewCookieStore([]byte(config.SessionSecret))
@ -55,104 +52,103 @@ func GetApi(config *Config) *martini.ClassicMartini {
api.MapTo(storage, (*Storage)(nil)) api.MapTo(storage, (*Storage)(nil))
api.Use(render.Renderer(render.Options{ api.Use(render.Renderer(render.Options{
Directory: "public/static/views", Directory: "public/static/views",
Extensions: []string{".html"}, Extensions: []string{".html"},
Delims: render.Delims{"{[{", "}]}"}, Delims: render.Delims{"{[{", "}]}"},
})) }))
api.Use(sessions.Sessions("my_session", store)) api.Use(sessions.Sessions("my_session", store))
api.Use(NewSessionHistoryHandler(20, "binHistory")) api.Use(NewSessionHistoryHandler(20, "binHistory"))
api.Post("/api/v1/bins/", func(r render.Render, storage Storage, history History, session sessions.Session, req *http.Request) {
payload := Bin{}
if err := DecodeJsonPayload(req, &payload); err != nil {
r.JSON(400, ErrorMsg{fmt.Sprintf("Decoding payload error: %s", err)})
return
}
bin := NewBin()
if payload.Private {
bin.SetPrivate()
}
if err := storage.CreateBin(bin); err == nil {
history.Add(bin.Name)
if bin.Private {
session.Set(fmt.Sprintf("pr_%s", bin.Name), bin.SecretKey)
}
r.JSON(http.StatusCreated, bin)
} else {
r.JSON(http.StatusInternalServerError, ErrorMsg{err.Error()})
}
})
api.Post("/api/v1/bins/", func(r render.Render, storage Storage, history History, session sessions.Session, req *http.Request){ api.Get("/api/v1/bins/", func(r render.Render, storage Storage, history History) {
payload := Bin{} if bins, err := storage.LookupBins(history.All()); err == nil {
if err := DecodeJsonPayload(req, &payload); err != nil { r.JSON(http.StatusOK, bins)
r.JSON(400, ErrorMsg{fmt.Sprintf("Decoding payload error: %s", err)}) } else {
return r.JSON(http.StatusInternalServerError, ErrorMsg{err.Error()})
} }
bin := NewBin() })
if payload.Private {
bin.SetPrivate()
}
if err := storage.CreateBin(bin); err == nil {
history.Add(bin.Name)
if bin.Private {
session.Set(fmt.Sprintf("pr_%s", bin.Name), bin.SecretKey)
}
r.JSON(http.StatusCreated, bin)
} else {
r.JSON(http.StatusInternalServerError, ErrorMsg{err.Error()})
}
})
api.Get("/api/v1/bins/", func(r render.Render, storage Storage, history History){ api.Get("/api/v1/bins/:bin", func(r render.Render, params martini.Params, session sessions.Session, storage Storage) {
if bins, err := storage.LookupBins(history.All()); err == nil { if bin, err := storage.LookupBin(params["bin"]); err == nil {
r.JSON(http.StatusOK, bins) if bin.Private && bin.SecretKey != session.Get(fmt.Sprintf("pr_%s", bin.Name)) {
r.JSON(http.StatusForbidden, ErrorMsg{"The bin is private"})
} else { } else {
r.JSON(http.StatusInternalServerError, ErrorMsg{err.Error()}) r.JSON(http.StatusOK, bin)
} }
}) } else {
r.JSON(http.StatusNotFound, ErrorMsg{err.Error()})
api.Get("/api/v1/bins/:bin", func(r render.Render, params martini.Params, session sessions.Session, storage Storage){ }
if bin, err := storage.LookupBin(params["bin"]); err == nil{ })
if bin.Private && bin.SecretKey != session.Get(fmt.Sprintf("pr_%s", bin.Name)){
r.JSON(http.StatusForbidden, ErrorMsg{"The bin is private"})
} else {
r.JSON(http.StatusOK, bin)
}
} else {
r.JSON(http.StatusNotFound, ErrorMsg{err.Error()})
}
})
api.Get("/api/v1/bins/:bin/requests/", func(r render.Render, storage Storage, session sessions.Session, api.Get("/api/v1/bins/:bin/requests/", func(r render.Render, storage Storage, session sessions.Session,
params martini.Params, req *http.Request){ params martini.Params, req *http.Request) {
if bin, error := storage.LookupBin(params["bin"]); error == nil { if bin, error := storage.LookupBin(params["bin"]); error == nil {
if bin.Private && bin.SecretKey != session.Get(fmt.Sprintf("pr_%s", bin.Name)){ if bin.Private && bin.SecretKey != session.Get(fmt.Sprintf("pr_%s", bin.Name)) {
r.JSON(http.StatusForbidden, ErrorMsg{"The bin is private"}) r.JSON(http.StatusForbidden, ErrorMsg{"The bin is private"})
} else { } else {
from := 0 from := 0
to := 20 to := 20
if fromVal, err := strconv.Atoi(req.FormValue("from")); err == nil { if fromVal, err := strconv.Atoi(req.FormValue("from")); err == nil {
from = fromVal from = fromVal
}
if toVal, err := strconv.Atoi(req.FormValue("to")); err == nil {
to = toVal
}
if requests, err := storage.LookupRequests(bin.Name, from, to); err == nil {
r.JSON(http.StatusOK, requests)
} else {
r.JSON(http.StatusInternalServerError, ErrorMsg{err.Error()})
}
} }
} else { if toVal, err := strconv.Atoi(req.FormValue("to")); err == nil {
r.Error(http.StatusNotFound) to = toVal
} }
}) if requests, err := storage.LookupRequests(bin.Name, from, to); err == nil {
r.JSON(http.StatusOK, requests)
api.Get("/api/v1/bins/:bin/requests/:request", func(r render.Render, storage Storage, params martini.Params){
if request, err := storage.LookupRequest(params["bin"], params["request"]); err == nil {
r.JSON(http.StatusOK, request)
} else {
r.JSON(http.StatusNotFound, ErrorMsg{err.Error()})
}
})
api.Any("/bins/:name", func(r render.Render, storage Storage, params martini.Params,
req *http.Request){
if bin, error := storage.LookupBin(params["name"]); error == nil {
request := NewRequest(req, REQUEST_BODY_SIZE)
if err := storage.CreateRequest(bin, request); err == nil {
r.JSON(http.StatusOK, request)
} else { } else {
r.JSON(http.StatusInternalServerError, ErrorMsg{err.Error()}) r.JSON(http.StatusInternalServerError, ErrorMsg{err.Error()})
} }
} else {
r.Error(http.StatusNotFound)
} }
}) } else {
r.Error(http.StatusNotFound)
}
})
api.Get("**", func(r render.Render){ api.Get("/api/v1/bins/:bin/requests/:request", func(r render.Render, storage Storage, params martini.Params) {
r.HTML(200, "index", nil) if request, err := storage.LookupRequest(params["bin"], params["request"]); err == nil {
}) r.JSON(http.StatusOK, request)
} else {
r.JSON(http.StatusNotFound, ErrorMsg{err.Error()})
}
})
api.Any("/bins/:name", func(r render.Render, storage Storage, params martini.Params,
req *http.Request) {
if bin, error := storage.LookupBin(params["name"]); error == nil {
request := NewRequest(req, REQUEST_BODY_SIZE)
if err := storage.CreateRequest(bin, request); err == nil {
r.JSON(http.StatusOK, request)
} else {
r.JSON(http.StatusInternalServerError, ErrorMsg{err.Error()})
}
} else {
r.Error(http.StatusNotFound)
}
})
api.Get("**", func(r render.Render) {
r.HTML(200, "index", nil)
})
return api return api
} }