func (s *Server) v1DataPut(w http.ResponseWriter, r *http.Request) { ctx := r.Context() vars := mux.Vars(r) var value interface{} if err := util.NewJSONDecoder(r.Body).Decode(&value); err != nil { handleError(w, 400, err) return } txn, err := s.store.NewTransaction(ctx) if err != nil { handleErrorAuto(w, err) return } defer s.store.Close(ctx, txn) path, ok := storage.ParsePath("/" + strings.Trim(vars["path"], "/")) if !ok { handleErrorf(w, 400, "bad path format %v", vars["path"]) return } _, err = s.store.Read(ctx, txn, path) if err != nil { if !storage.IsNotFound(err) { handleErrorAuto(w, err) return } if err := s.makeDir(ctx, txn, path[:len(path)-1]); err != nil { handleErrorAuto(w, err) return } } else if r.Header.Get("If-None-Match") == "*" { handleResponse(w, 304, nil) return } if err := s.store.Write(ctx, txn, storage.AddOp, path, value); err != nil { handleErrorAuto(w, err) return } handleResponse(w, 204, nil) }
func (s *Server) prepareV1PatchSlice(root string, ops []patchV1) (result []patchImpl, err error) { root = "/" + strings.Trim(root, "/") for _, op := range ops { impl := patchImpl{ value: op.Value, } // Map patch operation. switch op.Op { case "add": impl.op = storage.AddOp case "remove": impl.op = storage.RemoveOp case "replace": impl.op = storage.ReplaceOp default: return nil, badPatchOperationError(op.Op) } // Construct patch path. path := strings.Trim(op.Path, "/") if len(path) > 0 { path = root + "/" + path } else { path = root } var ok bool impl.path, ok = storage.ParsePath(path) if !ok { return nil, badPatchPathError(op.Path) } if err := s.writeConflict(impl.op, impl.path); err != nil { return nil, err } result = append(result, impl) } return result, nil }