Exemple #1
0
func main() {
	help := flag.Bool("help", false, "Show this help")
	file := flag.String("file", "", "A file to calculate the uuid for")
	base := flag.String("base", "cmbr://image/", "The base URI for the entity")
	port := flag.Int("port", 0, "A port to listen for image requests on")
	flag.Parse()

	if *help {
		flag.PrintDefaults()
		return
	}

	baseURL, err := url.Parse(*base)
	if err != nil {
		log.Fatalf("Could not parse the base URI %q: %s", *base, err)
	}

	var reader io.Reader

	if *file != "" {
		fileReader, err := os.Open(*file)
		if err != nil {
			log.Fatalf("Could not open the specified file %q for reading: %s", *file, err)
		}
		defer fileReader.Close()
		reader = fileReader
	}
	stat, _ := os.Stdin.Stat()
	if (stat.Mode() & os.ModeCharDevice) == 0 {
		reader = os.Stdin
	}

	if reader != nil {
		enc := json.NewEncoder(os.Stdout)
		res, err := getFileInfo(baseURL, reader)
		if err != nil {
			log.Fatalf("Failed to get file info: %s", err)
		}

		err = enc.Encode(res)
		if err != nil {
			log.Fatalf("Failed to encode result: %s", err)
		}
	}

	if *port != 0 {
		http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
			defer r.Body.Close()

			enc := json.NewEncoder(w)
			w.Header().Add("Content-type", "application/json")

			results := make(map[string]interface{})

			reader, err := r.MultipartReader()
			if err != nil {
				badRequest(w, err.Error())
				return
			}
			for {
				part, err := reader.NextPart()

				if err == io.EOF {
					break
				}
				if err != nil {
					badRequest(w, err.Error())
					return
				}

				if len(part.Header["Content-Disposition"]) == 0 {
					badRequest(w, "Missing Content-Disposition header in multipart part")
					return
				}
				_, params, err := mime.ParseMediaType(part.Header["Content-Disposition"][0])
				if err != nil {
					badRequest(w, "Failed to parse Content-Disposition %q", part.Header["Content-Disposition"][0])
					return
				}

				fieldName, ok := params["name"]
				if !ok {
					badRequest(w, "Missing Content-Disposition name in %q", part.Header["Content-Disposition"][0])
					return
				}

				res, err := getFileInfo(baseURL, part)
				if err != nil {
					results[fieldName] = map[string]interface{}{
						"error": err.Error(),
					}
					log.Printf("Failed to get file info: %s", err)
				} else {
					results[fieldName] = res
				}
			}

			w.WriteHeader(http.StatusOK)
			enc.Encode(results)
		})

		log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
	}
}
Exemple #2
0
// decodeBody parses body of a message, filling m.Body, m.HTML and m.Parts.
func (m *Message) decodeBody(r io.Reader, h textproto.MIMEHeader) error {
	cth := h.Get("Content-Type")
	if cth == "" {
		cth = "text/plain"
	}
	ct, ctp, err := mime.ParseMediaType(cth)
	if err != nil {
		return fmt.Errorf("invalid content-type: %q", cth)
	}

	// Find name.
	filename := ctp["name"]
	if filename == "" {
		cdh := h.Get("Content-Disposition")
		if cdh != "" {
			_, cdp, err := mime.ParseMediaType(cdh)
			if err != nil {
				return fmt.Errorf("invalid content-disposition: %q", cdh)
			}
			filename = cdp["filename"]

		}
	}

	// If it has filename, add as attachment.
	if filename != "" {
		name, err := decodeHeader(filename)
		if err != nil {
			return fmt.Errorf("decode filename: %v", err)
		}
		data, err := ioutil.ReadAll(decodeTransfer(r, h.Get("Content-Transfer-Encoding")))
		if err != nil {
			return fmt.Errorf("read attachment: %v", err)
		}

		m.Parts = append(m.Parts, Part{Name: name, Data: data})
		return nil
	}

	if ct == "text/plain" || ct == "text/html" {
		buf := new(bytes.Buffer)
		for {
			data, err := ioutil.ReadAll(decodeTransfer(r, h.Get("Content-Transfer-Encoding")))
			buf.Write(data)
			if err != nil {
				if _, ok := err.(base64.CorruptInputError); ok {
					continue
				}
				return fmt.Errorf("read body: %v", err)
			}
			break
		}

		body, err := decodeCharset(buf.String(), ctp["charset"])
		if err != nil {
			return fmt.Errorf("charsetDecode: %v", err)
		}

		if ct == "text/html" {
			m.HTML += body
			return nil
		}

		m.Body += body
		return nil
	}

	if strings.HasPrefix(ct, "multipart/") {
		r := multipart.NewReader(r, ctp["boundary"])
		for {
			p, err := r.NextPart()
			if err != nil {
				if err == io.EOF {
					break
				}
				return fmt.Errorf("next part: %q", err)
			}

			if err := m.decodeBody(p, p.Header); err != nil {
				p.Close() // p.Close is also called automatically by r.NextPart.
				return err
			}
		}
		return nil
	}

	// TODO: decide what to do with this.
	//return fmt.Errorf("content-type without filename: %q", ct)
	return nil
}