mirror of
https://github.com/kerberos-io/onvif.git
synced 2025-10-20 22:39:58 +08:00
api: error processing
This commit is contained in:
@@ -32,7 +32,7 @@ type wsAuth struct {
|
|||||||
Created string `xml:"wsse:Created"`
|
Created string `xml:"wsse:Created"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSecurity(username, passwd string) security {
|
func NewSecurity(username, passwd string) security {
|
||||||
/** Generating Nonce sequence **/
|
/** Generating Nonce sequence **/
|
||||||
charsToGenerate := 16
|
charsToGenerate := 16
|
||||||
charSet := gostrgen.Lower | gostrgen.Digit
|
charSet := gostrgen.Lower | gostrgen.Digit
|
||||||
|
147
api/api.go
147
api/api.go
@@ -11,10 +11,8 @@ import (
|
|||||||
"github.com/yakovlevdmv/gosoap"
|
"github.com/yakovlevdmv/gosoap"
|
||||||
"github.com/yakovlevdmv/goonvif"
|
"github.com/yakovlevdmv/goonvif"
|
||||||
"github.com/yakovlevdmv/goonvif/networking"
|
"github.com/yakovlevdmv/goonvif/networking"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"encoding/xml"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func RunApi () {
|
func RunApi () {
|
||||||
@@ -23,12 +21,18 @@ func RunApi () {
|
|||||||
router.POST("/:service/:method", func(c *gin.Context) {
|
router.POST("/:service/:method", func(c *gin.Context) {
|
||||||
serviceName := c.Param("service")
|
serviceName := c.Param("service")
|
||||||
methodName := c.Param("method")
|
methodName := c.Param("method")
|
||||||
|
//todo: login, pass, deviceXaddr
|
||||||
acceptedData, err := c.GetRawData()
|
acceptedData, err := c.GetRawData()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
message := callNecessaryMethod(serviceName, methodName, string(acceptedData), "192.168.13.12")
|
|
||||||
c.XML(http.StatusOK, message)
|
message, err := callNecessaryMethod(serviceName, methodName, string(acceptedData), "192.168.13.12")
|
||||||
|
if err != nil {
|
||||||
|
c.XML(http.StatusBadRequest, err.Error())
|
||||||
|
} else {
|
||||||
|
c.XML(http.StatusOK, message)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
router.Run()
|
router.Run()
|
||||||
}
|
}
|
||||||
@@ -53,65 +57,53 @@ func RunApi () {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
func callNecessaryMethod(serviceName string, methodName string, acceptedData string, deviceXaddr string) string {
|
func callNecessaryMethod(serviceName string, methodName string, acceptedData string, deviceXaddr string) (string, error) {
|
||||||
var methodStruct interface{}
|
var methodStruct interface{}
|
||||||
var err error
|
var err error
|
||||||
switch serviceName {
|
|
||||||
case "Device", "device":
|
switch strings.ToLower(serviceName) {
|
||||||
|
case "device":
|
||||||
methodStruct, err = GetDeviceStructByName(methodName)
|
methodStruct, err = GetDeviceStructByName(methodName)
|
||||||
case "PTZ", "ptz":
|
case "ptz":
|
||||||
methodStruct, err = GetPTZStructByName(methodName)
|
methodStruct, err = GetPTZStructByName(methodName)
|
||||||
|
//todo: ошибка: неподдерживаемый сервис
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil { //done
|
||||||
//todo: нормально написать
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := xmlAnalize(methodStruct, &acceptedData)
|
resp, err := xmlAnalize(methodStruct, &acceptedData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//todo: нормально написать
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint, err := getEndpoint(serviceName, deviceXaddr)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
soap := gosoap.NewEmptySOAP()
|
soap := gosoap.NewEmptySOAP()
|
||||||
soap.AddStringBodyContent(*resp)
|
soap.AddStringBodyContent(*resp)
|
||||||
soap.AddRootNamespaces(goonvif.Xlmns)
|
soap.AddRootNamespaces(goonvif.Xlmns)
|
||||||
|
soap.AddWSSecurity("admin", "Supervisor")
|
||||||
|
|
||||||
/*
|
servResp, err := networking.SendSoap(endpoint, soap.String())
|
||||||
Getting an WS-Security struct representation
|
if err != nil {
|
||||||
*/
|
return "", err
|
||||||
auth := goonvif.NewSecurity("admin", "Supervisor")
|
|
||||||
|
|
||||||
/*
|
|
||||||
Adding WS-Security namespaces to root element of SOAP message
|
|
||||||
*/
|
|
||||||
soap.AddRootNamespace("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext1.0.xsd")
|
|
||||||
soap.AddRootNamespace("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility1.0.xsd")
|
|
||||||
|
|
||||||
soapReq, err := xml.MarshalIndent(auth, "", " ")
|
|
||||||
|
|
||||||
/*
|
|
||||||
Adding WS-Security struct to SOAP header
|
|
||||||
*/
|
|
||||||
soap.AddStringHeaderContent(string(soapReq))
|
|
||||||
|
|
||||||
endpoint:= getEndpoint(serviceName, deviceXaddr)
|
|
||||||
servResp, srvErr := networking.SendSoap(endpoint, soap.String())
|
|
||||||
if srvErr != nil {
|
|
||||||
panic(srvErr)
|
|
||||||
//todo: нормально написать
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rsp, err := ioutil.ReadAll(servResp.Body)
|
rsp, err := ioutil.ReadAll(servResp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
return "", err
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
return string(rsp)
|
|
||||||
|
return string(rsp), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getEndpoint(service, xaddr string) string {
|
func getEndpoint(service, xaddr string) (string, error) {
|
||||||
dev, err := goonvif.NewDevice(xaddr)
|
dev, err := goonvif.NewDevice(xaddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
return "", err
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
pkg := strings.ToLower(service)
|
pkg := strings.ToLower(service)
|
||||||
|
|
||||||
@@ -123,48 +115,35 @@ func getEndpoint(service, xaddr string) string {
|
|||||||
case "media": endpoint = dev.GetEndpoint("Media")
|
case "media": endpoint = dev.GetEndpoint("Media")
|
||||||
case "ptz": endpoint = dev.GetEndpoint("PTZ")
|
case "ptz": endpoint = dev.GetEndpoint("PTZ")
|
||||||
}
|
}
|
||||||
return endpoint
|
return endpoint, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
NEW
|
|
||||||
*/
|
|
||||||
|
|
||||||
func xmlAnalize(methodStruct interface{}, acceptedData* string) (*string, error) {
|
func xmlAnalize(methodStruct interface{}, acceptedData* string) (*string, error) {
|
||||||
test := make([]map[string]string, 0) //tags
|
test := make([]map[string]string, 0) //tags
|
||||||
testunMarshal := make([][]interface{}, 0) //data
|
testunMarshal := make([][]interface{}, 0) //data
|
||||||
//tmp, err := GetPTZStructByName("Stop")
|
var mas []string //idnt
|
||||||
//if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
//}
|
|
||||||
|
|
||||||
soapHandling(methodStruct, &test)
|
soapHandling(methodStruct, &test)
|
||||||
test = mapProcessing(test)
|
test = mapProcessing(test)
|
||||||
|
|
||||||
doc := etree.NewDocument()
|
doc := etree.NewDocument()
|
||||||
if err := doc.ReadFromString(*acceptedData); err != nil {
|
if err := doc.ReadFromString(*acceptedData); err != nil {
|
||||||
fmt.Println(err)
|
return nil, err
|
||||||
return nil, nil //todo: нормально написать
|
|
||||||
}
|
}
|
||||||
etr := doc.FindElements("./*")
|
etr := doc.FindElements("./*")
|
||||||
xmlUnmarshal(etr, &testunMarshal)
|
xmlUnmarshal(etr, &testunMarshal, &mas)
|
||||||
|
|
||||||
etr_ := doc.FindElements("./*")
|
|
||||||
var mas []string //idnt
|
|
||||||
getPos(etr_, &mas)
|
|
||||||
ident(&mas)
|
ident(&mas)
|
||||||
|
|
||||||
//todo: может возникнуть проблема с типами данных без тегов. От таких типов надо избавляться
|
|
||||||
//todo: попробовать всунуть все вызовы (soapHandling, xmlUnmarshal)сюда
|
|
||||||
|
|
||||||
|
|
||||||
document:= etree.NewDocument()
|
document:= etree.NewDocument()
|
||||||
var el *etree.Element
|
var el *etree.Element
|
||||||
var idntIndex = 0
|
var idntIndex = 0
|
||||||
|
|
||||||
for lstIndex := 0; lstIndex < len(testunMarshal); {
|
for lstIndex := 0; lstIndex < len(testunMarshal); {
|
||||||
lst := (testunMarshal)[lstIndex]
|
lst := (testunMarshal)[lstIndex]
|
||||||
elemName, attr, value:= xmlMaker(&lst, &test, lstIndex)
|
elemName, attr, value, err := xmlMaker(&lst, &test, lstIndex)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if mas[lstIndex] == "Push" && lstIndex == 0 { //done
|
if mas[lstIndex] == "Push" && lstIndex == 0 { //done
|
||||||
el = document.CreateElement(elemName)
|
el = document.CreateElement(elemName)
|
||||||
@@ -200,16 +179,16 @@ func xmlAnalize(methodStruct interface{}, acceptedData* string) (*string, error)
|
|||||||
idntIndex += 1
|
idntIndex += 1
|
||||||
lstIndex += 1
|
lstIndex += 1
|
||||||
}
|
}
|
||||||
//document.Indent(2)
|
|
||||||
//fmt.Println(document.WriteToString())
|
|
||||||
resp, err := document.WriteToString()
|
resp, err := document.WriteToString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//todo нормально расписать
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &resp, err
|
return &resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func xmlMaker(lst* []interface{}, tags* []map[string]string, lstIndex int) (string, map[string]string, string) {
|
func xmlMaker(lst* []interface{}, tags* []map[string]string, lstIndex int) (string, map[string]string, string, error) {
|
||||||
var elemName, value string
|
var elemName, value string
|
||||||
attr := make(map[string]string)
|
attr := make(map[string]string)
|
||||||
for tgIndx, tg := range *tags {
|
for tgIndx, tg := range *tags {
|
||||||
@@ -225,13 +204,13 @@ func xmlMaker(lst* []interface{}, tags* []map[string]string, lstIndex int) (stri
|
|||||||
if index == 0 && lstIndex == 0 {
|
if index == 0 && lstIndex == 0 {
|
||||||
res, err := xmlProcessing(tg["XMLName"])
|
res, err := xmlProcessing(tg["XMLName"])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
return "", nil, "", err
|
||||||
}
|
}
|
||||||
elemName = res
|
elemName = res
|
||||||
} else if index == 0 {
|
} else if index == 0 {
|
||||||
res, err := xmlProcessing(tg[conversion])
|
res, err := xmlProcessing(tg[conversion])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
return "", nil, "", err
|
||||||
}
|
}
|
||||||
elemName = res
|
elemName = res
|
||||||
} else {
|
} else {
|
||||||
@@ -241,7 +220,7 @@ func xmlMaker(lst* []interface{}, tags* []map[string]string, lstIndex int) (stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return elemName, attr, value
|
return elemName, attr, value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func xmlProcessing (tg string) (string, error) {
|
func xmlProcessing (tg string) (string, error) {
|
||||||
@@ -252,13 +231,21 @@ func xmlProcessing (tg string) (string, error) {
|
|||||||
}
|
}
|
||||||
attr := strings.Index(str[1], ",attr")
|
attr := strings.Index(str[1], ",attr")
|
||||||
omit := strings.Index(str[1], ",omitempty")
|
omit := strings.Index(str[1], ",omitempty")
|
||||||
if attr == -1 && omit == -1 { //todo: проработать вариант, когдв omitempty и attr вместе
|
attrOmit := strings.Index(str[1], ",attr,omitempty")
|
||||||
return str[1], nil
|
omitAttr := strings.Index(str[1], ",omitempty,attr")
|
||||||
} else if omit > -1 {
|
|
||||||
|
if attr > -1 && attrOmit == -1 && omitAttr == -1 {
|
||||||
|
return str[1][0:attr], nil
|
||||||
|
} else if omit > -1 && attrOmit == -1 && omitAttr == -1 {
|
||||||
return str[1][0:omit], nil
|
return str[1][0:omit], nil
|
||||||
}else {
|
} else if attr == -1 && omit == -1 {
|
||||||
return str[0:attr][0], nil
|
return str[1], nil
|
||||||
|
} else if attrOmit > -1 {
|
||||||
|
return str[1][0:attrOmit], nil
|
||||||
|
} else {
|
||||||
|
return str[1][0:omitAttr], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", errors.New("something went wrong")
|
return "", errors.New("something went wrong")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,20 +284,12 @@ func soapHandling(tp interface{}, tags* []map[string]string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: передавать в него отступы
|
|
||||||
func xmlUnmarshal(elems []*etree.Element, data* [][]interface{}) {
|
func xmlUnmarshal(elems []*etree.Element, data* [][]interface{}, mas* []string) {
|
||||||
for _, elem := range elems {
|
for _, elem := range elems {
|
||||||
*data = append(*data, []interface{}{elem.Tag,elem.Attr,elem.Text()})
|
*data = append(*data, []interface{}{elem.Tag,elem.Attr,elem.Text()})
|
||||||
xmlUnmarshal(elem.FindElements("./*"), data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//todo лишняя функция, засунуть в xmlUnmarshal
|
|
||||||
func getPos(elems []*etree.Element, mas* []string) {
|
|
||||||
for _, elem := range elems {
|
|
||||||
*mas = append(*mas, "Push")
|
*mas = append(*mas, "Push")
|
||||||
getPos(elem.FindElements("./*"), mas)
|
xmlUnmarshal(elem.FindElements("./*"), data, mas)
|
||||||
*mas = append(*mas, "Pop")
|
*mas = append(*mas, "Pop")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -65,7 +65,7 @@ func GetPTZStructByName(name string) (interface{}, error) {
|
|||||||
case "GetCompatibleConfigurations":
|
case "GetCompatibleConfigurations":
|
||||||
return &PTZ.GetCompatibleConfigurations{}, nil
|
return &PTZ.GetCompatibleConfigurations{}, nil
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("invalid structure")
|
return nil, errors.New("there is no such method in the PTZ service")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,6 +74,6 @@ func GetDeviceStructByName(name string) (interface{}, error) {
|
|||||||
case "CreateUsers":
|
case "CreateUsers":
|
||||||
return &Device.CreateUsers{}, nil
|
return &Device.CreateUsers{}, nil
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("invalid structure")
|
return nil, errors.New("there is no such method in the Device service")
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user