]> Cypherpunks repositories - gostls13.git/commitdiff
mime: media type formatter
authorPascal S. de Kloe <pascal@quies.net>
Fri, 26 Aug 2011 20:55:18 +0000 (16:55 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 26 Aug 2011 20:55:18 +0000 (16:55 -0400)
R=bradfitz, rsc
CC=golang-dev
https://golang.org/cl/4654069

src/pkg/mime/grammar.go
src/pkg/mime/mediatype.go

index 6e319ff8be80ae8e35bbff4de2c9026e7471b350..70a94cd807ffbf42a90b956078212854de3d8d92 100644 (file)
@@ -22,6 +22,15 @@ func IsTokenChar(rune int) bool {
        return rune > 0x20 && rune < 0x7f && !isTSpecial(rune)
 }
 
+// IsToken returns true if s is a 'token' as as defined by RFC 1521
+// and RFC 2045.
+func IsToken(s string) bool {
+       if s == "" {
+               return false
+       }
+       return strings.IndexFunc(s, isNotTokenChar) < 0
+}
+
 // IsQText returns true if rune is in 'qtext' as defined by RFC 822.
 func IsQText(rune int) bool {
        // CHAR        =  <any ASCII character>        ; (  0-177,  0.-127.)
index 9c25b9eff488f7fceb3c5acc8641780c58b6dfa6..35cac1345839e7519b8d87b93986099d941021d7 100644 (file)
@@ -12,6 +12,50 @@ import (
        "unicode"
 )
 
+// FormatMediaType serializes type t, subtype sub and the paramaters
+// param as a media type conform RFC 2045 and RFC 2616.
+// The type, subtype, and parameter names are written in lower-case.
+// When any of the arguments result in a standard violation then
+// FormatMediaType returns the empty string.
+func FormatMediaType(t, sub string, param map[string]string) string {
+       if !(IsToken(t) && IsToken(sub)) {
+               return ""
+       }
+       var buffer bytes.Buffer
+       buffer.WriteString(strings.ToLower(t))
+       buffer.WriteByte('/')
+       buffer.WriteString(strings.ToLower(sub))
+
+       for attribute, value := range param {
+               buffer.WriteByte(';')
+               if !IsToken(attribute) {
+                       return ""
+               }
+               buffer.WriteString(strings.ToLower(attribute))
+               buffer.WriteByte('=')
+               if IsToken(value) {
+                       buffer.WriteString(value)
+                       continue
+               }
+
+               buffer.WriteByte('"')
+               offset := 0
+               for index, character := range value {
+                       if character == '"' || character == '\r' {
+                               buffer.WriteString(value[offset:index])
+                               offset = index
+                               buffer.WriteByte('\\')
+                       }
+                       if character&0x80 != 0 {
+                               return ""
+                       }
+               }
+               buffer.WriteString(value[offset:])
+               buffer.WriteByte('"')
+       }
+       return buffer.String()
+}
+
 func checkMediaTypeDisposition(s string) os.Error {
        typ, rest := consumeToken(s)
        if typ == "" {