//handle "POST /dir | body {name=/a/b/c&recursion=true}" 请求 func PostDir(w http.ResponseWriter, r *http.Request, serverConfig map[string]string) { name, recursion := r.FormValue("name"), r.FormValue("recursion") mylog.Info("post dir, {name = %s, recursion = %s}", name, recursion) if name == "" { panic(errors.New("POST /dir interface need 'name' param")) } if !(recursion == "true" || recursion == "false") { panic(errors.New("POST /dir interface need 'recursion' param, and the value must be 'true' or 'false'")) } storePath, _ := serverConfig["storePath"] absPath := storePath + "/" + strings.Trim(name, "/") mylog.Info("POST /dir make dir of absPath is %s", absPath) if recursion == "false" { err := os.Mkdir(absPath, 0777) check(err) } else if recursion == "true" { err := os.MkdirAll(absPath, 0777) check(err) } }
//os.FileInfo 转换为 FileInfo,并递归下级目录 func listR(absPath string, prefixToDel string) []FileInfo { fileInfos, err := ioutil.ReadDir(absPath) if err != nil { panic(err) } resultList := []FileInfo{} for _, v := range fileInfos { //resultList[k] = FileInfo{v.Name(), v.Size(), v.ModTime().Format("2006/01/02 15:04:05.000000000 MST 2006"), v.IsDir(), v.Mode()} mylog.Info("%v", v) p := (absPath + "/" + strings.Trim(v.Name(), "/"))[len(prefixToDel):] resultList = append(resultList, FileInfo{p, v.Size(), v.ModTime().Format("2006/01/02 15:04:05.000"), v.IsDir(), v.Mode()}) if v.IsDir() { childPath := absPath + "/" + v.Name() childResultList := listR(childPath, prefixToDel) for _, cv := range childResultList { resultList = append(resultList, cv) } } } return resultList }
//Get /file?name=/a/b/c/file func GetFile(w http.ResponseWriter, r *http.Request, serverConfig map[string]string) { name := r.FormValue("name") if name == "" { return } absPath := strings.TrimRight(serverConfig["storePath"], "/") + "/" + strings.Trim(name, "/") mylog.Info("Get file, absPath = %s", absPath) if strings.HasSuffix(absPath, ".jpg") || strings.HasSuffix(absPath, ".png") || strings.HasSuffix(absPath, ".jpeg") || strings.HasSuffix(absPath, ".JPG") || strings.HasSuffix(absPath, ".JPEG") || strings.HasSuffix(absPath, ".PNG") { w.Header().Add("Content-Type", "image/png") } else { w.Header().Add("Content-Type", "application/octet-stream") w.Header().Add("Content-Disposition", "attachment;filename="+name[strings.LastIndex(name, "/")+1:]) } fi, err := os.Open(absPath) if err != nil { panic(err) } defer func() { if fi.Close() != nil { panic(err) } }() reader := bufio.NewReader(fi) io.Copy(w, reader) }
func ParseRequest(r *http.Request) (s, c string, err error) { h, ok := r.Header["Authorization"] mylog.Info("%v", h) if !ok || len(h) == 0 { return "", "", errors.New("The authorization header is not set.") } s, c, err = Parse(h[0]) return }
//查询目录 func GetDir(w http.ResponseWriter, r *http.Request, serverConfig map[string]string) { name, recursion, mode := r.FormValue("name"), r.FormValue("recursion"), r.FormValue("modeÓ") mylog.Info("post dir, {name = %s, recursion = %s}", name, recursion) if name == "" { panic(errors.New("GET /dir interface need 'name' param")) } if !(recursion == "true" || recursion == "false") { panic(errors.New("GET /dir interface need 'recursion' param, and the value must be 'true' or 'false'")) } storePath, _ := serverConfig["storePath"] absPath := storePath + "/" + strings.Trim(name, "/") absPath = strings.TrimRight(absPath, "/") mylog.Info("GET /dir list dir of absPath is %s", absPath) //resultList := make([]FileInfo, len(fileInfos)) var resultList []FileInfo //os.FileInfo 转换为 FileInfo if recursion == "false" { resultList = list(absPath, storePath) } else { resultList = listR(absPath, storePath) } data, err := json.Marshal(resultList) if err != nil { panic(err) } w.Header()["Content-Type"] = []string{"application/json; charset=UTF-8"} w.WriteHeader(200) w.Write(data) fmt.Println(mode) }
// GET /pic/width-height?name=/a/b/c.jpg func GetPicWidthHeight(w http.ResponseWriter, r *http.Request, serverConfig map[string]string) { name := r.FormValue("name") mylog.Info("get pic width/height, {name = %s}", name) if name == "" { panic(errors.New("POST /dir interface need 'name' param")) } storePath, _ := serverConfig["storePath"] absPath := storePath + "/" + strings.Trim(name, "/") f, err := os.Open(absPath) if err != nil { panic(err) } defer f.Close() im, _, err := image.DecodeConfig(f) if err != nil { panic(err) } wh := WH{im.Width, im.Height} data, err := json.Marshal(wh) if err != nil { panic(err) } w.Header()["Content-Type"] = []string{"application/json; charset=UTF-8"} w.WriteHeader(200) w.Write(data) mylog.Info("%s width-height = %v", name, wh) }
//上传文件 //Post /file body: file, dir=/a/b/c func PostFile(w http.ResponseWriter, r *http.Request, serverConfig map[string]string) { file, header, err := r.FormFile("file") if err != nil { panic("POST /file must have a file field named file") } defer file.Close() dir := r.FormValue("dir") if dir == "" { panic("POST /file must have a dir field named dir to set the save path") } dir = strings.TrimRight(serverConfig["storePath"], "/") + "/" + strings.Trim(dir, "/") f := &File{dir, header.Filename, file} mylog.Info("%v", *f) f.save() fmt.Fprintf(w, "%s", "file uploaded") }
func (f *File) save() { absPath := strings.TrimRight(f.Dir, "/") absPath = absPath + "/" + f.Name file, err := os.Open(absPath) if err != nil { file, err = os.Create(absPath) } else { panic(errors.New(absPath + " has existed")) } if err != nil { panic(err) } defer file.Close() io.Copy(file, f.FormFile) mylog.Info("上传文件 %s", absPath) }
//调整图片分辨率,生成新的分辨率的图片文件 // PUT /pic/width-height , body : {name=/a.jpg&width=40&height=30} // 生成文件: /a.jpg.40.30.jpg 如果该文件已经存在,则直接返回 func TuningPicWH(w http.ResponseWriter, r *http.Request, serverConfig map[string]string) { name, sWidth, sHeight := r.FormValue("name"), r.FormValue("width"), r.FormValue("height") mylog.Info("put /pic/width-height, {name = %s}", name) if name == "" { panic(errors.New("Put /pic/width-height interface need 'name' param")) } if sWidth == "" { panic(errors.New("Put /pic/width-height interface need 'width' param")) } if sHeight == "" { panic(errors.New("Put /pic/width-height interface need 'height' param")) } width, err := strconv.ParseInt(sWidth, 10, 0) if err != nil { panic(err) } height, err := strconv.ParseInt(sHeight, 10, 0) if err != nil { panic(err) } storePath, _ := serverConfig["storePath"] absPath := storePath + "/" + strings.Trim(name, "/") sufix := getSufix(name) tunedAbsPath := absPath + "." + sWidth + "." + sHeight + "." + sufix _, err = os.Open(tunedAbsPath) if err != nil { //文件不存在,进行调整,生成新的文件 inFile, err := os.Open(absPath) if err != nil { panic(err) } defer inFile.Close() img, _, err := image.Decode(inFile) if err != nil { panic(err) } newImg := resize.Resample(img, image.Rect(0, 0, img.Bounds().Max.X, img.Bounds().Max.Y), int(width), int(height)) outFile, err := os.Create(tunedAbsPath) if err != nil { panic(err) } defer outFile.Close() if sufix == "jpg" || sufix == "jpeg" || sufix == "JPG" || sufix == "JPEG" { err = jpeg.Encode(outFile, newImg, &jpeg.Options{100}) if err != nil { panic(err) } } else if sufix == "png" || sufix == "PNG" { err = png.Encode(outFile, newImg) if err != nil { panic(err) } } } }
func notAuth(w http.ResponseWriter, r *http.Request) { mylog.Info("%s", "NotAuth response") w.Header().Set("WWW-Authenticate", `Basic realm="iDongler User Login"`) w.WriteHeader(http.StatusUnauthorized) }