func (dir *Directory) createVolumeHandler(w http.ResponseWriter, r *http.Request) { // increase volumeID createVolCmd := &CreateVolCommand{ReplicateStr: r.FormValue("replication")} // fmt.Println("replication: ", createVolCmd.ReplicateStr) v, err := dir.raftServer.Do(createVolCmd) if err != nil { helper.WriteJson(w, createVolResult{Error: err.Error()}, http.StatusInternalServerError) return } volidip := v.(VolumeIDIP) for _, ip := range volidip.IP { var b bytes.Buffer bytes, err := json.Marshal(volidip) if err != nil { helper.WriteJson(w, createVolResult{Error: err.Error()}, http.StatusInternalServerError) return } b.Write(bytes) _, err = postAndError(fmt.Sprintf("http://%s/vol/create", ip), "application/json", &b) if err != nil { helper.WriteJson(w, createVolResult{Error: err.Error()}, http.StatusInternalServerError) return } } helper.WriteJson(w, volidip, http.StatusOK) }
func (dir *Directory) assignFileIDHandler(w http.ResponseWriter, r *http.Request) { u4 := uuid.NewV4() keyBytes := u4.Bytes() needleid := helper.BytesToUInt64(keyBytes[:8]) volIDIP, err := dir.pickVolume(r.FormValue("replication")) if err != nil { helper.WriteJson(w, assignFileIDResult{Error: err.Error()}, http.StatusInternalServerError) return } cookie := rand.Uint32() fid := fmt.Sprintf("%d,%d,%d", volIDIP.ID, needleid, cookie) a := assignFileIDResult{ FID: fid, VolIP: volIDIP.IP[rand.Intn(len(volIDIP.IP))], } helper.WriteJson(w, a, http.StatusOK) }
func (ss *StoreServer) uploadHandler(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() vars := mux.Vars(r) fileIDStr := vars["fileID"] volID, needleID, cookie, err := newFileID(fileIDStr) if err != nil { helper.WriteJson(w, result{Error: err.Error()}, http.StatusInternalServerError) return } if ss.volumeMap[volID] == nil { helper.WriteJson(w, result{Error: fmt.Sprintf("no volume %d", volID)}, http.StatusInternalServerError) return } data, name, err := parseUpload(r) if err != nil { helper.WriteJson(w, result{Error: err.Error()}, http.StatusInternalServerError) return } n := storage.NewNeedle(cookie, needleID, data, name) if err = ss.volumeMap[volID].AppendNeedle(n); err != nil { helper.WriteJson(w, result{Error: err.Error()}, http.StatusInternalServerError) return } fi, _ := ss.volumeMap[volID].StoreFile.Stat() vi := volumeInfo{ ID: volID, Size: fi.Size(), } viBytes, _ := json.Marshal(vi) for i := range ss.conf.Directories { // send volume information to directory server var b bytes.Buffer b.Write(viBytes) _, err := postAndError("http://"+ss.conf.Directories[i]+"/vol/info", "application/json", &b) if err == nil { break } else { log4go.Warn("send volumeInfo to directory get err: %s", err.Error()) } } for _, localVolIDIP := range ss.localVolIDIPs { if localVolIDIP.ID == volID { for _, ip := range localVolIDIP.IP { if ip != ss.Addr { if err = replicateUpload(fmt.Sprintf("http://%s/replicate/%s", ip, fileIDStr), string(name), data); err != nil { helper.WriteJson(w, result{Error: err.Error()}, http.StatusInternalServerError) return } } } break } } res := result{ Name: string(name), Size: len(data), } helper.WriteJson(w, res, http.StatusOK) }
func (ss *StoreServer) getFileHandler(w http.ResponseWriter, r *http.Request) { fileIDStr := mux.Vars(r)["fileID"] if li := strings.LastIndex(fileIDStr, "."); li != -1 { fileIDStr = fileIDStr[:li] } volID, needleID, cookie, err := newFileID(fileIDStr) if err != nil { helper.WriteJson(w, result{Error: err.Error()}, http.StatusInternalServerError) return } if ss.volumeMap[volID] == nil { helper.WriteJson(w, result{Error: fmt.Sprintf("no volume %d", volID)}, http.StatusInternalServerError) return } n, err := ss.volumeMap[volID].GetNeedle(needleID, cookie) if err != nil { helper.WriteJson(w, result{Error: err.Error()}, http.StatusInternalServerError) return } filename := string(n.Name) dotIndex := strings.LastIndex(filename, ".") contentType := "" if dotIndex > 0 { ext := filename[dotIndex:] contentType = mime.TypeByExtension(ext) } if contentType != "" { w.Header().Set("Content-Type", contentType) } // TODO: Add ETAG w.Header().Set("Content-Disposition", fmt.Sprintf("filename=\"%s\"", filename)) w.Header().Set("Content-Length", strconv.Itoa(len(n.Data))) _, err = w.Write(n.Data) if err != nil { log4go.Error(err.Error()) } }
func (dir *Directory) proxyToLeader(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { if dir.raftServer.Leader() == dir.raftServer.Name() { f(w, r) } else { targetURL, err := url.Parse(dir.raftServer.Leader()) if err != nil { helper.WriteJson(w, err.Error(), http.StatusInternalServerError) return } log4go.Info("proxying to raft leader: %s", dir.raftServer.Leader()) proxy := httputil.NewSingleHostReverseProxy(targetURL) proxy.Transport = transport proxy.ServeHTTP(w, r) } } }