package main import ( "net/http" "sort" "strconv" "strings" ) type reverse struct { sort.Interface } func (r reverse) Less(i, j int) bool { return r.Interface.Less(j, i) } // ParseByQuality parses a field into the HTTP message to return the parameters // sorted by importance and others with a quality value of 0 (if any). // Returns nil if the field does not exist in the HTTP message. // // [HTTP spec](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html) // [Quality Values](http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.9) func ParseByQuality(r *http.Request, field string) (params, zero []string) { fieldValue := r.Header.Get(field) if fieldValue == "" { return } qParams := make(map[float64][]string) qSorted := make([]float64, 0) for _, f := range strings.Split(fieldValue, ",") { name := "" q := 1.0 // by default if strings.ContainsRune(f, ';') { name = strings.Split(f, ";")[0] name = strings.Trim(name, " ") q_ := strings.Split(f, "=")[1] q_ = strings.Trim(q_, " ") q, _ = strconv.ParseFloat(q_, 64) if q == 0 { // content not acceptable for the client zero = append(zero, name) continue } } else { name = strings.Trim(f, " ") } if _, ok := qParams[q]; !ok { qParams[q] = make([]string, 0) } qParams[q] = append(qParams[q], name) } // Sort the quality values. for k, _ := range qParams { qSorted = append(qSorted, k) } sort.Sort(reverse{sort.Float64Slice(qSorted)}) for _, v := range qSorted { params = append(params, qParams[v]...) } return }