func admNewRequest(psp *push.PushServiceProvider, dp *push.DeliveryPoint, data []byte) (req *http.Request, err push.PushError) { var token string var ok bool if token, ok = psp.VolatileData["token"]; !ok { err = push.NewBadPushServiceProviderWithDetails(psp, "NoToken") return } url, err := admURL(dp) if err != nil { return } req, reqErr := http.NewRequest("POST", url, bytes.NewBuffer(data)) if reqErr != nil { return } req.Header.Set("Content-Type", "application/json") req.Header.Set("Accept", "application/json") req.Header.Set("x-amzn-type-version", "[email protected]") req.Header.Set("x-amzn-accept-type", "[email protected]") req.Header.Set("Authorization", "Bearer "+token) return }
func admPspLocker(lockChan <-chan *pspLockRequest) { pspLockMap := make(map[string]*push.PushServiceProvider, 10) for req := range lockChan { var ok bool var clientid string psp := req.psp resp := new(pspLockResponse) if clientid, ok = psp.FixedData["clientid"]; !ok { resp.err = push.NewBadPushServiceProviderWithDetails(psp, "NoClientID") req.respCh <- resp continue } if psp, ok = pspLockMap[clientid]; !ok { psp = req.psp pspLockMap[clientid] = psp } resp.err = requestToken(psp) resp.psp = psp if resp.err != nil { if _, ok := resp.err.(*push.PushServiceProviderUpdate); ok { pspLockMap[clientid] = psp } else { delete(pspLockMap, clientid) } } req.respCh <- resp } }
func connectFeedback(psp *push.PushServiceProvider) (net.Conn, error) { cert, err := tls.LoadX509KeyPair(psp.FixedData["cert"], psp.FixedData["key"]) if err != nil { return nil, push.NewBadPushServiceProviderWithDetails(psp, err.Error()) } conf := &tls.Config{ Certificates: []tls.Certificate{cert}, InsecureSkipVerify: false, } if skip, ok := psp.VolatileData["skipverify"]; ok { if skip == "true" { conf.InsecureSkipVerify = true } } addr := "feedback.sandbox.push.apple.com:2196" if psp.VolatileData["addr"] == "gateway.push.apple.com:2195" { addr = "feedback.push.apple.com:2196" } else if psp.VolatileData["addr"] == "gateway.sandbox.push.apple.com:2195" { addr = "feedback.sandbox.push.apple.com:2196" } else { ae := strings.Split(psp.VolatileData["addr"], ":") addr = fmt.Sprintf("%v:2196", ae[0]) } tlsconn, err := tls.Dial("tcp", addr, conf) if err != nil { return nil, err } err = tlsconn.Handshake() if err != nil { return nil, err } return tlsconn, nil }
func requestToken(psp *push.PushServiceProvider) push.PushError { var ok bool var clientid string var cserect string if _, ok = psp.VolatileData["token"]; ok { if exp, ok := psp.VolatileData["expire"]; ok { unixsec, err := strconv.ParseInt(exp, 10, 64) if err == nil { deadline := time.Unix(unixsec, int64(0)) if deadline.After(time.Now()) { fmt.Printf("We don't need to request another token\n") return nil } } } } if clientid, ok = psp.FixedData["clientid"]; !ok { return push.NewBadPushServiceProviderWithDetails(psp, "NoClientID") } if cserect, ok = psp.FixedData["clientsecret"]; !ok { return push.NewBadPushServiceProviderWithDetails(psp, "NoClientSecret") } form := url.Values{} form.Set("grant_type", "client_credentials") form.Set("scope", "messaging:push") form.Set("client_id", clientid) form.Set("client_secret", cserect) req, err := http.NewRequest("POST", admTokenURL, bytes.NewBufferString(form.Encode())) if err != nil { return push.NewErrorf("NewRequest error: %v", err) } defer req.Body.Close() req.Header.Add("Content-Type", "application/x-www-form-urlencoded") client := &http.Client{} resp, err := client.Do(req) if err != nil { return push.NewErrorf("Do error: %v", err) } defer resp.Body.Close() content, err := ioutil.ReadAll(resp.Body) if err != nil { return push.NewBadPushServiceProviderWithDetails(psp, err.Error()) } if resp.StatusCode != 200 { var fail tokenFailObj err = json.Unmarshal(content, &fail) if err != nil { return push.NewBadPushServiceProviderWithDetails(psp, err.Error()) } reason := strings.ToUpper(fail.Reason) switch reason { case "INVALID_SCOPE": reason = "ADM is not enabled. Enable it on the Amazon Mobile App Distribution Portal" } return push.NewBadPushServiceProviderWithDetails(psp, fmt.Sprintf("%v:%v (%v)", resp.StatusCode, reason, fail.Description)) } var succ tokenSuccObj err = json.Unmarshal(content, &succ) if err != nil { return push.NewBadPushServiceProviderWithDetails(psp, err.Error()) } expire := time.Now().Add(time.Duration(succ.Expire-60) * time.Second) psp.VolatileData["expire"] = fmt.Sprintf("%v", expire.Unix()) psp.VolatileData["token"] = succ.Token psp.VolatileData["type"] = succ.Type return push.NewPushServiceProviderUpdate(psp) }