Example #1
0
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))
	}
}
Example #2
0
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))
}
Example #3
0
func DecodeXMLHttpResponse(r io.Reader) (map[string]string, error) {
	return util.DecodeXMLToMap(r)
}
Example #4
0
// 微信支付通用请求方法.
//  注意: 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
}
Example #5
0
// 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))
	}
}