77 lines
1.7 KiB
Go
77 lines
1.7 KiB
Go
|
package resolver
|
||
|
|
||
|
import (
|
||
|
"encoding/base64"
|
||
|
"fmt"
|
||
|
"net/url"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
type DataURL struct {
|
||
|
mimeType string
|
||
|
data string
|
||
|
isBase64 bool
|
||
|
}
|
||
|
|
||
|
func ParseDataURL(url string) (parsed DataURL, ok bool) {
|
||
|
if strings.HasPrefix(url, "data:") {
|
||
|
if comma := strings.IndexByte(url, ','); comma != -1 {
|
||
|
parsed.mimeType = url[len("data:"):comma]
|
||
|
parsed.data = url[comma+1:]
|
||
|
if strings.HasSuffix(parsed.mimeType, ";base64") {
|
||
|
parsed.mimeType = parsed.mimeType[:len(parsed.mimeType)-len(";base64")]
|
||
|
parsed.isBase64 = true
|
||
|
}
|
||
|
ok = true
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
type MIMEType uint8
|
||
|
|
||
|
const (
|
||
|
MIMETypeUnsupported MIMEType = iota
|
||
|
MIMETypeTextCSS
|
||
|
MIMETypeTextJavaScript
|
||
|
MIMETypeApplicationJSON
|
||
|
)
|
||
|
|
||
|
func (parsed DataURL) DecodeMIMEType() MIMEType {
|
||
|
// Remove things like ";charset=utf-8"
|
||
|
mimeType := parsed.mimeType
|
||
|
if semicolon := strings.IndexByte(mimeType, ';'); semicolon != -1 {
|
||
|
mimeType = mimeType[:semicolon]
|
||
|
}
|
||
|
|
||
|
// Hard-code a few supported types
|
||
|
switch mimeType {
|
||
|
case "text/css":
|
||
|
return MIMETypeTextCSS
|
||
|
case "text/javascript":
|
||
|
return MIMETypeTextJavaScript
|
||
|
case "application/json":
|
||
|
return MIMETypeApplicationJSON
|
||
|
default:
|
||
|
return MIMETypeUnsupported
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (parsed DataURL) DecodeData() (string, error) {
|
||
|
// Try to read base64 data
|
||
|
if parsed.isBase64 {
|
||
|
bytes, err := base64.StdEncoding.DecodeString(parsed.data)
|
||
|
if err != nil {
|
||
|
return "", fmt.Errorf("could not decode base64 data: %s", err.Error())
|
||
|
}
|
||
|
return string(bytes), nil
|
||
|
}
|
||
|
|
||
|
// Try to read percent-escaped data
|
||
|
content, err := url.PathUnescape(parsed.data)
|
||
|
if err != nil {
|
||
|
return "", fmt.Errorf("could not decode percent-escaped data: %s", err.Error())
|
||
|
}
|
||
|
return content, nil
|
||
|
}
|