Commit 6193e0ba authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

mime/multipart: switch from map to MIMEHeader

R=rsc
CC=golang-dev
https://golang.org/cl/4253058
parent 99686ec7
...@@ -17,6 +17,7 @@ import ( ...@@ -17,6 +17,7 @@ import (
"bytes" "bytes"
"io" "io"
"mime" "mime"
"net/textproto"
"os" "os"
"regexp" "regexp"
"strings" "strings"
...@@ -40,7 +41,7 @@ type Part struct { ...@@ -40,7 +41,7 @@ type Part struct {
// The headers of the body, if any, with the keys canonicalized // The headers of the body, if any, with the keys canonicalized
// in the same fashion that the Go http.Request headers are. // in the same fashion that the Go http.Request headers are.
// i.e. "foo-bar" changes case to "Foo-Bar" // i.e. "foo-bar" changes case to "Foo-Bar"
Header map[string]string Header textproto.MIMEHeader
buffer *bytes.Buffer buffer *bytes.Buffer
mr *multiReader mr *multiReader
...@@ -51,8 +52,8 @@ type Part struct { ...@@ -51,8 +52,8 @@ type Part struct {
func (p *Part) FormName() string { func (p *Part) FormName() string {
// See http://tools.ietf.org/html/rfc2183 section 2 for EBNF // See http://tools.ietf.org/html/rfc2183 section 2 for EBNF
// of Content-Disposition value format. // of Content-Disposition value format.
v, ok := p.Header["Content-Disposition"] v := p.Header.Get("Content-Disposition")
if !ok { if v == "" {
return "" return ""
} }
d, params := mime.ParseMediaType(v) d, params := mime.ParseMediaType(v)
...@@ -85,7 +86,7 @@ var devNull = devNullWriter(false) ...@@ -85,7 +86,7 @@ var devNull = devNullWriter(false)
func newPart(mr *multiReader) (bp *Part, err os.Error) { func newPart(mr *multiReader) (bp *Part, err os.Error) {
bp = new(Part) bp = new(Part)
bp.Header = make(map[string]string) bp.Header = make(map[string][]string)
bp.mr = mr bp.mr = mr
bp.buffer = new(bytes.Buffer) bp.buffer = new(bytes.Buffer)
if err = bp.populateHeaders(); err != nil { if err = bp.populateHeaders(); err != nil {
...@@ -104,10 +105,7 @@ func (bp *Part) populateHeaders() os.Error { ...@@ -104,10 +105,7 @@ func (bp *Part) populateHeaders() os.Error {
return nil return nil
} }
if matches := headerRegexp.FindStringSubmatch(line); len(matches) == 3 { if matches := headerRegexp.FindStringSubmatch(line); len(matches) == 3 {
key := matches[1] bp.Header.Add(matches[1], matches[2])
value := matches[2]
// TODO: canonicalize headers ala http.Request.Header?
bp.Header[key] = value
continue continue
} }
return os.NewError("Unexpected header line found parsing multipart body") return os.NewError("Unexpected header line found parsing multipart body")
......
...@@ -58,7 +58,7 @@ func expectEq(t *testing.T, expected, actual, what string) { ...@@ -58,7 +58,7 @@ func expectEq(t *testing.T, expected, actual, what string) {
func TestFormName(t *testing.T) { func TestFormName(t *testing.T) {
p := new(Part) p := new(Part)
p.Header = make(map[string]string) p.Header = make(map[string][]string)
tests := [...][2]string{ tests := [...][2]string{
{`form-data; name="foo"`, "foo"}, {`form-data; name="foo"`, "foo"},
{` form-data ; name=foo`, "foo"}, {` form-data ; name=foo`, "foo"},
...@@ -69,7 +69,7 @@ func TestFormName(t *testing.T) { ...@@ -69,7 +69,7 @@ func TestFormName(t *testing.T) {
{` FORM-DATA ; filename="foo.txt"; name=foo; baz=quux`, "foo"}, {` FORM-DATA ; filename="foo.txt"; name=foo; baz=quux`, "foo"},
} }
for _, test := range tests { for _, test := range tests {
p.Header["Content-Disposition"] = test[0] p.Header.Set("Content-Disposition", test[0])
expected := test[1] expected := test[1]
actual := p.FormName() actual := p.FormName()
if actual != expected { if actual != expected {
...@@ -114,12 +114,15 @@ never read data ...@@ -114,12 +114,15 @@ never read data
t.Error("Expected part1") t.Error("Expected part1")
return return
} }
if part.Header["Header1"] != "value1" { if part.Header.Get("Header1") != "value1" {
t.Error("Expected Header1: value") t.Error("Expected Header1: value")
} }
if part.Header["foo-bar"] != "baz" { if part.Header.Get("foo-bar") != "baz" {
t.Error("Expected foo-bar: baz") t.Error("Expected foo-bar: baz")
} }
if part.Header.Get("Foo-Bar") != "baz" {
t.Error("Expected Foo-Bar: baz")
}
buf.Reset() buf.Reset()
io.Copy(buf, part) io.Copy(buf, part)
expectEq(t, "My value\r\nThe end.", expectEq(t, "My value\r\nThe end.",
...@@ -131,7 +134,7 @@ never read data ...@@ -131,7 +134,7 @@ never read data
t.Error("Expected part2") t.Error("Expected part2")
return return
} }
if part.Header["foo-bar"] != "bazb" { if part.Header.Get("foo-bar") != "bazb" {
t.Error("Expected foo-bar: bazb") t.Error("Expected foo-bar: bazb")
} }
buf.Reset() buf.Reset()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment