예제 #1
0
파일: upload.go 프로젝트: zxwing/zanker
func (u *Upload) monolithicUpload(w http.ResponseWriter, req *http.Request) {
	length := req.Header.Get(UPLOAD_HEADER_CONTENT_LENGTH)
	if length == "" {
		panic(fmt.Errorf("'%s' must be set in the header for a monolithic upload", UPLOAD_HEADER_CONTENT_LENGTH))
	}

	nlen, err := strconv.ParseInt(length, 10, 64)

	location := req.Header.Get(UPLOAD_HEADER_LOCATION)
	if location == "" {
		panic(fmt.Errorf("'%s' must be set in the header for a monolithic upload", UPLOAD_HEADER_LOCATION))
	}

	vars := mux.Vars(req)
	token, _ := vars["token"]
	digest := req.URL.Query().Get("digest")

	tmpFile := u.makeTempFilePath(location, token)
	if !lib.IsFile(tmpFile) {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "cannot find the temporary file at %s, have you started a upload yet?", tmpFile)
		return
	}

	f, err := os.OpenFile(tmpFile, os.O_WRONLY, 0666)
	if err != nil {
		panic(fmt.Errorf("cannot open the file[%s], %v", tmpFile, err))
	}

	deleteFile := func() {
		os.Remove(tmpFile)
	}

	n, err := io.Copy(f, req.Body)
	if err != nil {
		defer deleteFile()
		panic(fmt.Errorf("failed to write to %s, %v", tmpFile, err))
	}

	if n != nlen {
		defer deleteFile()
		panic(fmt.Errorf("the file size[%d] is not matching '%s'[%d]", n, UPLOAD_HEADER_CONTENT_LENGTH, nlen))
	}

	if err := os.Rename(tmpFile, location); err != nil {
		defer deleteFile()
		panic(fmt.Errorf("failed rename the file[%s] to %s, %v", tmpFile, location, err))
	}

	sum := lib.Md5(location)
	if sum != digest {
		defer deleteFile()
		panic(fmt.Errorf("corrupted file; expected MD5[%s] but got %s", digest, sum))
	}

	w.WriteHeader(http.StatusCreated)
}
예제 #2
0
파일: shell.go 프로젝트: zxwing/zanker
func (s *_shell) CheckFlags() error {
	if s.command == "" && s.file == "" && !s.stdin {
		return fmt.Errorf("please specify a shell command by '-c', a shell script file by '-f', or import a script by the '-stdin'")
	} else if s.command == "" && s.file != "" {
		if !LIB.IsFile(s.file) {
			return fmt.Errorf("the shell file[%s] not found or not a file\n", s.file)
		}
	}

	return nil
}
예제 #3
0
파일: upload.go 프로젝트: zxwing/zanker
func (u *Upload) CheckFlags() error {
	args := flag.Args()[1:]
	if len(args) != 2 {
		return fmt.Errorf("Wrong parameters. Usage: zanker upload absolute_path_to_src_file absolute_path_to_dst_file")
	}

	src := args[0]
	if !lib.IsFile(src) {
		return fmt.Errorf("%s is not found or not a file", src)
	}

	dst := args[1]
	if !path.IsAbs(dst) {
		return fmt.Errorf("%s is not an absolute path")
	}

	return nil
}
예제 #4
0
파일: upload.go 프로젝트: zxwing/zanker
func (u *Upload) start(w http.ResponseWriter, req *http.Request) {
	location := req.Header.Get(UPLOAD_HEADER_LOCATION)
	if location == "" {
		panic(fmt.Errorf("'%s' must be set in the header for starting a upload", UPLOAD_HEADER_LOCATION))
	} else if !path.IsAbs(location) {
		panic(fmt.Errorf("%s[%s] must be an absolute path", UPLOAD_HEADER_LOCATION, location))
	}

	digest := req.Header.Get(UPLOAD_HEADER_DIGEST)
	if digest == "" {
		panic(fmt.Errorf("'%s' must be set in the header for starting a upload", UPLOAD_HEADER_DIGEST))
	}

	if lib.IsFile(location) {
		if sum := lib.Md5(location); sum == digest {
			// for existing and same file, don't upload it
			w.WriteHeader(http.StatusNotModified)
			return
		}
	}

	if err := os.MkdirAll(path.Dir(location), os.ModeDir); err != nil {
		panic(fmt.Errorf("cannot create directory for the file[%s], %v", location, err))
	}

	token := lib.RandomString()
	tmpFile := u.makeTempFilePath(location, token)
	f, err := os.Create(tmpFile)
	if err != nil {
		panic(fmt.Errorf("cannot create the file[%s], %v", tmpFile, err))
	}
	f.Close()

	w.Header().Add(UPLOAD_HEADER_URL, Url(fmt.Sprintf("/upload/%s", token)).String())
	w.Header().Add(UPLOAD_HEADER_TOKEN, token)
	w.WriteHeader(http.StatusAccepted)
}