Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added files and image validation #29

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,86 @@ Basic usage example:
See godoc for more info.

<!-- import "github.com/teamwork/validate" -->

Basic usage example: Image Validation with different formats

func uploadFile(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(10 << 20)
file, fileHeader, err := r.FormFile("myFile")
if err != nil {
fmt.Println("Error Retrieving the File")
fmt.Println(err)
return
}
defer file.Close()
validator := validate.New()
validator.IsImage("myFile", fileHeader, "") OR
validator.IsImage("myFile", fileHeader, "jpeg") OR
validator.IsImage("myFile", fileHeader, "jpeg, png")
if validator.HasErrors() {
fmt.Fprintf(w, validator.String())
}
}

For Image Dimensions (Width and Heights)

func uploadFile(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(10 << 20)
file, fileHeader, err := r.FormFile("myFile")
if err != nil {
fmt.Println("Error Retrieving the File")
fmt.Println(err)
return
}
defer file.Close()
validator := validate.New()
minDim := validate.ImageDimension{Width: 200, Height: 300} //minimum dimension
maxDim := validate.ImageDimension{Width: 300, Height: 350} //maximum dimension
validator.ImageDimensions("myFile", fileHeader, &minDim, &maxDim, "")
if validator.HasErrors() {
fmt.Fprintf(w, validator.String())
}
}


You can also validate different file mime types.
For more information on mime types, visit:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types
https://www.iana.org/assignments/media-types/media-types.xhtml

File Mime type Validation:

func uploadFile(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(10 << 20)
file, fileHeader, err := r.FormFile("myFile")
if err != nil {
fmt.Println("Error Retrieving the File")
fmt.Println(err)
return
}
defer file.Close()
validator := validate.New()
validator.FileMimeType("myFile", fileHeader, "application/pdf", "")
if validator.HasErrors() {
fmt.Fprintf(w, validator.String())
}
}

For File Sizes in bytes:

func uploadFile(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(10 << 20)
file, fileHeader, err := r.FormFile("myFile")
if err != nil {
fmt.Println("Error Retrieving the File")
fmt.Println(err)
return
}
defer file.Close()
validator := validate.New()
validator.FileSize("myFile", fileHeader, 100000, 200000, "")
if validator.HasErrors() {
fmt.Fprintf(w, validator.String())
}
}
111 changes: 111 additions & 0 deletions files.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package validate

import (
"fmt"
"image"

//For image encoding
_ "image/gif"
_ "image/jpeg"
_ "image/png"
"math"
"mime/multipart"

"strings"
)

//Supported Image Formats/Mime Types
var (
supportedImageFormats = map[string]string{
"jpeg": "image/jpeg", "png": "image/png", "gif": "image/gif", "jpg": "image/jpeg",
}
)

//ImageDimension represents width and height of an image dimension in pixels
//This is required by image dimension validation
type ImageDimension struct {
Width int
Height int
}

//isFileImage confirms if this file is and Image of jpeg, png, gif
//format should be separated by comma
func isFileImage(uploadedType, format string) bool {

//Required format supplied
if format != "" {
//Check format is defined in supported format map
requiredFormat, ok := supportedImageFormats[format]

if ok && (strings.TrimSpace(requiredFormat) == uploadedType) {
return true
}
//Try splitting the required format in case of multiple formats
formatsArray := strings.Split(format, ",")
//Iterate through splitted formats
for _, val := range formatsArray {
requiredFormat, ok := supportedImageFormats[val]
if ok && (strings.TrimSpace(requiredFormat) == uploadedType) {
return true
}
}
//return false if not match is found
return false
}
//Check if the file is an image
for _, requiredFormat := range supportedImageFormats {

if requiredFormat == uploadedType {
return true
}
}

return false
}

//getDimensions returns the dimensions of the uploaded image
func getDimension(fileHeader *multipart.FileHeader) (*ImageDimension, error) {
file, err := fileHeader.Open()
if err != nil {
return nil, fmt.Errorf("Error getting image dimension." + err.Error())
}
//Reset File
_, err = file.Seek(0, 0)
if err != nil {
panic(err)
}
// buf := bufio.NewReader(file)

img, _, err := image.DecodeConfig(file)

if err != nil {
fmt.Println(err.Error(), file)
return nil, fmt.Errorf("Error getting image dimension." + err.Error())
}

return &ImageDimension{img.Width, img.Height}, nil
}

//isFileMimeTypeValid confirms if the supplied mime type matches that of the image
func isFileMimeTypeValid(uploadedMimeType, requiresMimeType string) bool {
//Split mimetype to individual values
mimeTypeArray := strings.Split(requiresMimeType, ",")
//Check for single value mimetype
if len(mimeTypeArray) == 0 && uploadedMimeType == strings.TrimSpace(requiresMimeType) {
return true
}

//Iterate through splitted types to determine if mimeType matches
for _, mimeType := range mimeTypeArray {
if strings.TrimSpace(mimeType) == uploadedMimeType {
return true
}
}
//return false on no match
return false
}

//Convert bytes to kilobytes
func bytesToKiloBytes(byteData int64) float64 {
return math.Ceil(float64(byteData) / 1024)
}
Loading