]> Cypherpunks repositories - gostls13.git/commitdiff
http: add PostForm function to post url-encoded key/value data.
authorAndrew Gerrand <adg@golang.org>
Thu, 2 Sep 2010 00:01:34 +0000 (10:01 +1000)
committerAndrew Gerrand <adg@golang.org>
Thu, 2 Sep 2010 00:01:34 +0000 (10:01 +1000)
This is a common task, so it makes sense to have a helper to do it.

(App Engine doesn't like "Transfer-Encoding: chunked" for POST
bodies, which is the default for regular Post.)

R=rsc
CC=golang-dev
https://golang.org/cl/2113041

src/pkg/http/client.go

index 50b6e530d9842b56efe4f20c368e45e31a0446d2..d77bf0e7594e5c40d193b81f28107f67740f52c9 100644 (file)
@@ -8,12 +8,14 @@ package http
 
 import (
        "bufio"
+       "bytes"
        "crypto/tls"
        "encoding/base64"
        "fmt"
        "io"
        "net"
        "os"
+       "strconv"
        "strings"
 )
 
@@ -161,6 +163,48 @@ func Post(url string, bodyType string, body io.Reader) (r *Response, err os.Erro
        return send(&req)
 }
 
+// PostForm issues a POST to the specified URL, 
+// with data's keys and values urlencoded as the request body.
+//
+// Caller should close r.Body when done reading it.
+func PostForm(url string, data map[string]string) (r *Response, err os.Error) {
+       var req Request
+       req.Method = "POST"
+       req.ProtoMajor = 1
+       req.ProtoMinor = 1
+       req.Close = true
+       body := urlencode(data)
+       req.Body = nopCloser{body}
+       req.Header = map[string]string{
+               "Content-Type":   "application/x-www-form-urlencoded",
+               "Content-Length": strconv.Itoa(body.Len()),
+       }
+       req.ContentLength = int64(body.Len())
+
+       req.URL, err = ParseURL(url)
+       if err != nil {
+               return nil, err
+       }
+
+       return send(&req)
+}
+
+func urlencode(data map[string]string) (b *bytes.Buffer) {
+       b = new(bytes.Buffer)
+       first := true
+       for k, v := range data {
+               if first {
+                       first = false
+               } else {
+                       b.WriteByte('&')
+               }
+               b.WriteString(URLEscape(k))
+               b.WriteByte('=')
+               b.WriteString(URLEscape(v))
+       }
+       return
+}
+
 // Head issues a HEAD to the specified URL.
 func Head(url string) (r *Response, err os.Error) {
        var req Request