add \r\n management instead of just \n + test the new behaviour
This commit is contained in:
parent
ff9ff23e5a
commit
8c02bc53a5
|
@ -16,13 +16,12 @@ func (comp *Component) parseHeaders(_raw []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. trim each line + remove 'Content-Disposition' prefix
|
// 2. trim each line + remove 'Content-Disposition' prefix
|
||||||
trimmed := strings.Trim(_lines[0], " \t")
|
header := strings.Trim(_lines[0], " \t\r")
|
||||||
header := trimmed
|
|
||||||
|
|
||||||
if !strings.HasPrefix(trimmed, "Content-Disposition: form-data;") {
|
if !strings.HasPrefix(header, "Content-Disposition: form-data;") {
|
||||||
return ErrNoHeader
|
return ErrNoHeader
|
||||||
}
|
}
|
||||||
header = strings.Trim(trimmed[len("Content-Disposition: form-data;"):], " \t")
|
header = strings.Trim(header[len("Content-Disposition: form-data;"):], " \t\r")
|
||||||
|
|
||||||
if len(header) < 1 {
|
if len(header) < 1 {
|
||||||
return ErrNoHeader
|
return ErrNoHeader
|
||||||
|
@ -53,7 +52,7 @@ func (comp *Component) parseHeaders(_raw []byte) error {
|
||||||
for _, l := range _lines[1:] {
|
for _, l := range _lines[1:] {
|
||||||
|
|
||||||
if strings.HasPrefix(l, "Content-Type: ") {
|
if strings.HasPrefix(l, "Content-Type: ") {
|
||||||
comp.ContentType = strings.Trim(l[len("Content-Type: "):], " \t")
|
comp.ContentType = strings.Trim(l[len("Content-Type: "):], " \t\r")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +88,9 @@ func (comp *Component) read(_reader *bufio.Reader, _boundary string) error {
|
||||||
// remove last CR (newline)
|
// remove last CR (newline)
|
||||||
if strings.HasSuffix(string(comp.Data), "\n") {
|
if strings.HasSuffix(string(comp.Data), "\n") {
|
||||||
comp.Data = comp.Data[0 : len(comp.Data)-1]
|
comp.Data = comp.Data[0 : len(comp.Data)-1]
|
||||||
} else if strings.HasSuffix(string(comp.Data), "\r\n") {
|
}
|
||||||
comp.Data = comp.Data[0 : len(comp.Data)-2]
|
if strings.HasSuffix(string(comp.Data), "\r") {
|
||||||
|
comp.Data = comp.Data[0 : len(comp.Data)-1]
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -101,8 +101,9 @@ func (comp *Component) read(_reader *bufio.Reader, _boundary string) error {
|
||||||
// remove last CR (newline)
|
// remove last CR (newline)
|
||||||
if strings.HasSuffix(string(comp.Data), "\n") {
|
if strings.HasSuffix(string(comp.Data), "\n") {
|
||||||
comp.Data = comp.Data[0 : len(comp.Data)-1]
|
comp.Data = comp.Data[0 : len(comp.Data)-1]
|
||||||
} else if strings.HasSuffix(string(comp.Data), "\r\n") {
|
}
|
||||||
comp.Data = comp.Data[0 : len(comp.Data)-2]
|
if strings.HasSuffix(string(comp.Data), "\r") {
|
||||||
|
comp.Data = comp.Data[0 : len(comp.Data)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
// io.EOF if last boundary
|
// io.EOF if last boundary
|
||||||
|
|
|
@ -9,7 +9,6 @@ func TestSimple(t *testing.T) {
|
||||||
test := struct {
|
test := struct {
|
||||||
Input []byte
|
Input []byte
|
||||||
Boundary string
|
Boundary string
|
||||||
Length int
|
|
||||||
}{
|
}{
|
||||||
Input: []byte(`--BoUnDaRy
|
Input: []byte(`--BoUnDaRy
|
||||||
Content-Disposition: form-data; name="somevar"
|
Content-Disposition: form-data; name="somevar"
|
||||||
|
@ -70,6 +69,87 @@ facebook.com
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSimpleWithCRLF(t *testing.T) {
|
||||||
|
|
||||||
|
type tcase struct {
|
||||||
|
Input []byte
|
||||||
|
Boundary string
|
||||||
|
}
|
||||||
|
_test := tcase{
|
||||||
|
Input: []byte(`--BoUnDaRy
|
||||||
|
Content-Disposition: form-data; name="somevar"
|
||||||
|
|
||||||
|
google.com
|
||||||
|
--BoUnDaRy
|
||||||
|
Content-Disposition: form-data; name="somefile"; filename="somefilename.pdf"
|
||||||
|
Content-Type: application/pdf
|
||||||
|
|
||||||
|
facebook.com
|
||||||
|
--BoUnDaRy--`),
|
||||||
|
Boundary: "BoUnDaRy",
|
||||||
|
}
|
||||||
|
|
||||||
|
test := tcase{
|
||||||
|
Input: make([]byte, 0),
|
||||||
|
Boundary: _test.Boundary,
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace all \n with \r\n
|
||||||
|
for _, char := range _test.Input {
|
||||||
|
if char == '\n' {
|
||||||
|
test.Input = append(test.Input, []byte("\r\n")...)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
test.Input = append(test.Input, char)
|
||||||
|
}
|
||||||
|
|
||||||
|
mpr, err := NewReader(bytes.NewReader(test.Input), test.Boundary)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unexpected error <%s>", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = mpr.Parse(); err != nil {
|
||||||
|
t.Fatalf("Unexpected error <%s>", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Check var
|
||||||
|
somevar := mpr.Get("somevar")
|
||||||
|
if somevar == nil {
|
||||||
|
t.Fatalf("Expected data {%s} to exist", "somevar")
|
||||||
|
}
|
||||||
|
if somevar.ContentType != "raw" {
|
||||||
|
t.Fatalf("Expected ContentType to be {raw}, got {%s}", somevar.ContentType)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(somevar.Data) != "google.com" {
|
||||||
|
t.Fatalf("Expected data to be {%s}, got {%s}", "google.com", somevar.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Check file
|
||||||
|
somefile := mpr.Get("somefile")
|
||||||
|
if somefile == nil {
|
||||||
|
t.Fatalf("Expected data {%s} to exist", "somefile")
|
||||||
|
}
|
||||||
|
if somefile.ContentType != "application/pdf" {
|
||||||
|
t.Fatalf("Expected ContentType to be {application/pdf}, got {%s}", somevar.ContentType)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(somefile.Data) != "facebook.com" {
|
||||||
|
t.Fatalf("Expected data to be {%s}, got {%s}", "facebook.com", somefile.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
filename := somefile.GetHeader("filename")
|
||||||
|
if len(filename) < 1 {
|
||||||
|
t.Fatalf("Expected data to have header 'filename'")
|
||||||
|
}
|
||||||
|
if filename != "somefilename.pdf" {
|
||||||
|
t.Fatalf("Expected filename to be {%s}, got {%s}", "somefilename.pdf", filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestNoName(t *testing.T) {
|
func TestNoName(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Input []byte
|
Input []byte
|
||||||
|
|
Loading…
Reference in New Issue