func ServeHTTP(w http.ResponseWriter, r *http.Request, queryValues url.Values, srv Server, errHandler ErrorHandler) { switch r.Method { case "POST": RawMsgXML, err := ioutil.ReadAll(r.Body) if err != nil { errHandler.ServeError(w, r, err) return } msg, err := util.DecodeXMLToMap(bytes.NewReader(RawMsgXML)) if err != nil { errHandler.ServeError(w, r, err) return } ReturnCode, ok := msg["return_code"] if ReturnCode == ReturnCodeSuccess || !ok { haveAppId := msg["appid"] wantAppId := srv.AppId() if wantAppId != "" && !security.SecureCompareString(haveAppId, wantAppId) { err = fmt.Errorf("the message's appid mismatch, have: %s, want: %s", haveAppId, wantAppId) errHandler.ServeError(w, r, err) return } haveMchId := msg["mch_id"] wantMchId := srv.MchId() if wantMchId != "" && !security.SecureCompareString(haveMchId, wantMchId) { err = fmt.Errorf("the message's mch_id mismatch, have: %s, want: %s", haveMchId, wantMchId) errHandler.ServeError(w, r, err) return } // 认证签名 signature1, ok := msg["sign"] if !ok { err = errors.New("no sign parameter") errHandler.ServeError(w, r, err) return } signature2 := Sign(msg, srv.APIKey(), nil) if !security.SecureCompareString(signature1, signature2) { err = fmt.Errorf("check signature failed, \r\ninput: %q, \r\nlocal: %q", signature1, signature2) errHandler.ServeError(w, r, err) return } } req := &Request{ HttpRequest: r, RawMsgXML: RawMsgXML, Msg: msg, } srv.MessageHandler().ServeMessage(w, req) default: errHandler.ServeError(w, r, errors.New("Not expect Request.Method: "+r.Method)) } }
func DecodeXMLHttpResponse(r io.Reader) (map[string]string, error) { body, err := ioutil.ReadAll(r) if err != nil { return nil, err } log.Printf("[WECHAT_DEBUG] [MCH] [API] http response body:\n%s\n", body) return util.DecodeXMLToMap(bytes.NewReader(body)) }
func DecodeXMLHttpResponse(r io.Reader) (map[string]string, error) { return util.DecodeXMLToMap(r) }
// 微信支付通用请求方法. // 注意: err == nil 表示协议状态都为 SUCCESS(return_code == SUCCESS). func (pxy *Proxy) PostXML(url string, req map[string]string) (resp map[string]string, err error) { bodyBuf := textBufferPool.Get().(*bytes.Buffer) bodyBuf.Reset() defer textBufferPool.Put(bodyBuf) if err = util.EncodeXMLFromMap(bodyBuf, req, "xml"); err != nil { return } httpResp, err := pxy.httpClient.Post(url, "text/xml; charset=utf-8", bodyBuf) if err != nil { return } defer httpResp.Body.Close() if httpResp.StatusCode != http.StatusOK { err = fmt.Errorf("http.Status: %s", httpResp.Status) return } if resp, err = util.DecodeXMLToMap(httpResp.Body); err != nil { return } // 判断协议状态 ReturnCode, ok := resp["return_code"] if !ok { err = errors.New("no return_code parameter") return } if ReturnCode != ReturnCodeSuccess { err = &Error{ ReturnCode: ReturnCode, ReturnMsg: resp["return_msg"], } return } // 安全考虑, 做下验证 appId, ok := resp["appid"] if ok && appId != pxy.appId { err = fmt.Errorf("appid mismatch, have: %q, want: %q", appId, pxy.appId) return } mchId, ok := resp["mch_id"] if ok && mchId != pxy.mchId { err = fmt.Errorf("mch_id mismatch, have: %q, want: %q", mchId, pxy.mchId) return } // 认证签名 signature1, ok := resp["sign"] if !ok { err = errors.New("no sign parameter") return } signature2 := Sign(resp, pxy.apiKey, nil) if signature1 != signature2 { err = fmt.Errorf("check signature failed, \r\ninput: %q, \r\nlocal: %q", signature1, signature2) return } return }
// ServeHTTP 处理微信服务器的回调请求, queryParams 参数可以为 nil. func (srv *Server) ServeHTTP(w http.ResponseWriter, r *http.Request, queryParams url.Values) { callback.DebugPrintRequest(r) errorHandler := srv.errorHandler switch r.Method { case "POST": requestBody, err := ioutil.ReadAll(r.Body) if err != nil { errorHandler.ServeError(w, r, err) return } callback.DebugPrintRequestMessage(requestBody) msg, err := util.DecodeXMLToMap(bytes.NewReader(requestBody)) if err != nil { errorHandler.ServeError(w, r, err) return } returnCode, ok := msg["return_code"] if returnCode == ReturnCodeSuccess || !ok { haveAppId := msg["appid"] wantAppId := srv.appId if haveAppId != "" && wantAppId != "" && !security.SecureCompareString(haveAppId, wantAppId) { err = fmt.Errorf("appid mismatch, have: %s, want: %s", haveAppId, wantAppId) errorHandler.ServeError(w, r, err) return } haveMchId := msg["mch_id"] wantMchId := srv.mchId if haveMchId != "" && wantMchId != "" && !security.SecureCompareString(haveMchId, wantMchId) { err = fmt.Errorf("mch_id mismatch, have: %s, want: %s", haveMchId, wantMchId) errorHandler.ServeError(w, r, err) return } // 认证签名 haveSignature, ok := msg["sign"] if !ok { err = ErrNotFoundSign errorHandler.ServeError(w, r, err) return } wantSignature := Sign(msg, srv.apiKey, nil) if !security.SecureCompareString(haveSignature, wantSignature) { err = fmt.Errorf("sign mismatch,\nhave: %s,\nwant: %s", haveSignature, wantSignature) errorHandler.ServeError(w, r, err) return } } ctx := &Context{ Server: srv, ResponseWriter: w, Request: r, RequestBody: requestBody, Msg: msg, handlerIndex: initHandlerIndex, } srv.handler.ServeMsg(ctx) default: errorHandler.ServeError(w, r, errors.New("Unexpected HTTP Method: "+r.Method)) } }