Go中的XML HTTP Post

I'm attempting to create a post request that uses xml.

I know I need to use:

http.Post("myurl", "text/xml", body)

But the thing I can't figure out is how to set the actual XML data to be sent.

<request>
    <parameters>
        <email>test@test.com</email>
        <password>test</password>
    </parameters>
</request>

And setting a header to have Content-Type: text/xml

I am also new to Go, but I'd take a brave trial and try to answer this.

You can use http.Client with http.NewRequest, then set the request header before sending the POST, working sample like this:

package main

import (
    "bytes"
    "fmt"
    "net/http"
)

func main() {
    // or you can use []byte(`...`) and convert to Buffer later on
    body := "<request> <parameters> <email>test@test.com</email> <password>test</password> </parameters> </request>"

    client := &http.Client{}
    // build a new request, but not doing the POST yet
    req, err := http.NewRequest("POST", "http://localhost:8080/", bytes.NewBuffer([]byte(body)))
    if err != nil {
        fmt.Println(err)
    }
    // you can then set the Header here
    // I think the content-type should be "application/xml" like json...
    req.Header.Add("Content-Type", "application/xml; charset=utf-8")
    // now POST it
    resp, err := client.Do(req)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(resp)
}

Response from Client (dummy server so bad response of course):

>>> go run xmlpost.go
Post http://localhost:8080/: dial tcp 127.0.0.1:8080: connection refused
<nil>

Server Response:

>>> ncat -l 8080
POST / HTTP/1.1
Host: localhost:8080
User-Agent: Go 1.1 package http
Content-Length: 102
Content-Type: application/xml; charset=utf-8
Accept-Encoding: gzip

<request> <parameters> <email>test@test.com</email> <password>test</password> </parameters> </request>

update:

Thanks for @DaveC pointing out the unnecessary io.Reader(...), and apologized for using # for comment, I'm too used to Python and it came natural when adding comment in SO. Now fixed.

No need to make your own request or manually set the content type, it can all be done with a single simple http.Post call:

package main

import (
    "log"
    "net/http"
    "strings"
)

func main() {
    const myurl = "http://127.0.0.1:8080"
    const xmlbody = `
<request>
    <parameters>
        <email>test@test.com</email>
        <password>test</password>
    </parameters>
</request>`

    resp, err := http.Post(myurl, "text/xml", strings.NewReader(xmlbody))
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    // Do something with resp.Body
}

Whatever you use for the bodyType argument goes into the content type header. The server will see:

POST / HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: Go 1.1 package http
Content-Length: 127
Content-Type: text/xml
Accept-Encoding: gzip


<request>
    <parameters>
        <email>test@test.com</email>
        <password>test</password>
    </parameters>
</request>

(The extra blank line is because I chose to start the string literal on a new line).