我尝试使用Go编写一个实用程序,通过向我们的服务器发出多部分http请求来验证和上传文件。一切似乎都没问题,除了文件没有到达服务器。进一步观察它看起来请求中的多部分是空的。代码和请求输出如下。我的Go代码中缺少什么?
守则:(我已更改网址...)
package main
import (
"net/http"
"mime/multipart"
"strings"
"fmt"
"io/ioutil"
"io"
"os"
"bytes"
"flag"
"encoding/json"
)
var (
filename = flag.String("filename", "", "file to upload")
name = flag.String("name", "", "name to give file on server")
username = flag.String("username", "", "username for authentication")
password = flag.String("password", "", "password for authentication")
)
func main() {
flag.Parse()
// Create multipart
var b bytes.Buffer
w := multipart.NewWriter(&b)
f, _ := os.Open(*filename) //open file to send
defer f.Close()
fw, err := w.CreateFormFile("file", *name) //give file a name
if err != nil {
fmt.Println(err)
}
if _, err := io.Copy(fw, f); err != nil { //copy the file to the multipart buffer
fmt.Println(err)
}
w.Close()
// print the head of the multipart data
bs := b.Bytes()
fmt.Printf("%+v\n\n", string(bs[:1000]))
// Send authentication/login
r, e := http.Post("https://mysite/login", "application/json", strings.NewReader(fmt.Sprintf("{\"username\":\"%s\",\"password\":\"%s\"}", *username, *password)))
if e != nil {
fmt.Println(e)
} else {
// Get the token from the body
type Body struct {
Token string
}
// convert json to get the token
body, _ := ioutil.ReadAll(r.Body)
bd := bytes.NewBuffer(body)
dec := json.NewDecoder(bd)
var m Body
dec.Decode(&m)
// Upload file
req, err := http.NewRequest("POST", "https://mysite/api/apps", &b)
if err != nil {
fmt.Printf("%v\n", err)
}
req.Header.Set("Authentication", fmt.Sprintf("Bearer: %s", m.Token))
req.Header.Set("Content-Type", w.FormDataContentType())
client := &http.Client{}
res, err := client.Do(req)
if err != nil {
fmt.Printf("%v\n", err)
}
// print status and request body
fmt.Println(res.Status)
fmt.Printf("%+v\n", res.Request)
}
}
我打印的第一件事是字节缓冲区b,它包含多部分数据,从这里看起来一切都很好。 (这是一个xml文件)
--83451b003d8e5cc38c0e8f60ad318e522cad4818cf293745c84ec36d26d5
Content-Disposition: form-data; name="file"; filename="snapshot-162224-820-99"
Content-Type: application/octet-stream
<manifest>
<projects>
<project name=........
接下来,我打印请求的状态。
200 OK
然后我打印出请求结构,这里是我看到MultipartForm为空的地方。
&{Method:GET URL:https://mysite/home/ Proto: ProtoMajor:0 ProtoMinor:0 Header:map[Authentication:[Bearer: DY0LCJL0g] Content-Type:[multipart/form-data; boundary=83451b003d8e5cc38c0e8f60ad318e522cad4818cf293745c84ec36d26d5] Referer:[http://mysite/home/]] Body:<nil> GetBody:<nil> ContentLength:0 TransferEncoding:[] Close:false Host: Form:map[] PostForm:map[] MultipartForm:<nil> Trailer:map[] RemoteAddr: RequestURI: TLS:<nil> Cancel:<nil> Response:0xc42018a360 ctx:<nil>}
答案 0 :(得分:0)
我非常怀疑服务器是否真的没有收到任何信息。预期具有零体的印刷体的行为并记录在http.Response
// Request is the request that was sent to obtain this Response.
// Request's Body is nil (having already been consumed).
// This is only populated for Client requests.
Request *Request
如果要调试发送的请求主体,则应使用模拟服务器或代理。
另一方面,您的代码尝试登录不起作用。它不维护登录信息的cookie,因此后来的请求无法使用它们。