func TestMultipartMIME(t *testing.T) { var mime bytes.Buffer writer := multipart.NewWriter(&mime) if err := multipartMIME(writer, msgs.Message1, nil); err != nil { t.Fatal(err) } if err := writer.Close(); err != nil { t.Fatal(err) } mime.Reset() writer = multipart.NewWriter(&mime) err := multipartMIME(writer, msgs.Message1, []*Attachment{ { Filename: "message.txt", Reader: bytes.NewBufferString(msgs.Message2), ContentType: "application/octet-stream", }, }) if err != nil { t.Fatal(err) } if err := writer.Close(); err != nil { t.Fatal(err) } }
func TestUntypedFileUpload(t *testing.T) { binder := paramsForFileUpload() body := bytes.NewBuffer(nil) writer := multipart.NewWriter(body) part, err := writer.CreateFormFile("file", "plain-jane.txt") assert.NoError(t, err) part.Write([]byte("the file contents")) writer.WriteField("name", "the-name") assert.NoError(t, writer.Close()) urlStr := "http://localhost:8002/hello" req, _ := http.NewRequest("POST", urlStr, body) req.Header.Set("Content-Type", writer.FormDataContentType()) data := make(map[string]interface{}) assert.NoError(t, binder.Bind(req, nil, httpkit.JSONConsumer(), &data)) assert.Equal(t, "the-name", data["name"]) assert.NotNil(t, data["file"]) assert.IsType(t, httpkit.File{}, data["file"]) file := data["file"].(httpkit.File) assert.NotNil(t, file.Header) assert.Equal(t, "plain-jane.txt", file.Header.Filename) bb, err := ioutil.ReadAll(file.Data) assert.NoError(t, err) assert.Equal(t, []byte("the file contents"), bb) req, _ = http.NewRequest("POST", urlStr, body) req.Header.Set("Content-Type", "application/json") data = make(map[string]interface{}) assert.Error(t, binder.Bind(req, nil, httpkit.JSONConsumer(), &data)) req, _ = http.NewRequest("POST", urlStr, body) req.Header.Set("Content-Type", "application(") data = make(map[string]interface{}) assert.Error(t, binder.Bind(req, nil, httpkit.JSONConsumer(), &data)) body = bytes.NewBuffer(nil) writer = multipart.NewWriter(body) part, err = writer.CreateFormFile("bad-name", "plain-jane.txt") assert.NoError(t, err) part.Write([]byte("the file contents")) writer.WriteField("name", "the-name") assert.NoError(t, writer.Close()) req, _ = http.NewRequest("POST", urlStr, body) req.Header.Set("Content-Type", writer.FormDataContentType()) data = make(map[string]interface{}) assert.Error(t, binder.Bind(req, nil, httpkit.JSONConsumer(), &data)) req, _ = http.NewRequest("POST", urlStr, body) req.Header.Set("Content-Type", writer.FormDataContentType()) req.MultipartReader() data = make(map[string]interface{}) assert.Error(t, binder.Bind(req, nil, httpkit.JSONConsumer(), &data)) }
// ConditionallyIncludeMedia does nothing if media is nil. // // bodyp is an in/out parameter. It should initially point to the // reader of the application/json (or whatever) payload to send in the // API request. It's updated to point to the multipart body reader. // // ctypep is an in/out parameter. It should initially point to the // content type of the bodyp, usually "application/json". It's updated // to the "multipart/related" content type, with random boundary. // // The return value is the content-length of the entire multpart body. func ConditionallyIncludeMedia(media io.Reader, bodyp *io.Reader, ctypep *string) (totalContentLength int64, ok bool) { if media == nil { return } // Get the media type and size. The type check might return a // different reader instance, so do the size check first, // which looks at the specific type of the io.Reader. var mediaType string if typer, ok := media.(ContentTyper); ok { mediaType = typer.ContentType() } media, mediaSize := getReaderSize(media) if mediaType == "" { media, mediaType = getMediaType(media) } body, bodyType := *bodyp, *ctypep body, bodySize := getReaderSize(body) // Calculate how big the the multipart will be. { totalContentLength = bodySize + mediaSize mpw := multipart.NewWriter(countingWriter{&totalContentLength}) mpw.CreatePart(typeHeader(bodyType)) mpw.CreatePart(typeHeader(mediaType)) mpw.Close() } pr, pw := io.Pipe() mpw := multipart.NewWriter(pw) *bodyp = pr *ctypep = "multipart/related; boundary=" + mpw.Boundary() go func() { defer pw.Close() defer mpw.Close() w, err := mpw.CreatePart(typeHeader(bodyType)) if err != nil { return } _, err = io.Copy(w, body) if err != nil { return } w, err = mpw.CreatePart(typeHeader(mediaType)) if err != nil { return } _, err = io.Copy(w, media) if err != nil { return } }() return totalContentLength, true }
// Bytes converts the Email object to a []byte representation, including all needed MIMEHeaders, boundaries, etc. func (m *Message) Bytes() ([]byte, error) { // TODO: better guess buffer size buff := bytes.NewBuffer(make([]byte, 0, 4096)) headers := m.msgHeaders() w := multipart.NewWriter(buff) // TODO: determine the content type based on message/attachment mix. headers.Set("Content-Type", "multipart/mixed;\r\n boundary="+w.Boundary()) headerToBytes(buff, headers) io.WriteString(buff, "\r\n") // Start the multipart/mixed part fmt.Fprintf(buff, "--%s\r\n", w.Boundary()) header := textproto.MIMEHeader{} // Check to see if there is a Text or HTML field if len(m.Content) > 0 { subWriter := multipart.NewWriter(buff) // Create the multipart alternative part header.Set("Content-Type", fmt.Sprintf("multipart/alternative;\r\n boundary=%s\r\n", subWriter.Boundary())) // Write the header headerToBytes(buff, header) // Create the body sections if len(m.Content) > 0 { header.Set("Content-Type", fmt.Sprintf("%s; charset=UTF-8", m.ContentType)) header.Set("Content-Transfer-Encoding", "quoted-printable") if _, err := subWriter.CreatePart(header); err != nil { return nil, err } // Write the text if err := quotePrintEncode(buff, []byte(m.Content)); err != nil { return nil, err } } if err := subWriter.Close(); err != nil { return nil, err } } // Create attachment part, if necessary for _, a := range m.Attachments { ap, err := w.CreatePart(a.Header) if err != nil { return nil, err } // Write the base64Wrapped content to the part base64Wrap(ap, a.Content) } if err := w.Close(); err != nil { return nil, err } return buff.Bytes(), nil }
func NewFileUploadRequest(uri string, params map[string]string, paramName, path string) (*http.Request, error) { file, err := os.Open(path) if err != nil { return nil, err } defer file.Close() body := &bytes.Buffer{} writer := multipart.NewWriter(body) part, err := writer.CreateFormFile(paramName, filepath.Base(path)) if err != nil { return nil, err } _, err = io.Copy(part, file) for key, val := range params { _ = writer.WriteField(key, val) } writer.WriteField("type", "video/mp4") err = writer.Close() if err != nil { return nil, err } req, err := http.NewRequest("POST", uri, body) if err == nil { req.Header.Add("Content-Type", writer.FormDataContentType()) } return req, err }
// Streams upload directly from file -> mime/multipart -> pipe -> http-request func streamingUploadFile(params map[string]string, paramName, path string, w *io.PipeWriter, file *os.File) { defer file.Close() defer w.Close() writer := multipart.NewWriter(w) part, err := writer.CreateFormFile(paramName, filepath.Base(path)) if err != nil { log.Fatal(err) return } _, err = io.Copy(part, file) if err != nil { log.Fatal(err) return } for key, val := range params { _ = writer.WriteField(key, val) } err = writer.Close() if err != nil { log.Fatal(err) return } }
func buildFormFileReq(t *testing.T, tc *fileTestCase) *http.Request { var b bytes.Buffer w := multipart.NewWriter(&b) w.WriteField("title", tc.title) for _, doc := range tc.documents { fw, err := w.CreateFormFile("document", doc.fileName) if err != nil { t.Error(err) } fw.Write([]byte(doc.data)) } err := w.Close() if err != nil { t.Error(err) } req, err := http.NewRequest("POST", filepath, &b) if err != nil { t.Error(err) } req.Header.Set("Content-Type", w.FormDataContentType()) return req }
func NewMultipartWriter() *MultipartWriter { buf := &bytes.Buffer{} return &MultipartWriter{ Buffer: buf, Writer: multipart.NewWriter(buf), } }
// The getHandler function handles the GET endpoint for the artifact path. // It calls the RetrieveArtifact function, and then either returns the found artifact, or logs the error // returned by RetrieveArtifact. func (s *httpServer) getHandler(w http.ResponseWriter, r *http.Request) { log.Debug("GET %s", r.URL.Path) artifactPath := strings.TrimPrefix(r.URL.Path, "/artifact/") art, err := s.cache.RetrieveArtifact(artifactPath) if err != nil && os.IsNotExist(err) { w.WriteHeader(http.StatusNotFound) log.Debug("%s doesn't exist in http cache", artifactPath) return } else if err != nil { log.Errorf("Failed to retrieve artifact %s: %s", artifactPath, err) w.WriteHeader(http.StatusInternalServerError) return } // In order to handle directories we use multipart encoding. // Note that we don't bother on the upload because the client knows all the parts and can // send individually; here they don't know what they'll need to expect. // We could use it for upload too which might be faster and would be more symmetric, but // multipart is a bit fiddly so for now we're not bothering. mw := multipart.NewWriter(w) defer mw.Close() w.Header().Set("Content-Type", mw.FormDataContentType()) for name, body := range art { if part, err := mw.CreateFormFile(name, name); err != nil { log.Errorf("Failed to create form file %s: %s", name, err) w.WriteHeader(http.StatusInternalServerError) } else if _, err := io.Copy(part, bytes.NewReader(body)); err != nil { log.Errorf("Failed to write form file %s: %s", name, err) w.WriteHeader(http.StatusInternalServerError) } } }
// PostFile issues a POST to the fcgi responder in multipart(RFC 2046) standard, // with form as a string key to a list values (url.Values), // and/or with file as a string key to a list file path. func (this *FCGIClient) PostFile(p map[string]string, data url.Values, file map[string]string) (resp *http.Response, err error) { buf := &bytes.Buffer{} writer := multipart.NewWriter(buf) bodyType := writer.FormDataContentType() for key, val := range data { for _, v0 := range val { err = writer.WriteField(key, v0) if err != nil { return } } } for key, val := range file { fd, e := os.Open(val) if e != nil { return nil, e } defer fd.Close() part, e := writer.CreateFormFile(key, filepath.Base(val)) if e != nil { return nil, e } _, err = io.Copy(part, fd) } err = writer.Close() if err != nil { return } return this.Post(p, bodyType, buf, buf.Len()) }
func main() { // http Listener go func() { http.HandleFunc("/", handler) http.ListenAndServe(":9999", nil) }() // build multipart request buf := bytes.Buffer{} multipartWriter := multipart.NewWriter(&buf) multipartWriter.WriteField("foo", "bar") multipartWriter.WriteField("hoge", "fuga") multipartWriter.Close() // request body fmt.Println("# Request Body") fmt.Println(buf.String()) req, err := http.NewRequest("POST", "http://localhost:9999/", &buf) if err != nil { fmt.Println(err) os.Exit(1) } req.Header.Add("Content-Type", multipartWriter.FormDataContentType()) // request client := &http.Client{} _, err = client.Do(req) if err != nil { fmt.Println(err) os.Exit(1) } }
func StreamWriteMultipartForm(params map[string]string, fileField, path, boundary string, pw *io.PipeWriter, buf *bytes.Buffer) { defer pw.Close() mpw := multipart.NewWriter(pw) mpw.SetBoundary(boundary) if fileField != "" && path != "" { fw, err := mpw.CreateFormFile(fileField, filepath.Base(path)) if err != nil { log.Fatal(err) return } if buf != nil { _, err = io.Copy(fw, buf) if err != nil { log.Fatal(err) return } } } for key, val := range params { _ = mpw.WriteField(key, val) } err := mpw.Close() if err != nil { log.Fatal(err) return } }
// based on https://gist.githubusercontent.com/mattetti/5914158/raw/51ee58b51c43f797f200d273853f64e13aa21a8a/multipart_upload.go func (t *Client) newfileUploadRequest(uri string, params map[string]string, bodyField string, toUpload []byte) (*http.Request, error) { glog.V(0).Infoln("newfileUploadRequest", uri) body := &bytes.Buffer{} writer := multipart.NewWriter(body) p, err := writer.CreateFormField(bodyField) if err != nil { return nil, t.Finalize("can't create form field", err) } _, err = p.Write(toUpload) if err != nil { return nil, t.Finalize("can't write payload", err) } for key, val := range params { _ = writer.WriteField(key, val) } err = writer.Close() if err != nil { return nil, t.Finalize("close failed", err) } req, err := http.NewRequest("POST", uri, body) if err != nil { return nil, t.Finalize("new request failed", err) } req.Header.Set("Content-Type", writer.FormDataContentType()) return req, nil }
func createFileParam(param, path string) (*bytes.Buffer, string, error) { body := &bytes.Buffer{} writer := multipart.NewWriter(body) defer writer.Close() p, err := filepath.Abs(path) if err != nil { return nil, "", err } file, err := os.Open(p) if err != nil { return nil, "", err } defer file.Close() part, err := writer.CreateFormFile(param, filepath.Base(path)) if err != nil { return nil, "", err } _, err = io.Copy(part, file) if err != nil { return nil, "", err } return body, writer.FormDataContentType(), nil }
// ChannelFileSend sends a file to the given channel. // channelID : The ID of a Channel. // io.Reader : A reader for the file contents. func (s *Session) ChannelFileSend(channelID, name string, r io.Reader) (st *Message, err error) { body := &bytes.Buffer{} bodywriter := multipart.NewWriter(body) writer, err := bodywriter.CreateFormFile("file", name) if err != nil { return nil, err } _, err = io.Copy(writer, r) if err != nil { return } err = bodywriter.Close() if err != nil { return } response, err := s.request("POST", EndpointChannelMessages(channelID), bodywriter.FormDataContentType(), body.Bytes()) if err != nil { return } err = unmarshal(response, &st) return }
func (h *handler) writeMultipart(subtype string, callback func(*multipart.Writer) error) error { if !h.requestAccepts("multipart/") { return base.HTTPErrorf(http.StatusNotAcceptable, "Response is multipart") } // Get the output stream. Due to a CouchDB bug, if we're sending to it we need to buffer the // output in memory so we can trim the final bytes. var output io.Writer var buffer bytes.Buffer if h.userAgentIs("CouchDB") { output = &buffer } else { output = h.response } writer := multipart.NewWriter(output) h.setHeader("Content-Type", fmt.Sprintf("multipart/%s; boundary=%q", subtype, writer.Boundary())) err := callback(writer) writer.Close() if err == nil && output == &buffer { // Trim trailing newline; CouchDB is allergic to it: _, err = h.response.Write(bytes.TrimRight(buffer.Bytes(), "\r\n")) } return err }
// 通过HTTP上传文件 // 模拟<form ...><input name="file" type="file" />...</form> // 参数说明 // url: 上传服务器URL // form_name: 对应<input>标签中的name // file_name: 为form表单中的文件名 // path: 为实际要上传的本地文件路径 func PostFile(url, form_name, file_name, path string) (res *http.Response, err error) { buf := new(bytes.Buffer) // caveat IMO dont use this for large files, \ // create a tmpfile and assemble your multipart from there (not tested) w := multipart.NewWriter(buf) fw, err := w.CreateFormFile(form_name, file_name) //这里的file必须和服务器端的FormFile一致 if err != nil { return } fd, err := os.Open(path) if err != nil { return } defer fd.Close() // Write file field from file to upload _, err = io.Copy(fw, fd) if err != nil { return } // Important if you do not close the multipart writer you will not have a // terminating boundry w.Close() req, err := http.NewRequest("POST", url, buf) if err != nil { return } req.Header.Set("Content-Type", w.FormDataContentType()) var client http.Client res, err = client.Do(req) return }
// 上传自定义表情 func (this *WebQQ) UploadCustomFace(pic io.Reader) (v string, err error) { form := &bytes.Buffer{} formdata := multipart.NewWriter(form) formdata.WriteField("from", "control") formdata.WriteField("f", "EQQ.Model.ChatMsg.callbackSendPicGroup") formdata.WriteField("vfwebqq", this.vfwebqq) formdata.WriteField("fileid", util.ToString(fileid)) fileid++ picdata, _ := formdata.CreateFormFile("custom_face", "1.png") io.Copy(picdata, pic) formdata.Close() res, err := this.client.Post(_CFACE_UPLOAD_URL+"?time="+util.JsCurrentTime(), formdata.FormDataContentType(), form) if err != nil { return } defer res.Body.Close() b, err := ioutil.ReadAll(res.Body) if err != nil { return } sb := cfacePatten.FindStringSubmatch(string(b)) if len(sb) > 1 { v = sb[1] } return }
func buildRequestWithFile(testCase fileTestCase) *http.Request { b := &bytes.Buffer{} w := multipart.NewWriter(b) if testCase.singleFile != nil { formFileSingle, err := w.CreateFormFile("header_image", testCase.singleFile.fileName) if err != nil { panic("Could not create FormFile (single file): " + err.Error()) } formFileSingle.Write([]byte(testCase.singleFile.data)) } for _, file := range testCase.multipleFiles { formFileMultiple, err := w.CreateFormFile("picture", file.fileName) if err != nil { panic("Could not create FormFile (multiple files): " + err.Error()) } formFileMultiple.Write([]byte(file.data)) } err := w.Close() if err != nil { panic("Could not close multipart writer: " + err.Error()) } req, err := http.NewRequest("POST", testRoute, b) if err != nil { panic("Could not create file upload request: " + err.Error()) } req.Header.Set("Content-Type", w.FormDataContentType()) return req }
// 上传离线图片 func (this *WebQQ) UploadOfflinePic(peeruin Uin, pic io.Reader) (v *ResultOfflinePic, err error) { form := &bytes.Buffer{} formdata := multipart.NewWriter(form) formdata.WriteField("callback", "parent.EQQ.Model.ChatMsg.callbackSendPic") formdata.WriteField("locallangid", "2052") formdata.WriteField("clientversion", "1409") formdata.WriteField("uin", this.id_str) formdata.WriteField("skey", this.getCookie(util.MustParseUrl(_OFFLINE_UPLOAD_URL), "skey")) formdata.WriteField("appid", _WEBQQ_APPID) formdata.WriteField("peeruin", peeruin.String()) formdata.WriteField("vfwebqq", this.vfwebqq) formdata.WriteField("fileid", util.ToString(fileid)) formdata.WriteField("senderviplevel", "0") formdata.WriteField("reciverviplevel", "0") fileid++ picdata, _ := formdata.CreateFormFile("file", "1.png") io.Copy(picdata, pic) formdata.Close() res, err := this.client.Post(_CFACE_UPLOAD_URL+"?time="+util.JsCurrentTime(), formdata.FormDataContentType(), form) if err != nil { return } defer res.Body.Close() b, err := ioutil.ReadAll(res.Body) if err != nil { return } sb := offlinePatten.FindStringSubmatch(string(b)) if len(sb) > 1 { v = &ResultOfflinePic{} json.Unmarshal([]byte(sb[1]), v) } return }
func testMultipart(t *testing.T, test testCase, middleware martini.Handler, handler martini.Handler, index int) *httptest.ResponseRecorder { recorder := httptest.NewRecorder() m := martini.Classic() m.Post(route, middleware, handler) body := &bytes.Buffer{} writer := multipart.NewWriter(body) writer.WriteField("title", test.ref.Title) writer.WriteField("content", test.ref.Content) writer.WriteField("views", strconv.Itoa(test.ref.Views)) if len(test.ref.Multiple) != 0 { for _, value := range test.ref.Multiple { writer.WriteField("multiple", strconv.Itoa(value)) } } req, err := http.NewRequest(test.method, test.path, body) req.Header.Add("Content-Type", writer.FormDataContentType()) if err != nil { t.Error(err) } err = writer.Close() if err != nil { t.Error(err) } m.ServeHTTP(recorder, req) return recorder }
func uploadVideo(creds Credentials, filePath string) (VideoInfo, error) { if _, err := os.Stat(filePath); os.IsNotExist(err) { return VideoInfo{}, err } var buf bytes.Buffer multipartWriter := multipart.NewWriter(&buf) fileHandle, err := os.Open(filePath) if err != nil { return VideoInfo{}, err } fileWriter, err := multipartWriter.CreateFormFile("file", filePath) if err != nil { return VideoInfo{}, err } _, err = io.Copy(fileWriter, fileHandle) if err != nil { return VideoInfo{}, err } multipartWriter.Close() req, err := http.NewRequest("POST", uploadURL, &buf) if err != nil { return VideoInfo{}, err } authenticateHTTPRequest(req, creds) req.Header.Set("Content-Type", multipartWriter.FormDataContentType()) client := &http.Client{} res, err := client.Do(req) if err != nil { return VideoInfo{}, err } defer res.Body.Close() if res.StatusCode != http.StatusOK { return VideoInfo{}, fmt.Errorf("upload failed") } bodyBytes, err := ioutil.ReadAll(res.Body) if err != nil { return VideoInfo{}, err } body := bytesToString(bodyBytes) videoRes, err := videoResponseFromJSON(body) if err != nil { return VideoInfo{}, err } return videoRes, nil }
func Upload(uploadUrl string, filename string, reader io.Reader) (*UploadResult, error) { body_buf := bytes.NewBufferString("") body_writer := multipart.NewWriter(body_buf) file_writer, err := body_writer.CreateFormFile("file", filename) io.Copy(file_writer, reader) content_type := body_writer.FormDataContentType() body_writer.Close() resp, err := http.Post(uploadUrl, content_type, body_buf) if err != nil { log.Println("failing to upload to", uploadUrl) return nil, err } defer resp.Body.Close() resp_body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } var ret UploadResult err = json.Unmarshal(resp_body, &ret) if err != nil { log.Println("failing to read upload resonse", uploadUrl, resp_body) return nil, err } if ret.Error != "" { return nil, errors.New(ret.Error) } return &ret, nil }
func putFile(filename, targetUrl, username, password string) (string, error) { bodyBuf := &bytes.Buffer{} bodyWriter := multipart.NewWriter(bodyBuf) fileWriter, err := bodyWriter.CreateFormFile("uploadfile", filename) check(err) fh, err := os.Open(filename) check(err) _, err = io.Copy(fileWriter, fh) check(err) contentType := bodyWriter.FormDataContentType() bodyWriter.Close() req, err := http.NewRequest("PUT", targetUrl, bodyBuf) check(err) req.Header.Set("Content-Type", contentType) req.SetBasicAuth(username, password) client := &http.Client{} resp, err := client.Do(req) check(err) return resp.Status, nil }
// Creates a new file upload http request func newfileUploadRequest(uri, path string) (*http.Request, error) { file, err := os.Open(path) if err != nil { return nil, err } fileContents, err := ioutil.ReadAll(file) if err != nil { return nil, err } fi, err := file.Stat() if err != nil { return nil, err } file.Close() body := new(bytes.Buffer) writer := multipart.NewWriter(body) part, err := writer.CreateFormFile("file", fi.Name()) if err != nil { return nil, err } part.Write(fileContents) err = writer.Close() if err != nil { return nil, err } request, err := http.NewRequest("POST", uri, body) if err != nil { return nil, err } request.Header.Add("Content-Type", writer.FormDataContentType()) return request, err }
func (self *Baidu) Mkdir(path string) error { url := fmt.Sprintf("https://pcs.baidu.com/rest/2.0/pcs/file?method=mkdir&access_token=%s", self.token.AccessToken) url += "&path=" + neturl.QueryEscape(fmt.Sprintf("/apps/%s/%s", self.dir, path)) buf := new(bytes.Buffer) form := multipart.NewWriter(buf) form.Close() resp, err := self.client.Post(url, form.FormDataContentType(), buf) if err != nil { return err } defer resp.Body.Close() buf.Reset() _, err = io.Copy(buf, resp.Body) if err != nil { return errors.New("response body read error") } respBody := make(map[string]interface{}) err = json.NewDecoder(buf).Decode(&respBody) if err != nil { return errors.New("return json decode error") } q := jsonq.NewQuery(respBody) if resp.StatusCode != http.StatusOK { errCode, _ := q.Int("error_code") errMsg, _ := q.String("error_msg") return errors.New(fmt.Sprintf("server error %d %s", errCode, errMsg)) } return nil }
func (s *DeploySuite) TestDeployUploadFile(c *check.C) { user, _ := s.token.User() a := app.App{Name: "otherapp", Platform: "python", Teams: []string{s.team.Name}} err := app.CreateApp(&a, user) c.Assert(err, check.IsNil) defer app.Delete(&a, nil) url := fmt.Sprintf("/apps/%s/repository/clone?:appname=%s", a.Name, a.Name) var body bytes.Buffer writer := multipart.NewWriter(&body) file, err := writer.CreateFormFile("file", "archive.tar.gz") c.Assert(err, check.IsNil) file.Write([]byte("hello world!")) writer.Close() request, err := http.NewRequest("POST", url, &body) c.Assert(err, check.IsNil) request.Header.Set("Content-Type", "multipart/form-data; boundary="+writer.Boundary()) recorder := httptest.NewRecorder() request.Header.Set("Authorization", "bearer "+s.token.GetValue()) server := RunServer(true) server.ServeHTTP(recorder, request) c.Assert(recorder.Code, check.Equals, http.StatusOK) c.Assert(recorder.Header().Get("Content-Type"), check.Equals, "text") c.Assert(recorder.Code, check.Equals, http.StatusOK) c.Assert(recorder.Body.String(), check.Equals, "Upload deploy called\nOK\n") }
func (s *backupsUploadSuite) sendValid(c *gc.C, id string) *http.Response { s.fake.Meta = backups.NewMetadata() s.fake.Meta.SetID("<a new backup ID>") var parts bytes.Buffer writer := multipart.NewWriter(&parts) // Set the metadata part. s.meta = backups.NewMetadata() metaResult := apiserverbackups.ResultFromMetadata(s.meta) header := make(textproto.MIMEHeader) header.Set("Content-Disposition", `form-data; name="metadata"`) header.Set("Content-Type", apihttp.CTypeJSON) part, err := writer.CreatePart(header) c.Assert(err, jc.ErrorIsNil) err = json.NewEncoder(part).Encode(metaResult) c.Assert(err, jc.ErrorIsNil) // Set the attached part. archive := bytes.NewBufferString("<compressed data>") part, err = writer.CreateFormFile("attached", "juju-backup.tar.gz") c.Assert(err, jc.ErrorIsNil) _, err = io.Copy(part, archive) c.Assert(err, jc.ErrorIsNil) // Send the request. ctype := writer.FormDataContentType() resp, err := s.authRequest(c, "PUT", s.backupURL(c), ctype, &parts) c.Assert(err, jc.ErrorIsNil) return resp }
// PostAttachment uploads r (io.Reader) as an attachment to a given attachmentID func (s *IssueService) PostAttachment(attachmentID string, r io.Reader, attachmentName string) (*[]Attachment, *Response, error) { apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/attachments", attachmentID) b := new(bytes.Buffer) writer := multipart.NewWriter(b) fw, err := writer.CreateFormFile("file", attachmentName) if err != nil { return nil, nil, err } if r != nil { // Copy the file if _, err = io.Copy(fw, r); err != nil { return nil, nil, err } } writer.Close() req, err := s.client.NewMultiPartRequest("POST", apiEndpoint, b) if err != nil { return nil, nil, err } req.Header.Set("Content-Type", writer.FormDataContentType()) // PostAttachment response returns a JSON array (as multiple attachments can be posted) attachment := new([]Attachment) resp, err := s.client.Do(req, attachment) if err != nil { return nil, resp, err } return attachment, resp, nil }
func postFile(url string, reader io.Reader, apiKey string) (resp *http.Response, err error) { body := &bytes.Buffer{} writer := multipart.NewWriter(body) part, err := writer.CreateFormFile("file", "111.png") if err != nil { return nil, err } _, err = io.Copy(part, reader) if err != nil { return } if err = writer.Close(); err != nil { return } req, err := http.NewRequest("POST", getURL(url), body) if err != nil { return nil, err } req.Header.Set("Content-Type", oxford.ContentTypeOctetStream) req.Header.Set("Ocp-Apim-Subscription-Key", apiKey) client := &http.Client{Timeout: time.Second * 30} return client.Do(req) }