summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/Rhymen/go-whatsapp/media.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/Rhymen/go-whatsapp/media.go')
-rw-r--r--vendor/github.com/Rhymen/go-whatsapp/media.go112
1 files changed, 58 insertions, 54 deletions
diff --git a/vendor/github.com/Rhymen/go-whatsapp/media.go b/vendor/github.com/Rhymen/go-whatsapp/media.go
index b15b9ae2..87827d9c 100644
--- a/vendor/github.com/Rhymen/go-whatsapp/media.go
+++ b/vendor/github.com/Rhymen/go-whatsapp/media.go
@@ -10,10 +10,8 @@ import (
"fmt"
"io"
"io/ioutil"
- "mime/multipart"
"net/http"
- "os"
- "strings"
+ "net/url"
"time"
"github.com/Rhymen/go-whatsapp/crypto/cbc"
@@ -95,7 +93,50 @@ func downloadMedia(url string) (file []byte, mac []byte, err error) {
return data[:n-10], data[n-10 : n], nil
}
-func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (url string, mediaKey []byte, fileEncSha256 []byte, fileSha256 []byte, fileLength uint64, err error) {
+type MediaConn struct {
+ Status int `json:"status"`
+ MediaConn struct {
+ Auth string `json:"auth"`
+ TTL int `json:"ttl"`
+ Hosts []struct {
+ Hostname string `json:"hostname"`
+ IPs []string `json:"ips"`
+ } `json:"hosts"`
+ } `json:"media_conn"`
+}
+
+func (wac *Conn) queryMediaConn() (hostname, auth string, ttl int, err error) {
+ queryReq := []interface{}{"query", "mediaConn"}
+ ch, err := wac.writeJson(queryReq)
+ if err != nil {
+ return "", "", 0, err
+ }
+
+ var resp MediaConn
+ select {
+ case r := <-ch:
+ if err = json.Unmarshal([]byte(r), &resp); err != nil {
+ return "", "", 0, fmt.Errorf("error decoding query media conn response: %v", err)
+ }
+ case <-time.After(wac.msgTimeout):
+ return "", "", 0, fmt.Errorf("query media conn timed out")
+ }
+
+ if resp.Status != 200 {
+ return "", "", 0, fmt.Errorf("query media conn responded with %d", resp.Status)
+ }
+
+ return resp.MediaConn.Hosts[0].Hostname, resp.MediaConn.Auth, resp.MediaConn.TTL, nil
+}
+
+var mediaTypeMap = map[MediaType]string{
+ MediaImage: "/mms/image",
+ MediaVideo: "/mms/video",
+ MediaDocument: "/mms/document",
+ MediaAudio: "/mms/audio",
+}
+
+func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (downloadURL string, mediaKey []byte, fileEncSha256 []byte, fileSha256 []byte, fileLength uint64, err error) {
data, err := ioutil.ReadAll(reader)
if err != nil {
return "", nil, nil, nil, 0, err
@@ -128,67 +169,30 @@ func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (url string, mediaK
sha.Write(append(enc, mac...))
fileEncSha256 = sha.Sum(nil)
- var filetype string
- switch appInfo {
- case MediaImage:
- filetype = "image"
- case MediaAudio:
- filetype = "audio"
- case MediaDocument:
- filetype = "document"
- case MediaVideo:
- filetype = "video"
- }
-
- uploadReq := []interface{}{"action", "encr_upload", filetype, base64.StdEncoding.EncodeToString(fileEncSha256)}
- ch, err := wac.writeJson(uploadReq)
- if err != nil {
- return "", nil, nil, nil, 0, err
+ hostname, auth, _, err := wac.queryMediaConn()
+ token := base64.URLEncoding.EncodeToString(fileEncSha256)
+ q := url.Values{
+ "auth": []string{auth},
+ "token": []string{token},
}
-
- var resp map[string]interface{}
- select {
- case r := <-ch:
- if err = json.Unmarshal([]byte(r), &resp); err != nil {
- return "", nil, nil, nil, 0, fmt.Errorf("error decoding upload response: %v", err)
- }
- case <-time.After(wac.msgTimeout):
- return "", nil, nil, nil, 0, fmt.Errorf("restore session init timed out")
+ path := mediaTypeMap[appInfo]
+ uploadURL := url.URL{
+ Scheme: "https",
+ Host: hostname,
+ Path: fmt.Sprintf("%s/%s", path, token),
+ RawQuery: q.Encode(),
}
- if int(resp["status"].(float64)) != 200 {
- return "", nil, nil, nil, 0, fmt.Errorf("upload responsed with %d", resp["status"])
- }
+ body := bytes.NewReader(append(enc, mac...))
- var b bytes.Buffer
- w := multipart.NewWriter(&b)
- hashWriter, err := w.CreateFormField("hash")
- if err != nil {
- fmt.Fprintf(os.Stderr, "%v\n", err)
- }
- io.Copy(hashWriter, strings.NewReader(base64.StdEncoding.EncodeToString(fileEncSha256)))
-
- fileWriter, err := w.CreateFormFile("file", "blob")
- if err != nil {
- fmt.Fprintf(os.Stderr, "%v\n", err)
- }
- io.Copy(fileWriter, bytes.NewReader(append(enc, mac...)))
- err = w.Close()
- if err != nil {
- fmt.Fprintf(os.Stderr, "%v\n", err)
- }
-
- req, err := http.NewRequest("POST", resp["url"].(string), &b)
+ req, err := http.NewRequest("POST", uploadURL.String(), body)
if err != nil {
return "", nil, nil, nil, 0, err
}
- req.Header.Set("Content-Type", w.FormDataContentType())
req.Header.Set("Origin", "https://web.whatsapp.com")
req.Header.Set("Referer", "https://web.whatsapp.com/")
- req.URL.Query().Set("f", "j")
-
client := &http.Client{}
// Submit the request
res, err := client.Do(req)