Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
4923ba91
Commit
4923ba91
authored
May 26, 2011
by
Brad Fitzpatrick
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mime/multipart: misc code/doc fixes
R=rsc CC=golang-dev
https://golang.org/cl/4532089
parent
0836b86e
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
34 additions
and
41 deletions
+34
-41
writer.go
src/pkg/mime/multipart/writer.go
+33
-40
writer_test.go
src/pkg/mime/multipart/writer_test.go
+1
-1
No files found.
src/pkg/mime/multipart/writer.go
View file @
4923ba91
...
...
@@ -6,24 +6,18 @@ package multipart
import
(
"bytes"
"crypto/rand"
"fmt"
"io"
"net/textproto"
"os"
"rand"
"strings"
)
//
Writer is used to generate
multipart messages.
//
A Writer generates
multipart messages.
type
Writer
struct
{
// Boundary is the random boundary string between
// parts. NewWriter will generate this but it must
// not be changed after a part has been created.
// Setting this to an invalid value will generate
// malformed messages.
Boundary
string
w
io
.
Writer
boundary
string
lastpart
*
part
}
...
...
@@ -32,38 +26,42 @@ type Writer struct {
func
NewWriter
(
w
io
.
Writer
)
*
Writer
{
return
&
Writer
{
w
:
w
,
B
oundary
:
randomBoundary
(),
b
oundary
:
randomBoundary
(),
}
}
// Boundary returns the Writer's randomly selected boundary string.
func
(
w
*
Writer
)
Boundary
()
string
{
return
w
.
boundary
}
// FormDataContentType returns the Content-Type for an HTTP
// multipart/form-data with this Writer's Boundary.
func
(
w
*
Writer
)
FormDataContentType
()
string
{
return
"multipart/form-data; boundary="
+
w
.
B
oundary
return
"multipart/form-data; boundary="
+
w
.
b
oundary
}
const
randChars
=
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
func
randomBoundary
()
string
{
var
buf
[
60
]
byte
for
i
:=
range
buf
{
buf
[
i
]
=
randChars
[
rand
.
Intn
(
len
(
randChars
))]
var
buf
[
30
]
byte
_
,
err
:=
io
.
ReadFull
(
rand
.
Reader
,
buf
[
:
])
if
err
!=
nil
{
panic
(
err
)
}
return
string
(
buf
[
:
])
return
fmt
.
Sprintf
(
"%x"
,
buf
[
:
])
}
// CreatePart creates a new multipart section with the provided
// header. The
previous part, if still open, is closed. The body of
//
the part should be written to the returned WriteCloser. Closing the
//
returned WriteCloser after writing is optional
.
func
(
w
*
Writer
)
CreatePart
(
header
textproto
.
MIMEHeader
)
(
io
.
Write
Close
r
,
os
.
Error
)
{
// header. The
body of the part should be written to the returned
//
Writer. After calling CreatePart, any previous part may no longer
//
be written to
.
func
(
w
*
Writer
)
CreatePart
(
header
textproto
.
MIMEHeader
)
(
io
.
Writer
,
os
.
Error
)
{
if
w
.
lastpart
!=
nil
{
if
err
:=
w
.
lastpart
.
C
lose
();
err
!=
nil
{
if
err
:=
w
.
lastpart
.
c
lose
();
err
!=
nil
{
return
nil
,
err
}
}
var
b
bytes
.
Buffer
fmt
.
Fprintf
(
&
b
,
"
\r\n
--%s
\r\n
"
,
w
.
B
oundary
)
fmt
.
Fprintf
(
&
b
,
"
\r\n
--%s
\r\n
"
,
w
.
b
oundary
)
// TODO(bradfitz): move this to textproto.MimeHeader.Write(w), have it sort
// and clean, like http.Header.Write(w) does.
for
k
,
vv
:=
range
header
{
...
...
@@ -91,7 +89,7 @@ func escapeQuotes(s string) string {
// CreateFormFile is a convenience wrapper around CreatePart. It creates
// a new form-data header with the provided field name and file name.
func
(
w
*
Writer
)
CreateFormFile
(
fieldname
,
filename
string
)
(
io
.
Write
Close
r
,
os
.
Error
)
{
func
(
w
*
Writer
)
CreateFormFile
(
fieldname
,
filename
string
)
(
io
.
Writer
,
os
.
Error
)
{
h
:=
make
(
textproto
.
MIMEHeader
)
h
.
Set
(
"Content-Disposition"
,
fmt
.
Sprintf
(
`form-data; name="%s"; filename="%s"`
,
...
...
@@ -100,40 +98,35 @@ func (w *Writer) CreateFormFile(fieldname, filename string) (io.WriteCloser, os.
return
w
.
CreatePart
(
h
)
}
// CreateFormField
is a convenience wrapper around CreatePart. It creates
//
a new form-data header with the provided
field name.
func
(
w
*
Writer
)
CreateFormField
(
fieldname
string
)
(
io
.
Write
Close
r
,
os
.
Error
)
{
// CreateFormField
calls calls CreatePart with a header using the
//
given
field name.
func
(
w
*
Writer
)
CreateFormField
(
fieldname
string
)
(
io
.
Writer
,
os
.
Error
)
{
h
:=
make
(
textproto
.
MIMEHeader
)
h
.
Set
(
"Content-Disposition"
,
fmt
.
Sprintf
(
`form-data; name="%s"`
,
escapeQuotes
(
fieldname
)))
return
w
.
CreatePart
(
h
)
}
// WriteField is a convenience wrapper around CreateFormField. It creates and
// writes a part with the provided name and value.
// WriteField calls CreateFormField and then writes the given value.
func
(
w
*
Writer
)
WriteField
(
fieldname
,
value
string
)
os
.
Error
{
p
,
err
:=
w
.
CreateFormField
(
fieldname
)
if
err
!=
nil
{
return
err
}
_
,
err
=
p
.
Write
([]
byte
(
value
))
if
err
!=
nil
{
return
err
}
return
p
.
Close
()
return
err
}
// Close finishes the multipart message. It closes the previous part,
// if still open, and writes the trailing boundary end line to the
// output.
// Close finishes the multipart message and writes the trailing
// boundary end line to the output.
func
(
w
*
Writer
)
Close
()
os
.
Error
{
if
w
.
lastpart
!=
nil
{
if
err
:=
w
.
lastpart
.
C
lose
();
err
!=
nil
{
if
err
:=
w
.
lastpart
.
c
lose
();
err
!=
nil
{
return
err
}
w
.
lastpart
=
nil
}
_
,
err
:=
fmt
.
Fprintf
(
w
.
w
,
"
\r\n
--%s--
\r\n
"
,
w
.
B
oundary
)
_
,
err
:=
fmt
.
Fprintf
(
w
.
w
,
"
\r\n
--%s--
\r\n
"
,
w
.
b
oundary
)
return
err
}
...
...
@@ -143,14 +136,14 @@ type part struct {
we
os
.
Error
// last error that occurred writing
}
func
(
p
*
part
)
C
lose
()
os
.
Error
{
func
(
p
*
part
)
c
lose
()
os
.
Error
{
p
.
closed
=
true
return
p
.
we
}
func
(
p
*
part
)
Write
(
d
[]
byte
)
(
n
int
,
err
os
.
Error
)
{
if
p
.
closed
{
return
0
,
os
.
NewError
(
"multipart:
Write after Close
"
)
return
0
,
os
.
NewError
(
"multipart:
can't write to finished part
"
)
}
n
,
err
=
p
.
mw
.
w
.
Write
(
d
)
if
err
!=
nil
{
...
...
src/pkg/mime/multipart/writer_test.go
View file @
4923ba91
...
...
@@ -32,7 +32,7 @@ func TestWriter(t *testing.T) {
}
}
r
:=
NewReader
(
&
b
,
w
.
Boundary
)
r
:=
NewReader
(
&
b
,
w
.
Boundary
()
)
part
,
err
:=
r
.
NextPart
()
if
err
!=
nil
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment