feat: add cmpp inbound gateway listener

This commit is contained in:
hectorzhao
2026-07-07 16:19:14 +08:00
parent ad3b86ba0a
commit cc628d0214
14 changed files with 631 additions and 17 deletions
+114
View File
@@ -0,0 +1,114 @@
package inbound
import (
"encoding/json"
"net"
"net/http"
"net/http/httptest"
"testing"
"time"
cmpp "github.com/bigwhite/gocmpp"
cmpputils "github.com/bigwhite/gocmpp/utils"
)
func TestInboundServerAuthenticatesAndSubmits(t *testing.T) {
account := "100001"
password := "secret-hash"
var gotAuth authRequest
var gotSubmit submitRequest
api := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/api/gateway/events/inbound/authenticate":
if err := json.NewDecoder(r.Body).Decode(&gotAuth); err != nil {
t.Fatalf("decode auth: %v", err)
}
_ = json.NewEncoder(w).Encode(authResponse{PasswordCipher: password})
case "/api/gateway/events/inbound/submit":
if err := json.NewDecoder(r.Body).Decode(&gotSubmit); err != nil {
t.Fatalf("decode submit: %v", err)
}
_ = json.NewEncoder(w).Encode(submitResponse{Accepted: true, MessageID: "MSG-1"})
default:
t.Fatalf("unexpected api path: %s", r.URL.Path)
}
}))
defer api.Close()
addr := reserveTCPAddr(t)
go func() {
_ = (Server{Addr: addr, APIBaseURL: api.URL + "/api"}).ListenAndServe()
}()
time.Sleep(300 * time.Millisecond)
client := cmpp.NewClient(cmpp.V30)
defer client.Disconnect()
if err := client.Connect(addr, account, password, 2*time.Second); err != nil {
t.Fatalf("connect inbound cmpp: %v", err)
}
content, err := cmpputils.Utf8ToUcs2("测试入站")
if err != nil {
t.Fatalf("encode content: %v", err)
}
_, err = client.SendReqPkt(&cmpp.Cmpp3SubmitReqPkt{
PkTotal: 1,
PkNumber: 1,
RegisteredDelivery: 1,
MsgLevel: 1,
ServiceId: "cmpp",
FeeUserType: 2,
FeeTerminalId: "13500002696",
MsgFmt: 8,
MsgSrc: account,
FeeType: "02",
FeeCode: "0",
SrcId: "10690000",
DestUsrTl: 1,
DestTerminalId: []string{"13500002696"},
MsgLength: uint8(len(content)),
MsgContent: content,
})
if err != nil {
t.Fatalf("send submit: %v", err)
}
rsp := recvSubmitRsp(t, client)
if rsp.Result != 0 || rsp.MsgId == 0 {
t.Fatalf("unexpected submit response: %+v", rsp)
}
if gotAuth.Account != account || gotAuth.AuthSource == "" || gotAuth.RemoteIP == "" {
t.Fatalf("unexpected auth payload: %+v", gotAuth)
}
if gotSubmit.Account != account || gotSubmit.PhoneNumber != "13500002696" || gotSubmit.Content != "测试入站" {
t.Fatalf("unexpected submit payload: %+v", gotSubmit)
}
}
func reserveTCPAddr(t *testing.T) string {
t.Helper()
listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatalf("reserve tcp addr: %v", err)
}
addr := listener.Addr().String()
if err := listener.Close(); err != nil {
t.Fatalf("close reserved listener: %v", err)
}
return addr
}
func recvSubmitRsp(t *testing.T, client *cmpp.Client) *cmpp.Cmpp3SubmitRspPkt {
t.Helper()
deadline := time.Now().Add(2 * time.Second)
for time.Now().Before(deadline) {
packet, err := client.RecvAndUnpackPkt(200 * time.Millisecond)
if err != nil {
continue
}
if rsp, ok := packet.(*cmpp.Cmpp3SubmitRspPkt); ok {
return rsp
}
}
t.Fatal("timed out waiting submit response")
return nil
}