OSDN Git Service

Update to current version of Go library (revision 94d654be2064).
[pf3gnuchains/gcc-fork.git] / libgo / go / http / response.go
index a247261..3f919c8 100644 (file)
@@ -10,6 +10,7 @@ import (
        "bufio"
        "fmt"
        "io"
+       "net/textproto"
        "os"
        "sort"
        "strconv"
@@ -43,7 +44,7 @@ type Response struct {
        // omitted from Header.
        //
        // Keys in the map are canonicalized (see CanonicalHeaderKey).
-       Header map[string]string
+       Header Header
 
        // Body represents the response body.
        Body io.ReadCloser
@@ -66,7 +67,7 @@ type Response struct {
        // Trailer maps trailer keys to values.  Like for Header, if the
        // response has multiple trailer lines with the same key, they will be
        // concatenated, delimited by commas.
-       Trailer map[string]string
+       Trailer map[string][]string
 }
 
 // ReadResponse reads and returns an HTTP response from r.  The RequestMethod
@@ -76,13 +77,17 @@ type Response struct {
 // key/value pairs included in the response trailer.
 func ReadResponse(r *bufio.Reader, requestMethod string) (resp *Response, err os.Error) {
 
+       tp := textproto.NewReader(r)
        resp = new(Response)
 
        resp.RequestMethod = strings.ToUpper(requestMethod)
 
        // Parse the first line of the response.
-       line, err := readLine(r)
+       line, err := tp.ReadLine()
        if err != nil {
+               if err == os.EOF {
+                       err = io.ErrUnexpectedEOF
+               }
                return nil, err
        }
        f := strings.Split(line, " ", 3)
@@ -101,26 +106,16 @@ func ReadResponse(r *bufio.Reader, requestMethod string) (resp *Response, err os
 
        resp.Proto = f[0]
        var ok bool
-       if resp.ProtoMajor, resp.ProtoMinor, ok = parseHTTPVersion(resp.Proto); !ok {
+       if resp.ProtoMajor, resp.ProtoMinor, ok = ParseHTTPVersion(resp.Proto); !ok {
                return nil, &badStringError{"malformed HTTP version", resp.Proto}
        }
 
        // Parse the response headers.
-       nheader := 0
-       resp.Header = make(map[string]string)
-       for {
-               key, value, err := readKeyValue(r)
-               if err != nil {
-                       return nil, err
-               }
-               if key == "" {
-                       break // end of response header
-               }
-               if nheader++; nheader >= maxHeaderLines {
-                       return nil, ErrHeaderTooLong
-               }
-               resp.AddHeader(key, value)
+       mimeHeader, err := tp.ReadMIMEHeader()
+       if err != nil {
+               return nil, err
        }
+       resp.Header = Header(mimeHeader)
 
        fixPragmaCacheControl(resp.Header)
 
@@ -136,34 +131,14 @@ func ReadResponse(r *bufio.Reader, requestMethod string) (resp *Response, err os
 //     Pragma: no-cache
 // like
 //     Cache-Control: no-cache
-func fixPragmaCacheControl(header map[string]string) {
-       if header["Pragma"] == "no-cache" {
+func fixPragmaCacheControl(header Header) {
+       if hp, ok := header["Pragma"]; ok && len(hp) > 0 && hp[0] == "no-cache" {
                if _, presentcc := header["Cache-Control"]; !presentcc {
-                       header["Cache-Control"] = "no-cache"
+                       header["Cache-Control"] = []string{"no-cache"}
                }
        }
 }
 
-// AddHeader adds a value under the given key.  Keys are not case sensitive.
-func (r *Response) AddHeader(key, value string) {
-       key = CanonicalHeaderKey(key)
-
-       oldValues, oldValuesPresent := r.Header[key]
-       if oldValuesPresent {
-               r.Header[key] = oldValues + "," + value
-       } else {
-               r.Header[key] = value
-       }
-}
-
-// GetHeader returns the value of the response header with the given key.
-// If there were multiple headers with this key, their values are concatenated,
-// with a comma delimiter.  If there were no response headers with the given
-// key, GetHeader returns an empty string.  Keys are not case sensitive.
-func (r *Response) GetHeader(key string) (value string) {
-       return r.Header[CanonicalHeaderKey(key)]
-}
-
 // ProtoAtLeast returns whether the HTTP protocol used
 // in the response is at least major.minor.
 func (r *Response) ProtoAtLeast(major, minor int) bool {
@@ -231,20 +206,19 @@ func (resp *Response) Write(w io.Writer) os.Error {
        return nil
 }
 
-func writeSortedKeyValue(w io.Writer, kvm map[string]string, exclude map[string]bool) os.Error {
-       kva := make([]string, len(kvm))
-       i := 0
-       for k, v := range kvm {
+func writeSortedKeyValue(w io.Writer, kvm map[string][]string, exclude map[string]bool) os.Error {
+       keys := make([]string, 0, len(kvm))
+       for k := range kvm {
                if !exclude[k] {
-                       kva[i] = fmt.Sprint(k + ": " + v + "\r\n")
-                       i++
+                       keys = append(keys, k)
                }
        }
-       kva = kva[0:i]
-       sort.SortStrings(kva)
-       for _, l := range kva {
-               if _, err := io.WriteString(w, l); err != nil {
-                       return err
+       sort.SortStrings(keys)
+       for _, k := range keys {
+               for _, v := range kvm[k] {
+                       if _, err := fmt.Fprintf(w, "%s: %s\r\n", k, v); err != nil {
+                               return err
+                       }
                }
        }
        return nil