Set http status after modifying response headers.
This commit is contained in:
@@ -3,6 +3,7 @@ package weed_server
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -24,7 +25,7 @@ func init() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeJson(w http.ResponseWriter, r *http.Request, obj interface{}) (err error) {
|
func writeJson(w http.ResponseWriter, r *http.Request, httpStatus int, obj interface{}) (err error) {
|
||||||
var bytes []byte
|
var bytes []byte
|
||||||
if r.FormValue("pretty") != "" {
|
if r.FormValue("pretty") != "" {
|
||||||
bytes, err = json.MarshalIndent(obj, "", " ")
|
bytes, err = json.MarshalIndent(obj, "", " ")
|
||||||
@@ -37,9 +38,11 @@ func writeJson(w http.ResponseWriter, r *http.Request, obj interface{}) (err err
|
|||||||
callback := r.FormValue("callback")
|
callback := r.FormValue("callback")
|
||||||
if callback == "" {
|
if callback == "" {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(httpStatus)
|
||||||
_, err = w.Write(bytes)
|
_, err = w.Write(bytes)
|
||||||
} else {
|
} else {
|
||||||
w.Header().Set("Content-Type", "application/javascript")
|
w.Header().Set("Content-Type", "application/javascript")
|
||||||
|
w.WriteHeader(httpStatus)
|
||||||
if _, err = w.Write([]uint8(callback)); err != nil {
|
if _, err = w.Write([]uint8(callback)); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -51,20 +54,21 @@ func writeJson(w http.ResponseWriter, r *http.Request, obj interface{}) (err err
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// wrapper for writeJson - just logs errors
|
// wrapper for writeJson - just logs errors
|
||||||
func writeJsonQuiet(w http.ResponseWriter, r *http.Request, obj interface{}) {
|
func writeJsonQuiet(w http.ResponseWriter, r *http.Request, httpStatus int, obj interface{}) {
|
||||||
if err := writeJson(w, r, obj); err != nil {
|
if err := writeJson(w, r, httpStatus, obj); err != nil {
|
||||||
glog.V(0).Infof("error writing JSON %s: %s", obj, err.Error())
|
glog.V(0).Infof("error writing JSON %s: %s", obj, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func writeJsonError(w http.ResponseWriter, r *http.Request, err error) {
|
func writeJsonError(w http.ResponseWriter, r *http.Request, httpStatus int, err error) {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
m := make(map[string]interface{})
|
m := make(map[string]interface{})
|
||||||
m["error"] = err.Error()
|
m["error"] = err.Error()
|
||||||
writeJsonQuiet(w, r, m)
|
writeJsonQuiet(w, r, httpStatus, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func debug(params ...interface{}) {
|
func debug(params ...interface{}) {
|
||||||
@@ -74,15 +78,14 @@ func debug(params ...interface{}) {
|
|||||||
func submitForClientHandler(w http.ResponseWriter, r *http.Request, masterUrl string) {
|
func submitForClientHandler(w http.ResponseWriter, r *http.Request, masterUrl string) {
|
||||||
m := make(map[string]interface{})
|
m := make(map[string]interface{})
|
||||||
if r.Method != "POST" {
|
if r.Method != "POST" {
|
||||||
m["error"] = "Only submit via POST!"
|
writeJsonError(w, r, http.StatusMethodNotAllowed, errors.New("Only submit via POST!"))
|
||||||
writeJsonQuiet(w, r, m)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("parsing upload file...")
|
debug("parsing upload file...")
|
||||||
fname, data, mimeType, isGzipped, lastModified, _, pe := storage.ParseUpload(r)
|
fname, data, mimeType, isGzipped, lastModified, _, pe := storage.ParseUpload(r)
|
||||||
if pe != nil {
|
if pe != nil {
|
||||||
writeJsonError(w, r, pe)
|
writeJsonError(w, r, http.StatusBadRequest, pe)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +93,7 @@ func submitForClientHandler(w http.ResponseWriter, r *http.Request, masterUrl st
|
|||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
assignResult, ae := operation.Assign(masterUrl, 1, r.FormValue("replication"), r.FormValue("collection"), r.FormValue("ttl"))
|
assignResult, ae := operation.Assign(masterUrl, 1, r.FormValue("replication"), r.FormValue("collection"), r.FormValue("ttl"))
|
||||||
if ae != nil {
|
if ae != nil {
|
||||||
writeJsonError(w, r, ae)
|
writeJsonError(w, r, http.StatusInternalServerError, ae)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +105,7 @@ func submitForClientHandler(w http.ResponseWriter, r *http.Request, masterUrl st
|
|||||||
debug("upload file to store", url)
|
debug("upload file to store", url)
|
||||||
uploadResult, err := operation.Upload(url, fname, bytes.NewReader(data), isGzipped, mimeType)
|
uploadResult, err := operation.Upload(url, fname, bytes.NewReader(data), isGzipped, mimeType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeJsonError(w, r, err)
|
writeJsonError(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +113,7 @@ func submitForClientHandler(w http.ResponseWriter, r *http.Request, masterUrl st
|
|||||||
m["fid"] = assignResult.Fid
|
m["fid"] = assignResult.Fid
|
||||||
m["fileUrl"] = assignResult.PublicUrl + "/" + assignResult.Fid
|
m["fileUrl"] = assignResult.PublicUrl + "/" + assignResult.Fid
|
||||||
m["size"] = uploadResult.Size
|
m["size"] = uploadResult.Size
|
||||||
writeJsonQuiet(w, r, m)
|
writeJsonQuiet(w, r, http.StatusCreated, m)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,10 +122,10 @@ func deleteForClientHandler(w http.ResponseWriter, r *http.Request, masterUrl st
|
|||||||
fids := r.Form["fid"]
|
fids := r.Form["fid"]
|
||||||
ret, err := operation.DeleteFiles(masterUrl, fids)
|
ret, err := operation.DeleteFiles(masterUrl, fids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeJsonError(w, r, err)
|
writeJsonError(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
writeJsonQuiet(w, r, ret)
|
writeJsonQuiet(w, r, http.StatusAccepted, ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseURLPath(path string) (vid, fid, filename, ext string, isVolumeIdOnly bool) {
|
func parseURLPath(path string) (vid, fid, filename, ext string, isVolumeIdOnly bool) {
|
||||||
@@ -162,12 +165,12 @@ func statsCounterHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
m := make(map[string]interface{})
|
m := make(map[string]interface{})
|
||||||
m["Version"] = util.VERSION
|
m["Version"] = util.VERSION
|
||||||
m["Counters"] = serverStats
|
m["Counters"] = serverStats
|
||||||
writeJsonQuiet(w, r, m)
|
writeJsonQuiet(w, r, http.StatusOK, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func statsMemoryHandler(w http.ResponseWriter, r *http.Request) {
|
func statsMemoryHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
m := make(map[string]interface{})
|
m := make(map[string]interface{})
|
||||||
m["Version"] = util.VERSION
|
m["Version"] = util.VERSION
|
||||||
m["Memory"] = stats.MemStat()
|
m["Memory"] = stats.MemStat()
|
||||||
writeJsonQuiet(w, r, m)
|
writeJsonQuiet(w, r, http.StatusOK, m)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func (fs *FilerServer) listDirectoryHandler(w http.ResponseWriter, r *http.Reque
|
|||||||
limit = 100
|
limit = 100
|
||||||
}
|
}
|
||||||
m["Files"], _ = fs.filer.ListFiles(r.URL.Path, lastFileName, limit)
|
m["Files"], _ = fs.filer.ListFiles(r.URL.Path, lastFileName, limit)
|
||||||
writeJsonQuiet(w, r, m)
|
writeJsonQuiet(w, r, http.StatusOK, m)
|
||||||
}
|
}
|
||||||
func (fs *FilerServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request, isGetMethod bool) {
|
func (fs *FilerServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request, isGetMethod bool) {
|
||||||
if strings.HasSuffix(r.URL.Path, "/") {
|
if strings.HasSuffix(r.URL.Path, "/") {
|
||||||
@@ -102,7 +102,7 @@ func (fs *FilerServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request,
|
|||||||
resp, do_err := util.Do(request)
|
resp, do_err := util.Do(request)
|
||||||
if do_err != nil {
|
if do_err != nil {
|
||||||
glog.V(0).Infoln("failing to connect to volume server", do_err.Error())
|
glog.V(0).Infoln("failing to connect to volume server", do_err.Error())
|
||||||
writeJsonError(w, r, do_err)
|
writeJsonError(w, r, http.StatusInternalServerError, do_err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
@@ -122,7 +122,7 @@ func (fs *FilerServer) PostHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
assignResult, ae := operation.Assign(fs.master, 1, replication, fs.collection, query.Get("ttl"))
|
assignResult, ae := operation.Assign(fs.master, 1, replication, fs.collection, query.Get("ttl"))
|
||||||
if ae != nil {
|
if ae != nil {
|
||||||
glog.V(0).Infoln("failing to assign a file id", ae.Error())
|
glog.V(0).Infoln("failing to assign a file id", ae.Error())
|
||||||
writeJsonError(w, r, ae)
|
writeJsonError(w, r, http.StatusInternalServerError, ae)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,14 +142,14 @@ func (fs *FilerServer) PostHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
resp, do_err := util.Do(request)
|
resp, do_err := util.Do(request)
|
||||||
if do_err != nil {
|
if do_err != nil {
|
||||||
glog.V(0).Infoln("failing to connect to volume server", r.RequestURI, do_err.Error())
|
glog.V(0).Infoln("failing to connect to volume server", r.RequestURI, do_err.Error())
|
||||||
writeJsonError(w, r, do_err)
|
writeJsonError(w, r, http.StatusInternalServerError, do_err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
resp_body, ra_err := ioutil.ReadAll(resp.Body)
|
resp_body, ra_err := ioutil.ReadAll(resp.Body)
|
||||||
if ra_err != nil {
|
if ra_err != nil {
|
||||||
glog.V(0).Infoln("failing to upload to volume server", r.RequestURI, ra_err.Error())
|
glog.V(0).Infoln("failing to upload to volume server", r.RequestURI, ra_err.Error())
|
||||||
writeJsonError(w, r, ra_err)
|
writeJsonError(w, r, http.StatusInternalServerError, ra_err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
glog.V(4).Infoln("post result", string(resp_body))
|
glog.V(4).Infoln("post result", string(resp_body))
|
||||||
@@ -157,12 +157,12 @@ func (fs *FilerServer) PostHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
unmarshal_err := json.Unmarshal(resp_body, &ret)
|
unmarshal_err := json.Unmarshal(resp_body, &ret)
|
||||||
if unmarshal_err != nil {
|
if unmarshal_err != nil {
|
||||||
glog.V(0).Infoln("failing to read upload resonse", r.RequestURI, string(resp_body))
|
glog.V(0).Infoln("failing to read upload resonse", r.RequestURI, string(resp_body))
|
||||||
writeJsonError(w, r, unmarshal_err)
|
writeJsonError(w, r, http.StatusInternalServerError, unmarshal_err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ret.Error != "" {
|
if ret.Error != "" {
|
||||||
glog.V(0).Infoln("failing to post to volume server", r.RequestURI, ret.Error)
|
glog.V(0).Infoln("failing to post to volume server", r.RequestURI, ret.Error)
|
||||||
writeJsonError(w, r, errors.New(ret.Error))
|
writeJsonError(w, r, http.StatusInternalServerError, errors.New(ret.Error))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
path := r.URL.Path
|
path := r.URL.Path
|
||||||
@@ -172,7 +172,8 @@ func (fs *FilerServer) PostHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
} else {
|
} else {
|
||||||
operation.DeleteFile(fs.master, assignResult.Fid) //clean up
|
operation.DeleteFile(fs.master, assignResult.Fid) //clean up
|
||||||
glog.V(0).Infoln("Can not to write to folder", path, "without a file name!")
|
glog.V(0).Infoln("Can not to write to folder", path, "without a file name!")
|
||||||
writeJsonError(w, r, errors.New("Can not to write to folder "+path+" without a file name"))
|
writeJsonError(w, r, http.StatusInternalServerError,
|
||||||
|
errors.New("Can not to write to folder "+path+" without a file name"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,7 +181,7 @@ func (fs *FilerServer) PostHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
if db_err := fs.filer.CreateFile(path, assignResult.Fid); db_err != nil {
|
if db_err := fs.filer.CreateFile(path, assignResult.Fid); db_err != nil {
|
||||||
operation.DeleteFile(fs.master, assignResult.Fid) //clean up
|
operation.DeleteFile(fs.master, assignResult.Fid) //clean up
|
||||||
glog.V(0).Infof("failing to write %s to filer server : %v", path, db_err)
|
glog.V(0).Infof("failing to write %s to filer server : %v", path, db_err)
|
||||||
writeJsonError(w, r, db_err)
|
writeJsonError(w, r, http.StatusInternalServerError, db_err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusCreated)
|
w.WriteHeader(http.StatusCreated)
|
||||||
@@ -201,10 +202,9 @@ func (fs *FilerServer) DeleteHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
w.WriteHeader(http.StatusAccepted)
|
writeJsonQuiet(w, r, http.StatusAccepted, map[string]string{"error": ""})
|
||||||
writeJsonQuiet(w, r, map[string]string{"error": ""})
|
|
||||||
} else {
|
} else {
|
||||||
glog.V(4).Infoln("deleting", r.URL.Path, ":", err.Error())
|
glog.V(4).Infoln("deleting", r.URL.Path, ":", err.Error())
|
||||||
writeJsonError(w, r, err)
|
writeJsonError(w, r, http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func (fs *FilerServer) moveHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := fs.filer.Move(from, to)
|
err := fs.filer.Move(from, to)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(4).Infoln("moving", from, "->", to, err.Error())
|
glog.V(4).Infoln("moving", from, "->", to, err.Error())
|
||||||
writeJsonError(w, r, err)
|
writeJsonError(w, r, http.StatusInternalServerError, err)
|
||||||
} else {
|
} else {
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package weed_server
|
package weed_server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -103,7 +104,8 @@ func (ms *MasterServer) proxyToLeader(f func(w http.ResponseWriter, r *http.Requ
|
|||||||
defer func() { <-ms.bounedLeaderChan }()
|
defer func() { <-ms.bounedLeaderChan }()
|
||||||
targetUrl, err := url.Parse("http://" + ms.Topo.RaftServer.Leader())
|
targetUrl, err := url.Parse("http://" + ms.Topo.RaftServer.Leader())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeJsonQuiet(w, r, map[string]interface{}{"error": "Leader URL http://" + ms.Topo.RaftServer.Leader() + " Parse Error " + err.Error()})
|
writeJsonError(w, r, http.StatusInternalServerError,
|
||||||
|
fmt.Errorf("Leader URL http://%s Parse Error: %v", ms.Topo.RaftServer.Leader(), err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
glog.V(4).Infoln("proxying to leader", ms.Topo.RaftServer.Leader())
|
glog.V(4).Infoln("proxying to leader", ms.Topo.RaftServer.Leader())
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package weed_server
|
package weed_server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -50,10 +51,11 @@ func (ms *MasterServer) dirLookupHandler(w http.ResponseWriter, r *http.Request)
|
|||||||
collection := r.FormValue("collection") //optional, but can be faster if too many collections
|
collection := r.FormValue("collection") //optional, but can be faster if too many collections
|
||||||
volumeLocations := ms.lookupVolumeId(vids, collection)
|
volumeLocations := ms.lookupVolumeId(vids, collection)
|
||||||
location := volumeLocations[vid]
|
location := volumeLocations[vid]
|
||||||
|
httpStatus := http.StatusOK
|
||||||
if location.Error != "" {
|
if location.Error != "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
httpStatus = http.StatusNotFound
|
||||||
}
|
}
|
||||||
writeJsonQuiet(w, r, location)
|
writeJsonQuiet(w, r, httpStatus, location)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This can take batched volumeIds, &volumeId=x&volumeId=y&volumeId=z
|
// This can take batched volumeIds, &volumeId=x&volumeId=y&volumeId=z
|
||||||
@@ -62,7 +64,7 @@ func (ms *MasterServer) volumeLookupHandler(w http.ResponseWriter, r *http.Reque
|
|||||||
vids := r.Form["volumeId"]
|
vids := r.Form["volumeId"]
|
||||||
collection := r.FormValue("collection") //optional, but can be faster if too many collections
|
collection := r.FormValue("collection") //optional, but can be faster if too many collections
|
||||||
volumeLocations := ms.lookupVolumeId(vids, collection)
|
volumeLocations := ms.lookupVolumeId(vids, collection)
|
||||||
writeJsonQuiet(w, r, volumeLocations)
|
writeJsonQuiet(w, r, http.StatusOK, volumeLocations)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ms *MasterServer) dirAssignHandler(w http.ResponseWriter, r *http.Request) {
|
func (ms *MasterServer) dirAssignHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -74,22 +76,21 @@ func (ms *MasterServer) dirAssignHandler(w http.ResponseWriter, r *http.Request)
|
|||||||
|
|
||||||
option, err := ms.getVolumeGrowOption(r)
|
option, err := ms.getVolumeGrowOption(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusNotAcceptable)
|
writeJsonQuiet(w, r, http.StatusNotAcceptable, operation.AssignResult{Error: err.Error()})
|
||||||
writeJsonQuiet(w, r, operation.AssignResult{Error: err.Error()})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ms.Topo.HasWritableVolume(option) {
|
if !ms.Topo.HasWritableVolume(option) {
|
||||||
if ms.Topo.FreeSpace() <= 0 {
|
if ms.Topo.FreeSpace() <= 0 {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
writeJsonQuiet(w, r, http.StatusNotFound, operation.AssignResult{Error: "No free volumes left!"})
|
||||||
writeJsonQuiet(w, r, operation.AssignResult{Error: "No free volumes left!"})
|
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
ms.vgLock.Lock()
|
ms.vgLock.Lock()
|
||||||
defer ms.vgLock.Unlock()
|
defer ms.vgLock.Unlock()
|
||||||
if !ms.Topo.HasWritableVolume(option) {
|
if !ms.Topo.HasWritableVolume(option) {
|
||||||
if _, err = ms.vg.AutomaticGrowByType(option, ms.Topo); err != nil {
|
if _, err = ms.vg.AutomaticGrowByType(option, ms.Topo); err != nil {
|
||||||
writeJsonQuiet(w, r, operation.AssignResult{Error: "Cannot grow volume group! " + err.Error()})
|
writeJsonError(w, r, http.StatusInternalServerError,
|
||||||
|
fmt.Errorf("Cannot grow volume group! %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,9 +98,8 @@ func (ms *MasterServer) dirAssignHandler(w http.ResponseWriter, r *http.Request)
|
|||||||
}
|
}
|
||||||
fid, count, dn, err := ms.Topo.PickForWrite(requestedCount, option)
|
fid, count, dn, err := ms.Topo.PickForWrite(requestedCount, option)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
writeJsonQuiet(w, r, operation.AssignResult{Fid: fid, Url: dn.Url(), PublicUrl: dn.PublicUrl, Count: count})
|
writeJsonQuiet(w, r, http.StatusOK, operation.AssignResult{Fid: fid, Url: dn.Url(), PublicUrl: dn.PublicUrl, Count: count})
|
||||||
} else {
|
} else {
|
||||||
w.WriteHeader(http.StatusNotAcceptable)
|
writeJsonQuiet(w, r, http.StatusNotAcceptable, operation.AssignResult{Error: err.Error()})
|
||||||
writeJsonQuiet(w, r, operation.AssignResult{Error: err.Error()})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package weed_server
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -19,13 +20,13 @@ import (
|
|||||||
func (ms *MasterServer) collectionDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
func (ms *MasterServer) collectionDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
collection, ok := ms.Topo.GetCollection(r.FormValue("collection"))
|
collection, ok := ms.Topo.GetCollection(r.FormValue("collection"))
|
||||||
if !ok {
|
if !ok {
|
||||||
writeJsonQuiet(w, r, map[string]interface{}{"error": "collection " + r.FormValue("collection") + "does not exist!"})
|
writeJsonError(w, r, http.StatusBadRequest, fmt.Errorf("collection %s does not exist!", r.FormValue("collection")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, server := range collection.ListVolumeServers() {
|
for _, server := range collection.ListVolumeServers() {
|
||||||
_, err := util.Get("http://" + server.Ip + ":" + strconv.Itoa(server.Port) + "/admin/delete_collection?collection=" + r.FormValue("collection"))
|
_, err := util.Get("http://" + server.Ip + ":" + strconv.Itoa(server.Port) + "/admin/delete_collection?collection=" + r.FormValue("collection"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeJsonQuiet(w, r, map[string]string{"error": err.Error()})
|
writeJsonError(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,12 +36,12 @@ func (ms *MasterServer) collectionDeleteHandler(w http.ResponseWriter, r *http.R
|
|||||||
func (ms *MasterServer) dirJoinHandler(w http.ResponseWriter, r *http.Request) {
|
func (ms *MasterServer) dirJoinHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
body, err := ioutil.ReadAll(r.Body)
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeJsonError(w, r, err)
|
writeJsonError(w, r, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
joinMessage := &operation.JoinMessage{}
|
joinMessage := &operation.JoinMessage{}
|
||||||
if err = proto.Unmarshal(body, joinMessage); err != nil {
|
if err = proto.Unmarshal(body, joinMessage); err != nil {
|
||||||
writeJsonError(w, r, err)
|
writeJsonError(w, r, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if *joinMessage.Ip == "" {
|
if *joinMessage.Ip == "" {
|
||||||
@@ -49,7 +50,7 @@ func (ms *MasterServer) dirJoinHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
if glog.V(4) {
|
if glog.V(4) {
|
||||||
if jsonData, jsonError := json.Marshal(joinMessage); jsonError != nil {
|
if jsonData, jsonError := json.Marshal(joinMessage); jsonError != nil {
|
||||||
glog.V(0).Infoln("json marshaling error: ", jsonError)
|
glog.V(0).Infoln("json marshaling error: ", jsonError)
|
||||||
writeJsonError(w, r, jsonError)
|
writeJsonError(w, r, http.StatusBadRequest, jsonError)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
glog.V(4).Infoln("Proto size", len(body), "json size", len(jsonData), string(jsonData))
|
glog.V(4).Infoln("Proto size", len(body), "json size", len(jsonData), string(jsonData))
|
||||||
@@ -57,14 +58,14 @@ func (ms *MasterServer) dirJoinHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ms.Topo.ProcessJoinMessage(joinMessage)
|
ms.Topo.ProcessJoinMessage(joinMessage)
|
||||||
writeJsonQuiet(w, r, operation.JoinResult{VolumeSizeLimit: uint64(ms.volumeSizeLimitMB) * 1024 * 1024})
|
writeJsonQuiet(w, r, http.StatusOK, operation.JoinResult{VolumeSizeLimit: uint64(ms.volumeSizeLimitMB) * 1024 * 1024})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ms *MasterServer) dirStatusHandler(w http.ResponseWriter, r *http.Request) {
|
func (ms *MasterServer) dirStatusHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
m := make(map[string]interface{})
|
m := make(map[string]interface{})
|
||||||
m["Version"] = util.VERSION
|
m["Version"] = util.VERSION
|
||||||
m["Topology"] = ms.Topo.ToMap()
|
m["Topology"] = ms.Topo.ToMap()
|
||||||
writeJsonQuiet(w, r, m)
|
writeJsonQuiet(w, r, http.StatusOK, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ms *MasterServer) volumeVacuumHandler(w http.ResponseWriter, r *http.Request) {
|
func (ms *MasterServer) volumeVacuumHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -81,8 +82,7 @@ func (ms *MasterServer) volumeGrowHandler(w http.ResponseWriter, r *http.Request
|
|||||||
count := 0
|
count := 0
|
||||||
option, err := ms.getVolumeGrowOption(r)
|
option, err := ms.getVolumeGrowOption(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusNotAcceptable)
|
writeJsonError(w, r, http.StatusNotAcceptable, err)
|
||||||
writeJsonQuiet(w, r, map[string]string{"error": err.Error()})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -97,11 +97,9 @@ func (ms *MasterServer) volumeGrowHandler(w http.ResponseWriter, r *http.Request
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusNotAcceptable)
|
writeJsonError(w, r, http.StatusNotAcceptable, err)
|
||||||
writeJsonQuiet(w, r, map[string]string{"error": err.Error()})
|
|
||||||
} else {
|
} else {
|
||||||
w.WriteHeader(http.StatusOK)
|
writeJsonQuiet(w, r, http.StatusOK, map[string]interface{}{"count": count})
|
||||||
writeJsonQuiet(w, r, map[string]interface{}{"count": count})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +107,7 @@ func (ms *MasterServer) volumeStatusHandler(w http.ResponseWriter, r *http.Reque
|
|||||||
m := make(map[string]interface{})
|
m := make(map[string]interface{})
|
||||||
m["Version"] = util.VERSION
|
m["Version"] = util.VERSION
|
||||||
m["Volumes"] = ms.Topo.ToVolumeMap()
|
m["Volumes"] = ms.Topo.ToVolumeMap()
|
||||||
writeJsonQuiet(w, r, m)
|
writeJsonQuiet(w, r, http.StatusOK, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ms *MasterServer) redirectHandler(w http.ResponseWriter, r *http.Request) {
|
func (ms *MasterServer) redirectHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -123,8 +121,7 @@ func (ms *MasterServer) redirectHandler(w http.ResponseWriter, r *http.Request)
|
|||||||
if machines != nil && len(machines) > 0 {
|
if machines != nil && len(machines) > 0 {
|
||||||
http.Redirect(w, r, "http://"+machines[0].PublicUrl+r.URL.Path, http.StatusMovedPermanently)
|
http.Redirect(w, r, "http://"+machines[0].PublicUrl+r.URL.Path, http.StatusMovedPermanently)
|
||||||
} else {
|
} else {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
writeJsonError(w, r, http.StatusNotFound, fmt.Errorf("volume id %s not found.", volumeId))
|
||||||
writeJsonQuiet(w, r, map[string]string{"error": "volume id " + volumeId.String() + " not found. "})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,5 +60,5 @@ func (s *RaftServer) statusHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
if leader, e := s.topo.Leader(); e == nil {
|
if leader, e := s.topo.Leader(); e == nil {
|
||||||
ret.Leader = leader
|
ret.Leader = leader
|
||||||
}
|
}
|
||||||
writeJsonQuiet(w, r, ret)
|
writeJsonQuiet(w, r, http.StatusOK, ret)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package weed_server
|
package weed_server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"mime"
|
"mime"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
@@ -235,35 +236,34 @@ func (vs *VolumeServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request)
|
|||||||
func (vs *VolumeServer) PostHandler(w http.ResponseWriter, r *http.Request) {
|
func (vs *VolumeServer) PostHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
if e := r.ParseForm(); e != nil {
|
if e := r.ParseForm(); e != nil {
|
||||||
glog.V(0).Infoln("form parse error:", e)
|
glog.V(0).Infoln("form parse error:", e)
|
||||||
writeJsonError(w, r, e)
|
writeJsonError(w, r, http.StatusBadRequest, e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
vid, _, _, _, _ := parseURLPath(r.URL.Path)
|
vid, _, _, _, _ := parseURLPath(r.URL.Path)
|
||||||
volumeId, ve := storage.NewVolumeId(vid)
|
volumeId, ve := storage.NewVolumeId(vid)
|
||||||
if ve != nil {
|
if ve != nil {
|
||||||
glog.V(0).Infoln("NewVolumeId error:", ve)
|
glog.V(0).Infoln("NewVolumeId error:", ve)
|
||||||
writeJsonError(w, r, ve)
|
writeJsonError(w, r, http.StatusBadRequest, ve)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
needle, ne := storage.NewNeedle(r, vs.FixJpgOrientation)
|
needle, ne := storage.NewNeedle(r, vs.FixJpgOrientation)
|
||||||
if ne != nil {
|
if ne != nil {
|
||||||
writeJsonError(w, r, ne)
|
writeJsonError(w, r, http.StatusBadRequest, ne)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ret := operation.UploadResult{}
|
ret := operation.UploadResult{}
|
||||||
size, errorStatus := topology.ReplicatedWrite(vs.masterNode, vs.store, volumeId, needle, r)
|
size, errorStatus := topology.ReplicatedWrite(vs.masterNode, vs.store, volumeId, needle, r)
|
||||||
if errorStatus == "" {
|
httpStatus := http.StatusCreated
|
||||||
w.WriteHeader(http.StatusCreated)
|
if errorStatus != "" {
|
||||||
} else {
|
httpStatus = http.StatusInternalServerError
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
ret.Error = errorStatus
|
ret.Error = errorStatus
|
||||||
}
|
}
|
||||||
if needle.HasName() {
|
if needle.HasName() {
|
||||||
ret.Name = string(needle.Name)
|
ret.Name = string(needle.Name)
|
||||||
}
|
}
|
||||||
ret.Size = size
|
ret.Size = size
|
||||||
writeJsonQuiet(w, r, ret)
|
writeJsonQuiet(w, r, httpStatus, ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vs *VolumeServer) DeleteHandler(w http.ResponseWriter, r *http.Request) {
|
func (vs *VolumeServer) DeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -280,7 +280,7 @@ func (vs *VolumeServer) DeleteHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
if ok != nil {
|
if ok != nil {
|
||||||
m := make(map[string]uint32)
|
m := make(map[string]uint32)
|
||||||
m["size"] = 0
|
m["size"] = 0
|
||||||
writeJsonQuiet(w, r, m)
|
writeJsonQuiet(w, r, http.StatusNotFound, m)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,14 +293,13 @@ func (vs *VolumeServer) DeleteHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
ret := topology.ReplicatedDelete(vs.masterNode, vs.store, volumeId, n, r)
|
ret := topology.ReplicatedDelete(vs.masterNode, vs.store, volumeId, n, r)
|
||||||
|
|
||||||
if ret != 0 {
|
if ret != 0 {
|
||||||
w.WriteHeader(http.StatusAccepted)
|
m := make(map[string]uint32)
|
||||||
|
m["size"] = uint32(count)
|
||||||
|
writeJsonQuiet(w, r, http.StatusAccepted, m)
|
||||||
} else {
|
} else {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
writeJsonError(w, r, http.StatusInternalServerError, errors.New("Deletion Failed."))
|
||||||
}
|
}
|
||||||
|
|
||||||
m := make(map[string]uint32)
|
|
||||||
m["size"] = uint32(count)
|
|
||||||
writeJsonQuiet(w, r, m)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Experts only: takes multiple fid parameters. This function does not propagate deletes to replicas.
|
//Experts only: takes multiple fid parameters. This function does not propagate deletes to replicas.
|
||||||
@@ -334,7 +333,5 @@ func (vs *VolumeServer) batchDeleteHandler(w http.ResponseWriter, r *http.Reques
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusAccepted)
|
writeJsonQuiet(w, r, http.StatusAccepted, ret)
|
||||||
|
|
||||||
writeJsonQuiet(w, r, ret)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,15 +13,15 @@ func (vs *VolumeServer) statusHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
m := make(map[string]interface{})
|
m := make(map[string]interface{})
|
||||||
m["Version"] = util.VERSION
|
m["Version"] = util.VERSION
|
||||||
m["Volumes"] = vs.store.Status()
|
m["Volumes"] = vs.store.Status()
|
||||||
writeJsonQuiet(w, r, m)
|
writeJsonQuiet(w, r, http.StatusOK, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vs *VolumeServer) assignVolumeHandler(w http.ResponseWriter, r *http.Request) {
|
func (vs *VolumeServer) assignVolumeHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
err := vs.store.AddVolume(r.FormValue("volume"), r.FormValue("collection"), r.FormValue("replication"), r.FormValue("ttl"))
|
err := vs.store.AddVolume(r.FormValue("volume"), r.FormValue("collection"), r.FormValue("replication"), r.FormValue("ttl"))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
writeJsonQuiet(w, r, map[string]string{"error": ""})
|
writeJsonQuiet(w, r, http.StatusAccepted, map[string]string{"error": ""})
|
||||||
} else {
|
} else {
|
||||||
writeJsonQuiet(w, r, map[string]string{"error": err.Error()})
|
writeJsonError(w, r, http.StatusNotAcceptable, err)
|
||||||
}
|
}
|
||||||
glog.V(2).Infoln("assign volume =", r.FormValue("volume"), ", collection =", r.FormValue("collection"), ", replication =", r.FormValue("replication"), ", error =", err)
|
glog.V(2).Infoln("assign volume =", r.FormValue("volume"), ", collection =", r.FormValue("collection"), ", replication =", r.FormValue("replication"), ", error =", err)
|
||||||
}
|
}
|
||||||
@@ -33,9 +33,9 @@ func (vs *VolumeServer) deleteCollectionHandler(w http.ResponseWriter, r *http.R
|
|||||||
}
|
}
|
||||||
err := vs.store.DeleteCollection(r.FormValue("collection"))
|
err := vs.store.DeleteCollection(r.FormValue("collection"))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
writeJsonQuiet(w, r, map[string]string{"error": ""})
|
writeJsonQuiet(w, r, http.StatusOK, map[string]string{"error": ""})
|
||||||
} else {
|
} else {
|
||||||
writeJsonQuiet(w, r, map[string]string{"error": err.Error()})
|
writeJsonError(w, r, http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
glog.V(2).Infoln("deleting collection =", r.FormValue("collection"), ", error =", err)
|
glog.V(2).Infoln("deleting collection =", r.FormValue("collection"), ", error =", err)
|
||||||
}
|
}
|
||||||
@@ -44,9 +44,9 @@ func (vs *VolumeServer) freezeVolumeHandler(w http.ResponseWriter, r *http.Reque
|
|||||||
//TODO: notify master that this volume will be read-only
|
//TODO: notify master that this volume will be read-only
|
||||||
err := vs.store.FreezeVolume(r.FormValue("volume"))
|
err := vs.store.FreezeVolume(r.FormValue("volume"))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
writeJsonQuiet(w, r, map[string]interface{}{"error": ""})
|
writeJsonQuiet(w, r, http.StatusOK, map[string]string{"error": ""})
|
||||||
} else {
|
} else {
|
||||||
writeJsonQuiet(w, r, map[string]string{"error": err.Error()})
|
writeJsonError(w, r, http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
glog.V(2).Infoln("freeze volume =", r.FormValue("volume"), ", error =", err)
|
glog.V(2).Infoln("freeze volume =", r.FormValue("volume"), ", error =", err)
|
||||||
}
|
}
|
||||||
@@ -61,5 +61,5 @@ func (vs *VolumeServer) statsDiskHandler(w http.ResponseWriter, r *http.Request)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
m["DiskStatues"] = ds
|
m["DiskStatues"] = ds
|
||||||
writeJsonQuiet(w, r, m)
|
writeJsonQuiet(w, r, http.StatusOK, m)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,27 +9,27 @@ import (
|
|||||||
func (vs *VolumeServer) vacuumVolumeCheckHandler(w http.ResponseWriter, r *http.Request) {
|
func (vs *VolumeServer) vacuumVolumeCheckHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
err, ret := vs.store.CheckCompactVolume(r.FormValue("volume"), r.FormValue("garbageThreshold"))
|
err, ret := vs.store.CheckCompactVolume(r.FormValue("volume"), r.FormValue("garbageThreshold"))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
writeJsonQuiet(w, r, map[string]interface{}{"error": "", "result": ret})
|
writeJsonQuiet(w, r, http.StatusOK, map[string]interface{}{"error": "", "result": ret})
|
||||||
} else {
|
} else {
|
||||||
writeJsonQuiet(w, r, map[string]interface{}{"error": err.Error(), "result": false})
|
writeJsonQuiet(w, r, http.StatusInternalServerError, map[string]interface{}{"error": err.Error(), "result": false})
|
||||||
}
|
}
|
||||||
glog.V(2).Infoln("checked compacting volume =", r.FormValue("volume"), "garbageThreshold =", r.FormValue("garbageThreshold"), "vacuum =", ret)
|
glog.V(2).Infoln("checked compacting volume =", r.FormValue("volume"), "garbageThreshold =", r.FormValue("garbageThreshold"), "vacuum =", ret)
|
||||||
}
|
}
|
||||||
func (vs *VolumeServer) vacuumVolumeCompactHandler(w http.ResponseWriter, r *http.Request) {
|
func (vs *VolumeServer) vacuumVolumeCompactHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
err := vs.store.CompactVolume(r.FormValue("volume"))
|
err := vs.store.CompactVolume(r.FormValue("volume"))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
writeJsonQuiet(w, r, map[string]string{"error": ""})
|
writeJsonQuiet(w, r, http.StatusOK, map[string]string{"error": ""})
|
||||||
} else {
|
} else {
|
||||||
writeJsonQuiet(w, r, map[string]string{"error": err.Error()})
|
writeJsonError(w, r, http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
glog.V(2).Infoln("compacted volume =", r.FormValue("volume"), ", error =", err)
|
glog.V(2).Infoln("compacted volume =", r.FormValue("volume"), ", error =", err)
|
||||||
}
|
}
|
||||||
func (vs *VolumeServer) vacuumVolumeCommitHandler(w http.ResponseWriter, r *http.Request) {
|
func (vs *VolumeServer) vacuumVolumeCommitHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
err := vs.store.CommitCompactVolume(r.FormValue("volume"))
|
err := vs.store.CommitCompactVolume(r.FormValue("volume"))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
writeJsonQuiet(w, r, map[string]interface{}{"error": ""})
|
writeJsonQuiet(w, r, http.StatusOK, map[string]string{"error": ""})
|
||||||
} else {
|
} else {
|
||||||
writeJsonQuiet(w, r, map[string]string{"error": err.Error()})
|
writeJsonError(w, r, http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
glog.V(2).Infoln("commit compact volume =", r.FormValue("volume"), ", error =", err)
|
glog.V(2).Infoln("commit compact volume =", r.FormValue("volume"), ", error =", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user