|
|
|
@ -10,7 +10,7 @@ import (
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"gitlab.com/mporrato/uBrowserSync/syncstore"
|
|
|
|
|
"gitlab.com/mporrato/uBrowserSync/bsync"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
@ -27,14 +27,14 @@ const (
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
store syncstore.Store
|
|
|
|
|
store bsync.Store
|
|
|
|
|
maxSyncSize = defaultMaxSyncSize
|
|
|
|
|
maxSyncs = defaultMaxSyncs
|
|
|
|
|
listen string
|
|
|
|
|
serviceStatus = statusOnline
|
|
|
|
|
sidRe = regexp.MustCompile("^[[:xdigit:]]{32}$")
|
|
|
|
|
|
|
|
|
|
invalidRequestError = syncstore.NewSyncError(
|
|
|
|
|
invalidRequestError = bsync.NewSyncError(
|
|
|
|
|
"Invalid request",
|
|
|
|
|
"Malformed request body",
|
|
|
|
|
http.StatusBadRequest)
|
|
|
|
@ -60,11 +60,11 @@ func sendJSONOk(w http.ResponseWriter, data interface{}) {
|
|
|
|
|
|
|
|
|
|
func sendJSONError(w http.ResponseWriter, err error) {
|
|
|
|
|
switch e := err.(type) {
|
|
|
|
|
case syncstore.SyncError:
|
|
|
|
|
case bsync.SyncError:
|
|
|
|
|
sendJSON(w, e.StatusCode, e.Payload)
|
|
|
|
|
default:
|
|
|
|
|
sendJSON(w, http.StatusInternalServerError,
|
|
|
|
|
syncstore.ErrorPayload{
|
|
|
|
|
bsync.ErrorPayload{
|
|
|
|
|
Code: "Internal server error",
|
|
|
|
|
Message: e.Error()})
|
|
|
|
|
}
|
|
|
|
@ -72,10 +72,10 @@ func sendJSONError(w http.ResponseWriter, err error) {
|
|
|
|
|
|
|
|
|
|
func info(w http.ResponseWriter, req *http.Request) {
|
|
|
|
|
if req.Method != "GET" || req.URL.Path != "/info" {
|
|
|
|
|
sendJSONError(w, syncstore.NotImplementedError)
|
|
|
|
|
sendJSONError(w, bsync.NotImplementedError)
|
|
|
|
|
} else {
|
|
|
|
|
log.Println("info()")
|
|
|
|
|
serviceInfo := syncstore.ServiceInfoResp{
|
|
|
|
|
serviceInfo := bsync.ServiceInfoResp{
|
|
|
|
|
Version: apiVersion,
|
|
|
|
|
Message: infoMessage,
|
|
|
|
|
Status: serviceStatus,
|
|
|
|
@ -86,7 +86,7 @@ func info(w http.ResponseWriter, req *http.Request) {
|
|
|
|
|
|
|
|
|
|
func ensureJSONRequest(w http.ResponseWriter, req *http.Request) bool {
|
|
|
|
|
if strings.ToLower(req.Header["Content-Type"][0]) != "application/json" {
|
|
|
|
|
sendJSONError(w, syncstore.RequiredDataNotFoundError)
|
|
|
|
|
sendJSONError(w, bsync.RequiredDataNotFoundError)
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
@ -94,13 +94,13 @@ func ensureJSONRequest(w http.ResponseWriter, req *http.Request) bool {
|
|
|
|
|
|
|
|
|
|
func createSync(w http.ResponseWriter, req *http.Request) {
|
|
|
|
|
if serviceStatus != statusOnline {
|
|
|
|
|
sendJSONError(w, syncstore.NewSyncsForbiddenError)
|
|
|
|
|
sendJSONError(w, bsync.NewSyncsForbiddenError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if !ensureJSONRequest(w, req) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
body := new(syncstore.CreateReq)
|
|
|
|
|
body := new(bsync.CreateReq)
|
|
|
|
|
req.Body = http.MaxBytesReader(w, req.Body, 10000)
|
|
|
|
|
err := json.NewDecoder(req.Body).Decode(&body)
|
|
|
|
|
if err != nil {
|
|
|
|
@ -137,7 +137,7 @@ func getLastUpdated(syncId string, w http.ResponseWriter, _ *http.Request) {
|
|
|
|
|
sendJSONError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
sendJSONOk(w, syncstore.LastUpdatedResp{LastUpdated: resp})
|
|
|
|
|
sendJSONOk(w, bsync.LastUpdatedResp{LastUpdated: resp})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getVersion(syncId string, w http.ResponseWriter, _ *http.Request) {
|
|
|
|
@ -146,14 +146,14 @@ func getVersion(syncId string, w http.ResponseWriter, _ *http.Request) {
|
|
|
|
|
sendJSONError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
sendJSONOk(w, syncstore.GetSyncVerResp{Version: resp})
|
|
|
|
|
sendJSONOk(w, bsync.GetSyncVerResp{Version: resp})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func updateSync(syncId string, w http.ResponseWriter, req *http.Request) {
|
|
|
|
|
if !ensureJSONRequest(w, req) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
body := new(syncstore.UpdateReq)
|
|
|
|
|
body := new(bsync.UpdateReq)
|
|
|
|
|
req.Body = http.MaxBytesReader(w, req.Body, int64(10000+maxSyncSize))
|
|
|
|
|
err := json.NewDecoder(req.Body).Decode(&body)
|
|
|
|
|
if err != nil {
|
|
|
|
@ -161,7 +161,7 @@ func updateSync(syncId string, w http.ResponseWriter, req *http.Request) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if len(body.Bookmarks) > maxSyncSize {
|
|
|
|
|
sendJSONError(w, syncstore.SyncDataLimitExceededError)
|
|
|
|
|
sendJSONError(w, bsync.SyncDataLimitExceededError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
resp, err := store.Update(syncId, body.Bookmarks, body.LastUpdated)
|
|
|
|
@ -169,7 +169,7 @@ func updateSync(syncId string, w http.ResponseWriter, req *http.Request) {
|
|
|
|
|
sendJSONError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
sendJSONOk(w, syncstore.UpdateResp{LastUpdated: resp})
|
|
|
|
|
sendJSONOk(w, bsync.UpdateResp{LastUpdated: resp})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func bookmarks(w http.ResponseWriter, req *http.Request) {
|
|
|
|
@ -181,13 +181,13 @@ func bookmarks(w http.ResponseWriter, req *http.Request) {
|
|
|
|
|
createSync(w, req)
|
|
|
|
|
return
|
|
|
|
|
} else {
|
|
|
|
|
sendJSONError(w, syncstore.MethodNotImplementedError)
|
|
|
|
|
sendJSONError(w, bsync.MethodNotImplementedError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
syncId := elements[1]
|
|
|
|
|
if !sidRe.MatchString(syncId) {
|
|
|
|
|
sendJSONError(w, syncstore.NotImplementedError)
|
|
|
|
|
sendJSONError(w, bsync.NotImplementedError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if len(elements) == 2 {
|
|
|
|
@ -202,7 +202,7 @@ func bookmarks(w http.ResponseWriter, req *http.Request) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// TODO: Handle HEAD requests
|
|
|
|
|
sendJSONError(w, syncstore.MethodNotImplementedError)
|
|
|
|
|
sendJSONError(w, bsync.MethodNotImplementedError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if len(elements) == 3 {
|
|
|
|
@ -212,7 +212,7 @@ func bookmarks(w http.ResponseWriter, req *http.Request) {
|
|
|
|
|
getLastUpdated(syncId, w, req)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
sendJSONError(w, syncstore.MethodNotImplementedError)
|
|
|
|
|
sendJSONError(w, bsync.MethodNotImplementedError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if elements[2] == "version" {
|
|
|
|
@ -221,22 +221,22 @@ func bookmarks(w http.ResponseWriter, req *http.Request) {
|
|
|
|
|
getVersion(syncId, w, req)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
sendJSONError(w, syncstore.MethodNotImplementedError)
|
|
|
|
|
sendJSONError(w, bsync.MethodNotImplementedError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sendJSONError(w, syncstore.NotImplementedError)
|
|
|
|
|
sendJSONError(w, bsync.NotImplementedError)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func notFound(w http.ResponseWriter, _ *http.Request) {
|
|
|
|
|
sendJSONError(w, syncstore.NotImplementedError)
|
|
|
|
|
sendJSONError(w, bsync.NotImplementedError)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
|
var (
|
|
|
|
|
err error
|
|
|
|
|
storeFlag string
|
|
|
|
|
storeDrv syncstore.StoreDriver
|
|
|
|
|
storeDrv bsync.StoreDriver
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
flag.StringVar(&listen, "listen", ":8090", "listen address and port")
|
|
|
|
@ -252,17 +252,17 @@ func init() {
|
|
|
|
|
if len(storeFlagTokens) != 2 {
|
|
|
|
|
err = fmt.Errorf("argument required for fs store driver")
|
|
|
|
|
} else {
|
|
|
|
|
storeDrv, err = syncstore.NewFSStore(storeFlagTokens[1])
|
|
|
|
|
storeDrv, err = bsync.NewFSStore(storeFlagTokens[1])
|
|
|
|
|
}
|
|
|
|
|
case "mem":
|
|
|
|
|
storeDrv, err = syncstore.NewMemStore()
|
|
|
|
|
storeDrv, err = bsync.NewMemStore()
|
|
|
|
|
default:
|
|
|
|
|
err = fmt.Errorf("Invalid store driver: " + storeFlagTokens[0])
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatalf("store initialization failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
store = syncstore.NewStore(storeDrv)
|
|
|
|
|
store = bsync.NewStore(storeDrv)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|