func (r Client) PostWithMultiPartData(req_url string, headers map[string][]string, params map[string][]string, body io.Reader, filename string) (resp *http.Response, err error) { var buffer *bytes.Buffer = new(bytes.Buffer) var writer *multipart.Writer = multipart.NewWriter(buffer) for k, v := range params { for _, field := range v { err1 := writer.WriteField(k, field) if err1 != nil { err = err1 return } } } w, err := writer.CreateFormFile("file", filename) if err != nil { return } _, err = io.Copy(w, body) if err != nil { return } err = writer.Close() if err != nil { return } if headers == nil { headers = make(map[string][]string) } headers["Content-Type"] = []string{writer.FormDataContentType()} return r.Post(req_url, headers, buffer, int64(buffer.Len())) }
func sendSnapFile(snapPath string, snapFile *os.File, pw *io.PipeWriter, mw *multipart.Writer, action *actionData) { defer snapFile.Close() if action.SnapOptions == nil { action.SnapOptions = &SnapOptions{} } errs := []error{ mw.WriteField("action", action.Action), mw.WriteField("name", action.Name), mw.WriteField("snap-path", action.SnapPath), mw.WriteField("channel", action.Channel), mw.WriteField("devmode", strconv.FormatBool(action.DevMode)), } for _, err := range errs { if err != nil { pw.CloseWithError(err) return } } fw, err := mw.CreateFormFile("snap", filepath.Base(snapPath)) if err != nil { pw.CloseWithError(err) return } _, err = io.Copy(fw, snapFile) if err != nil { pw.CloseWithError(err) return } mw.Close() pw.Close() }
func SendMediaRequest(client *twittergo.Client, reqUrl string, params map[string]string, media []byte) (mediaResp twittergo.MediaResponse, err error) { var ( req *http.Request resp *twittergo.APIResponse body io.ReadWriter = bytes.NewBufferString("") mp *multipart.Writer writer io.Writer contentType string ) mp = multipart.NewWriter(body) for key, value := range params { mp.WriteField(key, value) } if media != nil { if writer, err = mp.CreateFormField("media"); err != nil { return } writer.Write(media) } contentType = fmt.Sprintf("multipart/form-data;boundary=%v", mp.Boundary()) mp.Close() if req, err = http.NewRequest("POST", reqUrl, body); err != nil { return } req.Header.Set("Content-Type", contentType) if resp, err = client.SendRequest(req); err != nil { return } err = resp.Parse(&mediaResp) return }
func (a *BuyActivity) encodeChunkedFirstTransmission(log bitwrk.Logger, mwriter *multipart.Writer) (err error) { part, err := mwriter.CreateFormFile("a32chunks", "a32chunks.bin") if err != nil { return } log.Printf("Sending work chunk hashes to seller [%v].", *a.tx.WorkerURL) err = cafs.WriteChunkHashes(a.workFile, part) if err != nil { return } log.Printf("Sending buyer's secret to seller.") err = mwriter.WriteField("buyersecret", a.buyerSecret.String()) if err != nil { return } return mwriter.Close() }
// streamingUpload streams a file via a pipe through a multipart.Writer. // Generally one should use newStreamingUpload instead of calling this directly. func streamingUpload(file *os.File, fileName string, postBodyWriter *multipart.Writer, w *io.PipeWriter) { defer GinkgoRecover() defer file.Close() defer w.Close() // Set up the form file fileWriter, err := postBodyWriter.CreateFormFile("file", fileName) if err != nil { Failf("Unable to to write file at %s to buffer. Error: %s", fileName, err) } // Copy kubectl binary into the file writer if _, err := io.Copy(fileWriter, file); err != nil { Failf("Unable to to copy file at %s into the file writer. Error: %s", fileName, err) } // Nothing more should be written to this instance of the postBodyWriter if err := postBodyWriter.Close(); err != nil { Failf("Unable to close the writer for file upload. Error: %s", err) } }
func writePluginToWriter(pw io.WriteCloser, bufin []*bufio.Reader, writer *multipart.Writer, pluginPaths []string, errChan chan error) { for i, pluginPath := range pluginPaths { part, err := writer.CreateFormFile("snap-plugins", pluginPath) if err != nil { errChan <- err return } if CompressUpload { cpart := gzip.NewWriter(part) _, err := bufin[i].WriteTo(cpart) if err != nil { errChan <- err return } err = cpart.Close() if err != nil { errChan <- err return } } else { _, err := bufin[i].WriteTo(part) if err != nil { errChan <- err return } } } err := writer.Close() if err != nil { errChan <- err return } err = pw.Close() if err != nil { errChan <- err return } errChan <- nil }
func GetBody() (body io.ReadWriter, header string, err error) { var ( mp *multipart.Writer media []byte writer io.Writer ) body = bytes.NewBufferString("") mp = multipart.NewWriter(body) media, err = ioutil.ReadFile("tweet_media/media.png") if err != nil { return } mp.WriteField("status", fmt.Sprintf("Hello %v!", time.Now())) writer, err = mp.CreateFormFile("media[]", "media.png") if err != nil { return } writer.Write(media) header = fmt.Sprintf("multipart/form-data;boundary=%v", mp.Boundary()) mp.Close() return }
func TestHTTPAPI(t *testing.T) { // get volume // upload // uploads // delete // deletes var ( client http.Client s *Store z *zk.Zookeeper w *multipart.Writer f *os.File bw io.Writer req *http.Request resp *http.Response body []byte err error buf = &bytes.Buffer{} tr = &testRet{} ) os.Remove(testConf.Store.VolumeIndex) os.Remove(testConf.Store.FreeVolumeIndex) os.Remove("./test/_free_block_1") os.Remove("./test/1_0") defer os.Remove(testConf.Store.VolumeIndex) defer os.Remove(testConf.Store.FreeVolumeIndex) defer os.Remove("./test/_free_block_1") defer os.Remove("./test/1_0") if z, err = zk.NewZookeeper(testConf); err != nil { t.Errorf("NewZookeeper() error(%v)", err) t.FailNow() } defer z.Close() z.DelVolume(1) defer z.DelVolume(1) if s, err = NewStore(testConf); err != nil { t.Errorf("NewStore() error(%v)", err) t.FailNow() } defer s.Close() StartAdmin("localhost:6064", s) time.Sleep(1 * time.Second) buf.Reset() buf.WriteString("n=1&bdir=./test/&idir=./test/") if resp, err = http.Post("http://localhost:6064/add_free_volume", "application/x-www-form-urlencoded", buf); err != nil { t.Errorf("http.Post() error(%v)", err) t.FailNow() } defer resp.Body.Close() if body, err = ioutil.ReadAll(resp.Body); err != nil { t.Errorf("ioutil.ReadAll() error(%v)", err) t.FailNow() } if err = json.Unmarshal(body, tr); err != nil { t.Errorf("json.Unmarshal() error(%v)", err) t.FailNow() } if tr.Ret != 1 { t.Errorf("add_free_volume: %d", tr.Ret) t.FailNow() } buf.Reset() buf.WriteString("vid=1") if resp, err = http.Post("http://localhost:6064/add_volume", "application/x-www-form-urlencoded", buf); err != nil { t.Errorf("http.Post() error(%v)", err) t.FailNow() } defer resp.Body.Close() if body, err = ioutil.ReadAll(resp.Body); err != nil { t.Errorf("ioutil.ReadAll() error(%v)", err) t.FailNow() } if err = json.Unmarshal(body, tr); err != nil { t.Errorf("json.Unmarshal() error(%v)", err) t.FailNow() } if tr.Ret != 1 { t.FailNow() } StartApi("localhost:6062", s, testConf) time.Sleep(1 * time.Second) buf.Reset() w = multipart.NewWriter(buf) if bw, err = w.CreateFormFile("file", "./test/1.jpg"); err != nil { t.Errorf("w.CreateFormFile() error(%v)", err) t.FailNow() } if f, err = os.Open("./test/1.jpg"); err != nil { t.Errorf("os.Open() error(%v)", err) t.FailNow() } defer f.Close() if _, err = io.Copy(bw, f); err != nil { t.Errorf("io.Copy() error(%v)", err) t.FailNow() } if err = w.WriteField("vid", "1"); err != nil { t.Errorf("w.WriteField() error(%v)", err) t.FailNow() } if err = w.WriteField("key", "15"); err != nil { t.Errorf("w.WriteField() error(%v)", err) t.FailNow() } if err = w.WriteField("cookie", "15"); err != nil { t.Errorf("w.WriteField() error(%v)", err) t.FailNow() } w.Close() if req, err = http.NewRequest("POST", "http://localhost:6062/upload", buf); err != nil { t.Errorf("http..NewRequest() error(%v)", err) t.FailNow() } req.Header.Set("Content-Type", w.FormDataContentType()) if resp, err = client.Do(req); err != nil { t.Errorf("client.Do() error(%v)", err) t.FailNow() } defer resp.Body.Close() if body, err = ioutil.ReadAll(resp.Body); err != nil { t.Errorf("ioutil.ReadAll() error(%v)", err) t.FailNow() } if err = json.Unmarshal(body, tr); err != nil { t.Errorf("json.Unmarshal() error(%v)", err) t.FailNow() } if tr.Ret != 1 { t.Errorf("ret: %d", tr.Ret) t.FailNow() } buf.Reset() w = multipart.NewWriter(buf) if err = w.WriteField("vid", "1"); err != nil { t.Errorf("w.WriteField() error(%v)", err) t.FailNow() } for i := 1; i < 10; i++ { if bw, err = w.CreateFormFile("file", "./test/"+strconv.Itoa(i)+".jpg"); err != nil { t.Errorf("w.CreateFormFile() error(%v)", err) t.FailNow() } if f, err = os.Open("./test/" + strconv.Itoa(i) + ".jpg"); err != nil { t.Errorf("os.Open() error(%v)", err) t.FailNow() } defer f.Close() if _, err = io.Copy(bw, f); err != nil { t.Errorf("io.Copy() error(%v)", err) t.FailNow() } if err = w.WriteField("keys", strconv.Itoa(20+i)); err != nil { t.Errorf("w.WriteField() error(%v)", err) t.FailNow() } if err = w.WriteField("cookies", strconv.Itoa(20+i)); err != nil { t.Errorf("w.WriteField() error(%v)", err) t.FailNow() } } w.Close() if req, err = http.NewRequest("POST", "http://localhost:6062/uploads", buf); err != nil { t.Errorf("http..NewRequest() error(%v)", err) t.FailNow() } req.Header.Set("Content-Type", w.FormDataContentType()) if resp, err = client.Do(req); err != nil { t.Errorf("client.Do() error(%v)", err) t.FailNow() } defer resp.Body.Close() if body, err = ioutil.ReadAll(resp.Body); err != nil { t.Errorf("ioutil.ReadAll() error(%v)", err) t.FailNow() } if err = json.Unmarshal(body, tr); err != nil { t.Errorf("json.Unmarshal() error(%v)", err) t.FailNow() } if tr.Ret != 1 { t.Errorf("uploads: %d", tr.Ret) t.FailNow() } buf.Reset() buf.WriteString("vid=1&key=21") if resp, err = http.Post("http://localhost:6062/del", "application/x-www-form-urlencoded", buf); err != nil { t.Errorf("http.Post() error(%v)", err) t.FailNow() } defer resp.Body.Close() if body, err = ioutil.ReadAll(resp.Body); err != nil { t.Errorf("ioutil.ReadAll() error(%v)", err) t.FailNow() } if err = json.Unmarshal(body, tr); err != nil { t.Errorf("json.Unmarshal() error(%v)", err) t.FailNow() } if tr.Ret != 1 { t.FailNow() } // TODO add get }
func sendMail(to []string, cc []string, bcc []string, msg *Message) error { from := Config.DefaultFrom server := Config.MailServer if msg.Server != "" { server = msg.Server } if msg.From != "" { from = msg.From } if from == "" { return errNoFrom } var auth smtp.Auth cram, username, password, server := parseServer(server) if username != "" || password != "" { if cram { auth = smtp.CRAMMD5Auth(username, password) } else { auth = smtp.PlainAuth("", username, password, server) } } var buf bytes.Buffer headers := msg.Headers if headers == nil { headers = make(Headers) } if msg.Subject != "" { headers["Subject"] = msg.Subject } headers["From"] = from if msg.ReplyTo != "" { headers["Reply-To"] = msg.ReplyTo } var err error if len(to) > 0 { headers["To"], err = joinAddrs(to) if err != nil { return err } for ii, v := range to { if v == Admin { if Config.AdminEmail == "" { return errNoAdminEmail } to[ii] = Config.AdminEmail } } } if len(cc) > 0 { headers["Cc"], err = joinAddrs(cc) if err != nil { return err } } if len(bcc) > 0 { headers["Bcc"], err = joinAddrs(bcc) if err != nil { return err } } hk := make([]string, 0, len(headers)) for k := range headers { hk = append(hk, k) } sort.Strings(hk) for _, k := range hk { buf.WriteString(fmt.Sprintf("%s: %s\r\n", k, headers[k])) } buf.WriteString("MIME-Version: 1.0\r\n") mw := multipart.NewWriter(&buf) mw.SetBoundary(makeBoundary()) // Create a multipart mixed first fmt.Fprintf(&buf, "Content-Type: multipart/mixed;\r\n\tboundary=%q\r\n\r\n", mw.Boundary()) var bodyWriter *multipart.Writer if msg.TextBody != "" && msg.HTMLBody != "" { boundary := makeBoundary() outerHeader := make(textproto.MIMEHeader) // First part is a multipart/alternative, which contains the text and html bodies outerHeader.Set("Content-Type", fmt.Sprintf("multipart/alternative; boundary=%q", boundary)) iw, err := mw.CreatePart(outerHeader) if err != nil { return err } bodyWriter = multipart.NewWriter(iw) bodyWriter.SetBoundary(boundary) } else { bodyWriter = mw } if msg.TextBody != "" { textHeader := make(textproto.MIMEHeader) textHeader.Set("Content-Type", "text/plain; charset=UTF-8") tpw, err := bodyWriter.CreatePart(textHeader) if err != nil { return err } if _, err := io.WriteString(tpw, msg.TextBody); err != nil { return err } tpw.Write(crlf) tpw.Write(crlf) } attached := make(map[*Attachment]bool) if msg.HTMLBody != "" { var htmlAttachments []*Attachment for _, v := range msg.Attachments { if v.ContentID != "" && strings.Contains(msg.HTMLBody, fmt.Sprintf("cid:%s", v.ContentID)) { htmlAttachments = append(htmlAttachments, v) attached[v] = true } } var htmlWriter *multipart.Writer if len(htmlAttachments) > 0 { relatedHeader := make(textproto.MIMEHeader) relatedBoundary := makeBoundary() relatedHeader.Set("Content-Type", fmt.Sprintf("multipart/related; boundary=%q; type=\"text/html\"", relatedBoundary)) rw, err := bodyWriter.CreatePart(relatedHeader) if err != nil { return err } htmlWriter = multipart.NewWriter(rw) htmlWriter.SetBoundary(relatedBoundary) } else { htmlWriter = bodyWriter } htmlHeader := make(textproto.MIMEHeader) htmlHeader.Set("Content-Type", "text/html; charset=UTF-8") thw, err := htmlWriter.CreatePart(htmlHeader) if err != nil { return err } if _, err := io.WriteString(thw, msg.HTMLBody); err != nil { return err } thw.Write(crlf) thw.Write(crlf) for _, v := range htmlAttachments { attachmentHeader := make(textproto.MIMEHeader) attachmentHeader.Set("Content-Disposition", "inline") attachmentHeader.Set("Content-Id", fmt.Sprintf("<%s>", v.ContentID)) attachmentHeader.Set("Content-Transfer-Encoding", "base64") attachmentHeader.Set("Content-Type", v.ContentType) aw, err := htmlWriter.CreatePart(attachmentHeader) if err != nil { return err } b := make([]byte, base64.StdEncoding.EncodedLen(len(v.Data))) base64.StdEncoding.Encode(b, v.Data) aw.Write(b) } if htmlWriter != bodyWriter { if err := htmlWriter.Close(); err != nil { return err } } } if bodyWriter != mw { if err := bodyWriter.Close(); err != nil { return err } } for _, v := range msg.Attachments { if attached[v] { continue } attachmentHeader := make(textproto.MIMEHeader) attachmentHeader.Set("Content-Disposition", fmt.Sprintf("attachment; filename=%q", v.Name)) attachmentHeader.Set("Content-Transfer-Encoding", "base64") attachmentHeader.Set("Content-Type", v.ContentType) aw, err := mw.CreatePart(attachmentHeader) if err != nil { return err } b := make([]byte, base64.StdEncoding.EncodedLen(len(v.Data))) base64.StdEncoding.Encode(b, v.Data) aw.Write(b) } if err := mw.Close(); err != nil { return err } if server == "echo" { printer(buf.String()) return nil } return smtp.SendMail(server, auth, from, to, buf.Bytes()) }
// Http params func Http(method, uri string, params url.Values, buf []byte, res interface{}) (err error) { var ( body []byte w *multipart.Writer bw io.Writer bufdata = &bytes.Buffer{} req *http.Request resp *http.Response ru string enc string ctype string ) enc = params.Encode() if enc != "" { ru = uri + "?" + enc } if method == "GET" { if req, err = http.NewRequest("GET", ru, nil); err != nil { return } } else { if buf == nil { if req, err = http.NewRequest("POST", uri, strings.NewReader(enc)); err != nil { return } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") } else { w = multipart.NewWriter(bufdata) if bw, err = w.CreateFormFile("file", "1.jpg"); err != nil { return } if _, err = bw.Write(buf); err != nil { return } for key, _ := range params { w.WriteField(key, params.Get(key)) } ctype = w.FormDataContentType() if err = w.Close(); err != nil { return } if req, err = http.NewRequest("POST", uri, bufdata); err != nil { return } req.Header.Set("Content-Type", ctype) } } td := _timer.Start(5*time.Second, func() { _canceler(req) }) if resp, err = _client.Do(req); err != nil { log.Errorf("_client.Do(%s) error(%v)", ru, err) return } td.Stop() defer resp.Body.Close() if res == nil { return } if resp.StatusCode != http.StatusOK { log.Errorf("_client.Do(%s) status: %d", ru, resp.StatusCode) return } if body, err = ioutil.ReadAll(resp.Body); err != nil { log.Errorf("ioutil.ReadAll(%s) uri(%s) error(%v)", body, ru, err) return } if err = json.Unmarshal(body, res); err != nil { log.Errorf("json.Unmarshal(%s) uri(%s) error(%v)", body, ru, err) } return }
func PostFile(req_url, path, filename string, start, end, filesize int, params map[string]string) (body string, err error) { var buffer *bytes.Buffer = bytes.NewBuffer(make([]byte, 0)) var writer *multipart.Writer = multipart.NewWriter(buffer) for k, v := range params { err = writer.WriteField(k, v) if err != nil { return } } var file *os.File if file, err = os.OpenFile(path, os.O_RDONLY, 0644); err != nil { return } defer file.Close() w, err := writer.CreateFormFile("file", filename) if err != nil { return } var size = end - start + 1 if size == filesize { _, err = io.Copy(w, file) if err != nil { return } } else { var section []byte = make([]byte, size) var n int n, err = file.ReadAt(section, int64(start)) if err != nil || n != size { return } var buf *bytes.Buffer = bytes.NewBuffer(make([]byte, 0)) buf.Write(section) _, err = io.Copy(w, buf) if err != nil { return } } writer.Close() var client *http.Client = new(http.Client) var req *http.Request req, err = http.NewRequest("POST", req_url, buffer) if err != nil { return } req.Header.Set("Content-Type", writer.FormDataContentType()) req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20100101 Firefox/17.0") var resp *http.Response resp, err = client.Do(req) if err != nil { return } defer resp.Body.Close() resp_body, err := ioutil.ReadAll(resp.Body) body = string(resp_body) if resp.StatusCode != 200 { err = errors.New(fmt.Sprintf("%d", resp.StatusCode)) return } return }
func (douban *Douban) post(requestUrl string, accessToken string, params Params, picReader io.Reader, picFormat string, response interface{}) error { var urlBuffer bytes.Buffer urlBuffer.WriteString(requestUrl) var bodyBuffer bytes.Buffer var writer *multipart.Writer if picReader == nil { body := url.Values{} for k, v := range params { value := fmt.Sprint(v) body.Add(k, value) } bodyBuffer = *bytes.NewBufferString(body.Encode()) } else { writer = multipart.NewWriter(&bodyBuffer) picWriter, err := writer.CreateFormFile("image", "image."+picFormat) if err != nil { return err } _, e := io.Copy(picWriter, picReader) if e != nil { return e } for k, v := range params { value := fmt.Sprint(v) if k != "" && value != "" { writer.WriteField(k, value) } } writer.Close() } // log.Printf("URL: %s\n", urlBuffer.String()) // log.Printf("Body: %#v\n", bodyBuffer) req, err := http.NewRequest("POST", urlBuffer.String(), &bodyBuffer) if err != nil { return err } req.Header.Add("Authorization", accessToken) if picReader == nil { req.Header.Add("Content-Type", "application/x-www-form-urlencoded") } else { req.Header.Add("Content-Type", writer.FormDataContentType()) } // log.Printf("Header: %#V\n", req.Header) resp, err := douban.httpClient.Do(req) if err != nil { return err } defer resp.Body.Close() respContent, err := ioutil.ReadAll(resp.Body) if err != nil { return err } if resp.StatusCode != 200 { doubanError := DoubanError{} err := json.Unmarshal(respContent, &doubanError) if err != nil { return err } else { return &doubanError } } //log.Printf("==================================\n================================\n%s\n", respContent) return json.Unmarshal(respContent, &response) }
// Bytes gets the encoded MIME message. func (m *Message) Bytes() ([]byte, error) { var buffer = &bytes.Buffer{} header := textproto.MIMEHeader{} var err error // Require To, Cc, or Bcc // We'll parse the slices into a list of addresses // and then make sure that list isn't empty. toAddrs := getAddressListString(m.To) ccAddrs := getAddressListString(m.Cc) bccAddrs := getAddressListString(m.Bcc) var hasTo = toAddrs != "" var hasCc = ccAddrs != "" var hasBcc = bccAddrs != "" if !hasTo && !hasCc && !hasBcc { return nil, ErrMissingRecipient } if hasTo { header.Add("To", toAddrs) } if hasCc { header.Add("Cc", ccAddrs) } // BCC header is excluded on purpose. // BCC recipients aren't included in the message // headers and are only used at the SMTP level. var emptyAddress mail.Address // Require From address if m.From == emptyAddress { return nil, ErrMissingFromAddress } header.Add("From", m.From.String()) // Optional ReplyTo if m.ReplyTo != emptyAddress { header.Add("Reply-To", m.ReplyTo.String()) } // Optional Subject if m.Subject != "" { quotedSubject := qEncodeAndWrap(m.Subject, 9 /* len("Subject: ") */) if quotedSubject[0] == '"' { // qEncode used simple quoting, which adds quote // characters to email subjects. quotedSubject = quotedSubject[1 : len(quotedSubject)-1] } header.Add("Subject", quotedSubject) } // Date if _, ok := m.Headers["Date"]; !ok { header.Add("Date", time.Now().UTC().Format(time.RFC822)) } for k, v := range m.Headers { header[k] = v } header.Add("MIME-Version", "1.0") var mixedw *multipart.Writer var hasAttachments = m.Attachments != nil && len(m.Attachments) > 0 if hasAttachments { // Top level multipart writer for our `multipart/mixed` body. // only needed if we have attachments mixedw = multipart.NewWriter(buffer) header.Add("Content-Type", fmt.Sprintf("multipart/mixed;%s boundary=%s", crlf, mixedw.Boundary())) err = writeHeader(buffer, header) if err != nil { return nil, err } header = textproto.MIMEHeader{} // Write the start of our `multipart/mixed` body. _, err = fmt.Fprintf(buffer, "--%s%s", mixedw.Boundary(), crlf) if err != nil { return nil, err } } var altw *multipart.Writer if m.Body != "" && m.HTMLBody != "" { // Nested multipart writer for our `multipart/alternative` body. altw = multipart.NewWriter(buffer) header.Add("Content-Type", fmt.Sprintf("multipart/alternative;%s boundary=%s", crlf, altw.Boundary())) err := writeHeader(buffer, header) if err != nil { return nil, err } } // Only include an empty plain text body if the html body is also empty. if m.Body != "" || m.Body == "" && m.HTMLBody == "" { if altw != nil { header = textproto.MIMEHeader{} } header.Add("Content-Type", "text/plain; charset=utf-8") header.Add("Content-Transfer-Encoding", "quoted-printable") //header.Add("Content-Transfer-Encoding", "base64") var writer io.Writer if altw != nil { partw, err := altw.CreatePart(header) if err != nil { return nil, err } writer = partw } else { writer = buffer err = writeHeader(buffer, header) if err != nil { return nil, err } } bodyBytes := []byte(m.Body) //encoder := NewBase64MimeEncoder(writer) encoder := qprintable.NewEncoder(qprintable.DetectEncoding(m.Body), writer) _, err = encoder.Write(bodyBytes) if err != nil { return nil, err } err = encoder.Close() if err != nil { return nil, err } } if m.HTMLBody != "" { if altw != nil { header = textproto.MIMEHeader{} } header.Add("Content-Type", "text/html; charset=utf-8") //header.Add("Content-Transfer-Encoding", "quoted-printable") header.Add("Content-Transfer-Encoding", "base64") var writer io.Writer if altw != nil { partw, err := altw.CreatePart(header) if err != nil { return nil, err } writer = partw } else { writer = buffer err = writeHeader(buffer, header) if err != nil { return nil, err } } htmlBodyBytes := []byte(m.HTMLBody) encoder := NewBase64MimeEncoder(writer) //encoder := qprintable.NewEncoder(qprintable.DetectEncoding(m.HTMLBody), writer) _, err = encoder.Write(htmlBodyBytes) if err != nil { return nil, err } err = encoder.Close() if err != nil { return nil, err } } if altw != nil { altw.Close() } else { _, err = fmt.Fprintf(buffer, "%s", crlf) if err != nil { return nil, err } } if hasAttachments { for _, attachment := range m.Attachments { contentType := attachment.ContentType if contentType == "" { contentType = mime.TypeByExtension(filepath.Ext(attachment.Name)) if contentType == "" { contentType = "application/octet-stream" } } header := textproto.MIMEHeader{} header.Add("Content-Type", contentType) header.Add("Content-Disposition", fmt.Sprintf(`attachment;%s filename="%s"`, crlf, attachment.Name)) header.Add("Content-Transfer-Encoding", "base64") attachmentPart, err := mixedw.CreatePart(header) if err != nil { return nil, err } if attachment.Data != nil { encoder := NewBase64MimeEncoder(attachmentPart) _, err = io.Copy(encoder, attachment.Data) if err != nil { return nil, err } err = encoder.Close() if err != nil { return nil, err } } } mixedw.Close() } return buffer.Bytes(), nil }
func TestHTTPAPI(t *testing.T) { // get volume // upload // uploads // delete // deletes var ( client http.Client s *Store z *Zookeeper w *multipart.Writer f *os.File bw io.Writer req *http.Request resp *http.Response body []byte err error buf = &bytes.Buffer{} tr = &testRet{} file = "./test/store_api.idx" bfile = "./test/block_api_1" ifile = "./test/block_api_1.idx" ) os.Remove(file) os.Remove(bfile) os.Remove(ifile) defer os.Remove(file) defer os.Remove(bfile) defer os.Remove(ifile) t.Log("NewStore()") if z, err = NewZookeeper([]string{"localhost:2181"}, time.Second*1, "/rack/test-api/"); err != nil { t.Errorf("NewZookeeper() error(%v)", err) t.FailNow() } z.DelVolume(1) if s, err = NewStore(z, file); err != nil { t.Errorf("NewStore() error(%v)", err) t.FailNow() } defer s.Close() StartAdmin(s, "localhost:6064") time.Sleep(1 * time.Second) t.Log("AddFreeVolume()") buf.Reset() buf.WriteString("n=1&bdir=./test/&idir=./test/") if resp, err = http.Post("http://localhost:6064/add_free_volume", "application/x-www-form-urlencoded", buf); err != nil { t.Errorf("http.Post() error(%v)", err) t.FailNow() } defer resp.Body.Close() if body, err = ioutil.ReadAll(resp.Body); err != nil { t.Errorf("ioutil.ReadAll() error(%v)", err) t.FailNow() } t.Logf("%s", body) if err = json.Unmarshal(body, tr); err != nil { t.Errorf("json.Unmarshal() error(%v)", err) t.FailNow() } if tr.Ret != 1 { t.FailNow() } t.Log("AddVolume()") buf.Reset() buf.WriteString("vid=1") if resp, err = http.Post("http://localhost:6064/add_volume", "application/x-www-form-urlencoded", buf); err != nil { t.Errorf("http.Post() error(%v)", err) t.FailNow() } defer resp.Body.Close() if body, err = ioutil.ReadAll(resp.Body); err != nil { t.Errorf("ioutil.ReadAll() error(%v)", err) t.FailNow() } t.Logf("%s", body) if err = json.Unmarshal(body, tr); err != nil { t.Errorf("json.Unmarshal() error(%v)", err) t.FailNow() } if tr.Ret != 1 { t.FailNow() } StartApi(s, "localhost:6062") time.Sleep(1 * time.Second) t.Log("Upload") buf.Reset() w = multipart.NewWriter(buf) if bw, err = w.CreateFormFile("file", "./test/1.jpg"); err != nil { t.Errorf("w.CreateFormFile() error(%v)", err) t.FailNow() } if f, err = os.Open("./test/1.jpg"); err != nil { t.Errorf("os.Open() error(%v)", err) t.FailNow() } defer f.Close() if _, err = io.Copy(bw, f); err != nil { t.Errorf("io.Copy() error(%v)", err) t.FailNow() } if err = w.WriteField("vid", "1"); err != nil { t.Errorf("w.WriteField() error(%v)", err) t.FailNow() } if err = w.WriteField("key", "15"); err != nil { t.Errorf("w.WriteField() error(%v)", err) t.FailNow() } if err = w.WriteField("cookie", "15"); err != nil { t.Errorf("w.WriteField() error(%v)", err) t.FailNow() } w.Close() if req, err = http.NewRequest("POST", "http://localhost:6062/upload", buf); err != nil { t.Errorf("http..NewRequest() error(%v)", err) t.FailNow() } req.Header.Set("Content-Type", w.FormDataContentType()) if resp, err = client.Do(req); err != nil { t.Errorf("client.Do() error(%v)", err) t.FailNow() } defer resp.Body.Close() if body, err = ioutil.ReadAll(resp.Body); err != nil { t.Errorf("ioutil.ReadAll() error(%v)", err) t.FailNow() } if err = json.Unmarshal(body, tr); err != nil { t.Errorf("json.Unmarshal() error(%v)", err) t.FailNow() } if tr.Ret != 1 { t.Errorf("ret: %d", tr.Ret) t.FailNow() } t.Log("Uploads") buf.Reset() w = multipart.NewWriter(buf) if err = w.WriteField("vid", "1"); err != nil { t.Errorf("w.WriteField() error(%v)", err) t.FailNow() } for i := 1; i < 10; i++ { if bw, err = w.CreateFormFile("file", "./test/"+strconv.Itoa(i)+".jpg"); err != nil { t.Errorf("w.CreateFormFile() error(%v)", err) t.FailNow() } if f, err = os.Open("./test/" + strconv.Itoa(i) + ".jpg"); err != nil { t.Errorf("os.Open() error(%v)", err) t.FailNow() } defer f.Close() if _, err = io.Copy(bw, f); err != nil { t.Errorf("io.Copy() error(%v)", err) t.FailNow() } if err = w.WriteField("keys", strconv.Itoa(20+i)); err != nil { t.Errorf("w.WriteField() error(%v)", err) t.FailNow() } if err = w.WriteField("cookies", strconv.Itoa(20+i)); err != nil { t.Errorf("w.WriteField() error(%v)", err) t.FailNow() } } w.Close() if req, err = http.NewRequest("POST", "http://localhost:6062/uploads", buf); err != nil { t.Errorf("http..NewRequest() error(%v)", err) t.FailNow() } req.Header.Set("Content-Type", w.FormDataContentType()) if resp, err = client.Do(req); err != nil { t.Errorf("client.Do() error(%v)", err) t.FailNow() } defer resp.Body.Close() if body, err = ioutil.ReadAll(resp.Body); err != nil { t.Errorf("ioutil.ReadAll() error(%v)", err) t.FailNow() } if err = json.Unmarshal(body, tr); err != nil { t.Errorf("json.Unmarshal() error(%v)", err) t.FailNow() } if tr.Ret != 1 { t.Errorf("ret: %d", tr.Ret) t.FailNow() } // t.Log("Get") t.Log("Delete") buf.Reset() buf.WriteString("vid=1&key=21") if resp, err = http.Post("http://localhost:6062/del", "application/x-www-form-urlencoded", buf); err != nil { t.Errorf("http.Post() error(%v)", err) t.FailNow() } defer resp.Body.Close() if body, err = ioutil.ReadAll(resp.Body); err != nil { t.Errorf("ioutil.ReadAll() error(%v)", err) t.FailNow() } t.Logf("%s", body) if err = json.Unmarshal(body, tr); err != nil { t.Errorf("json.Unmarshal() error(%v)", err) t.FailNow() } if tr.Ret != 1 { t.FailNow() } t.Log("Deletes") buf.Reset() buf.WriteString("vid=1&keys=21&keys=22") if resp, err = http.Post("http://localhost:6062/dels", "application/x-www-form-urlencoded", buf); err != nil { t.Errorf("http.Post() error(%v)", err) t.FailNow() } defer resp.Body.Close() if body, err = ioutil.ReadAll(resp.Body); err != nil { t.Errorf("ioutil.ReadAll() error(%v)", err) t.FailNow() } t.Logf("%s", body) if err = json.Unmarshal(body, tr); err != nil { t.Errorf("json.Unmarshal() error(%v)", err) t.FailNow() } if tr.Ret != 1 { t.FailNow() } }
// 向微博API服务器发送POST请求 // // 输入参数的含义请见Upload函数注释。当reader == nil时使用query string模式,否则使用multipart。 func (weibo *Weibo) sendPostHttpRequest(uri string, token string, params Params, reader io.Reader, imageFormat string, response interface{}) error { // 生成POST请求URI requestUri := fmt.Sprintf("%s?access_token=%s", uri, token) // 生成POST内容 var bodyBuffer bytes.Buffer var writer *multipart.Writer if reader == nil { // reader为nil时无文件上传,因此POST body为简单的query string模式 pb := url.Values{} pb.Add("access_token", token) for k, v := range params { value := fmt.Sprint(v) if k != "" && value != "" { pb.Add(k, value) } } bodyBuffer = *bytes.NewBufferString(pb.Encode()) } else { // 否则POST body使用multipart模式 writer = multipart.NewWriter(&bodyBuffer) imagePartWriter, _ := writer.CreateFormFile("pic", "image."+imageFormat) io.Copy(imagePartWriter, reader) for k, v := range params { value := fmt.Sprint(v) if k != "" && value != "" { writer.WriteField(k, value) } } writer.Close() } // 生成POST请求 req, err := http.NewRequest("POST", requestUri, &bodyBuffer) if err != nil { return err } if reader == nil { // reader为nil时使用一般的内容类型 req.Header.Set("Content-Type", "application/x-www-form-urlencoded") } else { // 否则使用带boundary的multipart类型 req.Header.Set("Content-Type", writer.FormDataContentType()) } // 发送请求 resp, err := weibo.httpClient.Do(req) if err != nil { return err } defer resp.Body.Close() // 解析API服务器返回内容 bytes, _ := ioutil.ReadAll(resp.Body) if resp.StatusCode == 200 { err := json.Unmarshal(bytes, &response) if err != nil { return err } return nil } else { var weiboErr WeiboError err := json.Unmarshal(bytes, &weiboErr) if err != nil { return err } return weiboErr } return nil }