func getExportFilename(name, mimeType string) string { extensions, err := mime.ExtensionsByType(mimeType) if err != nil || len(extensions) == 0 { return name } return name + extensions[0] }
// TransferUrl 将外站图片URL转为本站,如果失败,返回原图 func (this *UploaderLogic) TransferUrl(ctx context.Context, origUrl string, prefixs ...string) (string, error) { if origUrl == "" || strings.Contains(origUrl, "studygolang") { return origUrl, errors.New("origin image is empty or is studygolang.com") } resp, err := http.Get(origUrl) if err != nil { return origUrl, errors.New("获取图片失败") } defer resp.Body.Close() buf, _ := ioutil.ReadAll(resp.Body) md5 := goutils.Md5Buf(buf) objImage, err := this.findImage(md5) if err != nil { logger.Errorln("find image:", md5, "error:", err) return origUrl, err } if objImage.Pid > 0 { return objImage.Path, nil } ext := filepath.Ext(origUrl) if ext == "" { contentType := http.DetectContentType(buf) exts, _ := mime.ExtensionsByType(contentType) if len(exts) > 0 { ext = exts[0] } } prefix := times.Format("ymd") if len(prefixs) > 0 { prefix = prefixs[0] } path := prefix + "/" + md5 + ext reader := bytes.NewReader(buf) if len(buf) > MaxImageSize { return origUrl, errors.New("文件太大") } err = this.uploadMemoryFile(reader, path) if err != nil { return origUrl, err } go this.saveImage(buf, path) return path, nil }
func mimetypes2net(u *url.URL, mimetypes []string) NetEntity { u, _ = u.Parse("") // dup u.Path = strings.TrimSuffix(u.Path, "/") locations := make([]*url.URL, len(mimetypes)) for i, mimetype := range mimetypes { u2, _ := u.Parse("") exts, _ := mime.ExtensionsByType(mimetype) if exts == nil || len(exts) == 0 { u2.Path += ".httpentity_mimetypes2net_no_extension_should_never_happen?" + mimetype } else { u2.Path += exts[0] } locations[i] = u2 } return NetLocations(locations) }
func (bingImageProcess) process(data []byte) (string, error) { var api imageResponse if err := json.Unmarshal(data, &api); err != nil { return "", err } if len(api.D.Results) == 0 { return "", errors.New("no results") } img := api.D.Results[0] client := new(http.Client) req, err := http.NewRequest("GET", img.MediaURL, nil) if err != nil { return "", err } resp, err := client.Do(req) if err != nil { return "", err } defer resp.Body.Close() name := uniuri.NewLen(10) extention, err := mime.ExtensionsByType(img.ContentType) if err != nil || len(extention) == 0 { name += ".png" // browser should pick up on it anyway } else { name += extention[0] } bucketName, bucketCfg := config.Get("BING_S3_BUCKET") awsRegion, regionCfg := config.Get("BING_S3_REGION") if !bucketCfg || !regionCfg { return "", errors.New("invalid bucket/region to upload") } url, err := util.UploadWithEnv(bucketName, awsRegion, name, img.ContentType, resp.Body) if err != nil { return "", err } return fmt.Sprintf("Image Result: %s", url), nil }
// MapPathToExtension returns the path with the proper extension that matches the given content type, // even if the resource (path) contains a different extension // Only works with Go 1.5+ //@@TODO should switch to a more comprehensive list of mime-to-ext (instead of using go's internal list) func MapPathToExtension(path string, ctype string) (string, error) { if len(path) == 0 { return "", errors.New("MapPathToExt -- missing path or ctype value") } if path[len(path)-1:] == "/" { return path, nil } fileCType, ext, _ := MimeLookup(path) if len(fileCType) > 0 { fileCType, _, _ = mime.ParseMediaType(fileCType) if len(ctype) > 0 { if fileCType != ctype { // append the extension corresponding to Content-Type header newExt, err := mime.ExtensionsByType(ctype) if err != nil { return "", err } if len(newExt) > 0 { ext = newExt[0] } path += "$" + ext } } } else { if len(ext) > 0 { if len(ctype) > 0 { newExt, err := mime.ExtensionsByType(ctype) if err != nil { return "", err } if len(newExt) > 0 { match := false for _, e := range newExt { if e == ext { match = true break } } if !match { // could not find matching extension if !IsRdfExtension(newExt[0]) { path += "$" + newExt[0] } } } } } else { // !fileCtype, !ext, ctype if len(ctype) > 0 { // maybe it's an RDF resource if ext = LookupExt(ctype); len(ext) > 0 { path += ext } else { newExt, err := mime.ExtensionsByType(ctype) if err != nil { return "", err } if len(newExt) > 0 { path += newExt[0] } } } else { return "", errors.New("Cannot infer mime type from from empty file") } } } return path, nil }
func UploadImageHandler(rw http.ResponseWriter, req *http.Request) { var ( uri string buf []byte err error reader io.Reader ) origUrl := req.FormValue("url") if origUrl != "" { resp, err := http.Get(origUrl) if err != nil { fmt.Fprint(rw, `{"ok": 0, "error":"获取图片失败"}`) return } defer resp.Body.Close() buf, err := ioutil.ReadAll(resp.Body) ext := filepath.Ext(origUrl) if ext == "" { contentType := http.DetectContentType(buf) exts, _ := mime.ExtensionsByType(contentType) if len(exts) > 0 { ext = exts[0] } } uri = util.DateNow() + "/" + util.Md5Buf(buf) + ext reader = bytes.NewReader(buf) } else { file, fileHeader, err := req.FormFile("img") if err != nil { fmt.Fprint(rw, `{"ok": 0, "error":"非法文件上传!"}`) return } defer file.Close() // 如果是临时文件,存在硬盘中,则是 *os.File(大于32M),直接报错 if _, ok := file.(*os.File); ok { fmt.Fprint(rw, `{"ok": 0, "error":"文件太大!"}`) return } reader = file buf, err := ioutil.ReadAll(file) imgDir := util.DateNow() if req.FormValue("avatar") != "" { imgDir = "avatar" } uri = imgDir + "/" + util.Md5Buf(buf) + filepath.Ext(fileHeader.Filename) } if err != nil { fmt.Fprint(rw, `{"ok": 0, "error":"文件读取失败!"}`) return } if len(buf) > maxImageSize { fmt.Fprint(rw, `{"ok": 0, "error":"文件太大!"}`) return } err = service.UploadMemoryFile(reader, uri) if err != nil { fmt.Fprint(rw, `{"ok": 0, "error":"文件上传失败!"}`) return } if origUrl != "" { uri = "http://studygolang.qiniudn.com/" + uri } fmt.Fprint(rw, `{"ok": 1, "uri":"`+uri+`"}`) }
func main() { server := os.Getenv("AMQP_URL") if server == "" { server = os.ExpandEnv("amqp://$AMQP_USER:[email protected]:5672") } timeout := 5 * time.Second clientID, _ := os.Hostname() queue := "scanner" mainCmd := &cobra.Command{ Use: "amqpc", } p := mainCmd.PersistentFlags() p.StringVarP(&server, "server", "S", server, "server address") p.DurationVarP(&timeout, "timeout", "", timeout, "timeout for commands") p.StringVarP(&clientID, "id", "", clientID, "client ID") p.StringVarP(&queue, "queue", "q", queue, "queue name to publish") appID := queue var noCompress bool pubCmd := &cobra.Command{ Use: "pub", Aliases: []string{"publish", "send", "write"}, Run: func(_ *cobra.Command, args []string) { c, err := newClient(server, queue) if err != nil { log.Fatal(err) } defer c.Close() if err = c.Confirm(false); err != nil { log.Fatal(err) } confirms := c.NotifyPublish(make(chan amqp.Confirmation, 1)) returns := c.NotifyReturn(make(chan amqp.Return, 1)) var sendCount int tbl := make(map[string]interface{}, 1) for _, arg := range args { for k := range tbl { delete(tbl, k) } var r io.ReadCloser mimeType, contentEncoding := "text/plain", "" if strings.HasPrefix(arg, "@") { arg = arg[1:] if arg == "-" { r = os.Stdin } else if fh, err := os.Open(arg); err != nil { log.Fatal(err) } else { if noCompress { r = fh } else { pr, pw := io.Pipe() go func() { defer fh.Close() gw := gzip.NewWriter(pw) if _, err := io.Copy(gw, fh); err != nil { pw.CloseWithError(err) return } pw.CloseWithError(gw.Close()) }() r = pr contentEncoding = "application/gzip" } tbl["FileName"] = arg if err := amqp.Table(tbl).Validate(); err != nil { log.Fatal(err) } mimeType = mime.TypeByExtension(filepath.Ext(arg)) } } else { r = ioutil.NopCloser(strings.NewReader(arg)) } b, err := ioutil.ReadAll(&io.LimitedReader{R: r, N: 256 << 20}) r.Close() if err != nil { log.Fatal(err) } if mimeType == "" { if mimeType = magic.MIMEType(b); mimeType == "" { mimeType = "application/octet-stream" } } if err := c.Publish("", c.Queue.Name, false, false, amqp.Publishing{ Headers: tbl, DeliveryMode: amqp.Persistent, ContentType: mimeType, ContentEncoding: contentEncoding, AppId: appID, Body: b, }, ); err != nil { log.Fatalf("Publish: %v", err) } log.Printf("Sent %q", arg) sendCount++ } Loop: for i := 0; i < sendCount; { select { case c, ok := <-confirms: if !ok { break Loop } if !c.Ack { log.Printf("couldn't deliver %d", c.DeliveryTag) } else { log.Printf("Delivered %d.", c.DeliveryTag) i++ } case r, ok := <-returns: if !ok { break Loop } log.Printf("RETURN: %#v", r) i++ } } }, } f := pubCmd.Flags() f.StringVarP(&appID, "app-id", "", appID, "appID") f.BoolVarP(&noCompress, "no-compress", "", noCompress, "disable file data compression (for slow devices)") var keepFiles bool subCmd := &cobra.Command{ Use: "sub", Aliases: []string{"subscribe", "recv", "receive", "read"}, Run: func(_ *cobra.Command, args []string) { c, err := newClient(server, queue) if err != nil { log.Fatal(err) } defer c.Close() d, err := c.Consume(c.Queue.Name, clientID, false, false, false, false, nil) if err != nil { log.Fatal(err) } tempDir, err := ioutil.TempDir("", "amqpc-") if err != nil { log.Fatal(err) } defer os.RemoveAll(tempDir) var i uint64 for msg := range d { i++ log.Printf("Received %s with %q from %s@%s.", msg.MessageId, msg.Headers, msg.UserId, msg.AppId) var fn string if fnI := msg.Headers["FileName"]; fnI != nil { if fn, _ = fnI.(string); fn != "" { fn = filepath.Base(fn) } } if fn == "" { var ext string if exts, err := mime.ExtensionsByType(msg.ContentType); err != nil { log.Printf("Extension for %q: %v", msg.ContentType) } else if len(ext) > 0 { ext = exts[0] } fn = fmt.Sprintf("%09d%s", i, ext) } fn = filepath.Join(tempDir, fn) err = receive(fn, msg, args) if !keepFiles { os.Remove(fn) } if err != nil { msg.Nack(false, true) log.Fatal(err) } if err := msg.Ack(false); err != nil { log.Printf("cannot ACK %q: %v", msg, err) } } }, } subCmd.Flags().BoolVarP(&keepFiles, "keep-files", "x", keepFiles, "keep temporary files") mainCmd.AddCommand(pubCmd, subCmd) mainCmd.Execute() }