/* * Copyright 2020 The Dragonfly Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package source import "net/textproto" const ( LastModified = "X-Dragonfly-Last-Modified" IfModifiedSince = "X-Dragonfly-If-Modified-Since" ETag = "X-Dragonfly-ETag" IfNoneMatch = "X-Dragonfly-If-None-Match" Range = "X-Dragonfly-Range" // startIndex-endIndex ) const LastModifiedLayout = "Mon, 02 Jan 2006 15:04:05 GMT" type ExpireInfo struct { LastModified string // Mon, 02 Jan 2006 15:04:05 GMT ETag string } // A Header represents the key-value pairs in a Dragonfly source header. // // The keys should be in canonical form, as returned by // CanonicalHeaderKey. type Header map[string][]string // Add adds the key, value pair to the header. // It appends to any existing values associated with key. // The key is case insensitive; it is canonicalized by // CanonicalHeaderKey. func (h Header) Add(key, value string) { textproto.MIMEHeader(h).Add(key, value) } // Set sets the header entries associated with key to the // single element value. It replaces any existing values // associated with key. The key is case insensitive; it is // canonicalized by textproto.CanonicalMIMEHeaderKey. // To use non-canonical keys, assign to the map directly. func (h Header) Set(key, value string) { textproto.MIMEHeader(h).Set(key, value) } // Get gets the first value associated with the given key. If // there are no values associated with the key, Get returns "". // It is case insensitive; textproto.CanonicalMIMEHeaderKey is // used to canonicalize the provided key. To use non-canonical keys, // access the map directly. func (h Header) Get(key string) string { return textproto.MIMEHeader(h).Get(key) } // Values returns all values associated with the given key. // It is case insensitive; textproto.CanonicalMIMEHeaderKey is // used to canonicalize the provided key. To use non-canonical // keys, access the map directly. // The returned slice is not a copy. func (h Header) Values(key string) []string { return textproto.MIMEHeader(h).Values(key) } // get is like Get, but key must already be in CanonicalHeaderKey form. func (h Header) get(key string) string { if v := h[key]; len(v) > 0 { return v[0] } return "" } // has reports whether h has the provided key defined, even if it's // set to 0-length slice. func (h Header) has(key string) bool { _, ok := h[key] return ok } // Del deletes the values associated with key. // The key is case insensitive; it is canonicalized by // CanonicalHeaderKey. func (h Header) Del(key string) { textproto.MIMEHeader(h).Del(key) } // Clone returns a copy of h or nil if h is nil. func (h Header) Clone() Header { if h == nil { return nil } // Find total number of values. nv := 0 for _, vv := range h { nv += len(vv) } sv := make([]string, nv) // shared backing array for headers' values h2 := make(Header, len(h)) for k, vv := range h { n := copy(sv, vv) h2[k] = sv[:n:n] sv = sv[n:] } return h2 } func CanonicalHeaderKey(s string) string { return textproto.CanonicalMIMEHeaderKey(s) }