yukari/contenttype/contenttype.go
alex 04ff44b7ef [enh] parse and filter Content-Type.
svg, mathml, multipart, xml (because of namespace) are forbidden.
the charset parameters in Content-Type is only set when it is by the original server.
the */xhtml+* Content-Type : the conversion to UTF-8 is now done (it wasn't the case before).
string type is used because of the mime package API.

git-svn-id: file:///srv/svn/repo/yukari/trunk@63 f3bd38d9-da89-464d-a02a-eb04e43141b5
2016-12-15 22:32:34 +00:00

99 lines
2.8 KiB
Go

package contenttype
import (
"mime"
"strings"
)
type ContentType struct {
TopLevelType string
SubType string
Suffix string
Parameters map[string]string
}
func (contenttype *ContentType) String() string {
var mimetype string
if contenttype.Suffix == "" {
if contenttype.SubType == "" {
mimetype = contenttype.TopLevelType
} else {
mimetype = contenttype.TopLevelType + "/" + contenttype.SubType
}
} else {
mimetype = contenttype.TopLevelType + "/" + contenttype.SubType + "+" + contenttype.Suffix
}
return mime.FormatMediaType(mimetype, contenttype.Parameters)
}
func (contenttype *ContentType) Equals(other ContentType) bool {
if contenttype.TopLevelType != other.TopLevelType ||
contenttype.SubType != other.SubType ||
contenttype.Suffix != other.Suffix ||
len(contenttype.Parameters) != len(other.Parameters) {
return false
}
for k, v := range contenttype.Parameters {
if other.Parameters[k] != v {
return false
}
}
return true
}
func (contenttype *ContentType) FilterParameters(parameters map[string]bool) {
for k, _ := range contenttype.Parameters {
if !parameters[k] {
delete(contenttype.Parameters, k)
}
}
}
func ParseContentType(contenttype string) (ContentType, error) {
mimetype, params, err := mime.ParseMediaType(contenttype)
if err != nil {
return ContentType{"", "", "", params}, err
}
splitted_mimetype := strings.SplitN(strings.ToLower(mimetype), "/", 2)
if len(splitted_mimetype) <= 1 {
return ContentType{splitted_mimetype[0], "", "", params}, nil
} else {
splitted_subtype := strings.SplitN(splitted_mimetype[1], "+", 2)
if len(splitted_subtype) == 1 {
return ContentType{splitted_mimetype[0], splitted_subtype[0], "", params}, nil
} else {
return ContentType{splitted_mimetype[0], splitted_subtype[0], splitted_subtype[1], params}, nil
}
}
}
type Filter func(contenttype ContentType) bool
func NewFilterContains(partialMimeType string) Filter {
return func(contenttype ContentType) bool {
return strings.Contains(contenttype.TopLevelType, partialMimeType) ||
strings.Contains(contenttype.SubType, partialMimeType) ||
strings.Contains(contenttype.Suffix, partialMimeType)
}
}
func NewFilterEquals(TopLevelType, SubType, Suffix string) Filter {
return func(contenttype ContentType) bool {
return ((TopLevelType != "*" && TopLevelType == contenttype.TopLevelType) || (TopLevelType == "*")) &&
((SubType != "*" && SubType == contenttype.SubType) || (SubType == "*")) &&
((Suffix != "*" && Suffix == contenttype.Suffix) || (Suffix == "*"))
}
}
func NewFilterOr(contentTypeFilterList []Filter) Filter {
return func(contenttype ContentType) bool {
for _, contentTypeFilter := range contentTypeFilterList {
if contentTypeFilter(contenttype) {
return true
}
}
return false
}
}