2017-12-29 4 views
2

이동을 사용하여 서버에 다중 HTTP 요청을 작성하여 파일을 인증하고 업로드하는 유틸리티를 작성하려고합니다. 파일이 서버에 도착하지 않는 것을 제외하고는 모든 것이 정상적으로 처리됩니다. 더 자세히 살펴보면 요청의 멀티 파트가 비어있는 것 같습니다. 코드를 작성하고 아래 출력을 요청하십시오. Go 코드에서 누락 된 항목은 무엇입니까?이동 다중 HTTP 요청

코드가

: (나는 URL을 변경했습니다 ...)

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) 
    } 
} 

I 인쇄 우선 바이트 버퍼 다중 데이터를 포함, 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

오류를 무시하지 마십시오. – Flimzy

+0

오류를 확인하고이를 인쇄합니다. – dangeroushobo

답변

0

나는 서버가 실제로 아무것도받지 못했다고 생각합니다. nil의 몸을 가진 인쇄 된 몸의 동작이 예상하고 요청 본문, 당신은 모의 서버 또는 프록시를 사용해야하거나 폐기했다 디버깅 할 경우 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 

에 설명되어 있습니다.

또 다른 참고로, 코드의 로그인 시도가 작동하지 않습니다. 로그인 정보의 쿠키는 유지되지 않으므로 나중에 요청하면 쿠키 정보를 사용할 수 없습니다.