| | |
| | | |
| | | 国标28181的api |
| | | |
| | | API:gb28181Api.go |
| | | 传输:httpClient.go |
| | | 使用接口前需要执行Init(),指定ip+port |
| New file |
| | |
| | | package gb28181api |
| | | |
| | | import ( |
| | | "fmt" |
| | | "testing" |
| | | ) |
| | | |
| | | func TestSetPlatformServerInfo(t *testing.T) { |
| | | var api Gb28181Api |
| | | var gbserverinfo = GbServerInfo{ |
| | | Name: "测试国标平台", |
| | | PublicID: "44120000002000000011", |
| | | GbServerPort: 7060, |
| | | RtspServrPort: 7554, |
| | | HTTPClientIP: "", |
| | | HTTPClientPort: 0, |
| | | } |
| | | Init("192.168.1.203", 8060) |
| | | flag := api.SetPlatformServerInfo(gbserverinfo) |
| | | fmt.Println(flag) |
| | | } |
| | | |
| | | func TestGetPlatformServerInfo(t *testing.T) { |
| | | var api Gb28181Api |
| | | Init("192.168.1.203", 8060) |
| | | gbserverinfo, flag := api.GetPlatformServerInfo() |
| | | fmt.Println("flag:", flag) |
| | | fmt.Println("gbserverinfo:", SmartPrintStruct(gbserverinfo)) |
| | | } |
| | | |
| | | func TestGetDevicesByPageNO(t *testing.T) { |
| | | var api Gb28181Api |
| | | Init("192.168.1.203", 8060) |
| | | devsinfo, flag := api.GetDevicesByPageNO(1) |
| | | fmt.Println("flag:", flag) |
| | | fmt.Println("devsinfo:", SmartPrintStruct(devsinfo)) |
| | | } |
| | | |
| | | func TestGetAllDevices(t *testing.T) { |
| | | var api Gb28181Api |
| | | Init("192.168.1.203", 8060) |
| | | alldevsinfo, flag := api.GetAllDevices() |
| | | fmt.Println("flag:", flag) |
| | | fmt.Println("alldevsinfo:", SmartPrintStruct(alldevsinfo)) |
| | | } |
| | | |
| | | func TestGetCamsByDevAndPage(t *testing.T) { |
| | | var api Gb28181Api |
| | | Init("192.168.1.203", 8060) |
| | | camsinfo, flag := api.GetCamsByDevAndPage("44122500042001000123", "all", 1) |
| | | fmt.Println("flag:", flag) |
| | | fmt.Println("camsinfo:", SmartPrintStruct(camsinfo)) |
| | | } |
| | | |
| | | func TestGetAllCamerasByDevID(t *testing.T) { |
| | | var api Gb28181Api |
| | | Init("192.168.1.203", 8060) |
| | | allcamsinfo, flag := api.GetAllCamerasByDevID("44122500042001000123") |
| | | fmt.Println("flag:", flag) |
| | | fmt.Println("allcamsinfo:", SmartPrintStruct(allcamsinfo)) |
| | | } |
| | | |
| | | func TestSetCameraPtz(t *testing.T) { |
| | | var api Gb28181Api |
| | | Init("192.168.1.203", 8060) |
| | | flag := api.SetCameraPtz("11010202081314000004", "focusnear", 150) |
| | | fmt.Println("flag:", flag) |
| | | } |
| New file |
| | |
| | | package gb28181api |
| | | |
| | | import ( |
| | | "strconv" |
| | | ) |
| | | |
| | | type Client interface { |
| | | //GET |
| | | DoGetRequest(url string, params map[string]string, headers map[string]string) ([]byte, error) |
| | | //POST |
| | | DoPostRequest(url string, contentType string, body map[string]interface{}, params map[string]string, headers map[string]string) ([]byte, error) |
| | | //PUT |
| | | DoPutRequest(url string, contentType string, body map[string]interface{}, headers map[string]string) ([]byte, error) |
| | | //DELETE |
| | | DoDeleteRequest(url string, contentType string, body map[string]interface{}, headers map[string]string) ([]byte, error) |
| | | } |
| | | |
| | | var BASIC_URL = "http://192.168.1.203:8060" |
| | | |
| | | const ( |
| | | DATA_URL_PREFIX = "/vssconfig" |
| | | CONTENT_TYPE_FORM = "application/x-www-form-urlencoded" |
| | | CONTENT_TYPE_MULFORM = "multipart/form-data" |
| | | CONTENT_TYPE_JSON = "application/json" |
| | | ) |
| | | |
| | | //初始化dbserver的地址和端口 |
| | | func Init(ip string, port int) { |
| | | BASIC_URL = "http://" + ip + ":" + strconv.Itoa(port) |
| | | } |
| New file |
| | |
| | | package gb28181api |
| | | |
| | | //Factory new client |
| | | func NewClient() Client { |
| | | var client Client |
| | | client = &HttpClient{} |
| | | //client = &ReqRepClient{} |
| | | return client |
| | | } |
| New file |
| | |
| | | package gb28181api |
| | | |
| | | //GbServerInfo 国标平台信息 |
| | | type GbServerInfo struct { |
| | | Name string `json:"name"` //国标平台的名称 |
| | | PublicID string `json:"publicid"` //国标平台的20位ID (200类型) |
| | | GbServerPort int `json:"gbserverport"` //国标平台监听的端口 |
| | | RtspServrPort int `json:"rtspservrport"` //RTSP服务的端口 |
| | | HTTPClientIP string `json:"httpclientip"` //HTTP客户端的ip(用于报警通知,一般不设置) |
| | | HTTPClientPort int `json:"httpclientport"` //HTTP客户端的端口(用于报警通知,一般不设置) |
| | | } |
| | | |
| | | //GbResult 返回值信息 |
| | | type GbResult struct { |
| | | ErrCode int `json:"errcode"` |
| | | ErrDesc string `json:"errdesc"` |
| | | } |
| | | |
| | | //DeviceInfo 下级设备信息 |
| | | type DeviceInfo struct { |
| | | PublicID string `json:"publicid"` //(字符串) 国标设备20位id |
| | | Name string `json:"name"` //(字符串) 资源名称 |
| | | Alive int `json:"alive"` //(数字) 状态 0:不在线 1:在线 |
| | | Corp string `json:"corp"` //(字符串) 厂商 |
| | | Parentid string `json:"parentid"` //(字符串) 父节点id |
| | | IP string `json:"ip"` //(字符串) ip地址 |
| | | Port int `json:"port"` //(数字) 端口 |
| | | Username string `json:"username"` //(字符串) 设备注册用户名 |
| | | Passwd string `json:"passwd"` //(字符串) 设备注册密码 |
| | | Devmode string `json:"devmode"` //(字符串) 设备类型 |
| | | } |
| | | |
| | | //DevicesInOnePage 一页的下级设备信息 |
| | | type DevicesInOnePage struct { |
| | | GbResult |
| | | TotalSize int `json:"totalsize"` //(数字) 设备总数 (下同) |
| | | OnePageSize int `json:"onepagesize"` //(数字) 每页大小 (下同) |
| | | TotalPage int `json:"totalpage"` //(数字) 总分页数 (下同) |
| | | PageNO int `json:"pageno"` //(数字) 当前第几页(下同) |
| | | Count int `json:"count"` //(数字) 当前有几条数据(下同) |
| | | Data []DeviceInfo `json:"data"` //设备信息,参照“1.设备管理”定义 |
| | | } |
| | | |
| | | //CameraInfo 摄像机信息 |
| | | type CameraInfo struct { |
| | | ResType int `json:"restype"` //(数字) 1-通道资源 2-资源组 |
| | | PublicID string `json:"publicid"` //(字符串) 国标资源通道20位id (用于请求视频、控制等操作) |
| | | Name string `json:"name"` //(字符串) 资源名称 |
| | | Alive int `json:"alive"` //(数字) 状态 0:不在线 1:在线 |
| | | Corp string `json:"corp"` //(字符串) 厂商 |
| | | Model string `json:"model"` //(字符串) 设备类型 |
| | | Owner string `json:"owner"` //(字符串) 设备归属 |
| | | CivilCode string `json:"civilcode"` //(字符串) 行政区域 (可以按照行政区域进行划分资源组) |
| | | Address string `json:"address"` //(字符串) 地址 |
| | | DevPubID string `json:"devpubid"` //(字符串) 通道的设备id |
| | | ParentID string `json:"parentid"` //(字符串) 父节点id |
| | | IP string `json:"ip"` //(字符串) ip地址 |
| | | Port int `json:"port"` //(数字) 端口 |
| | | Longitude float64 `json:"longitude"` //(数字) 经度 |
| | | Latitude float64 `json:"latitude"` //(数字) 纬度 |
| | | PtzType int `json:"ptztype"` //(数字) 控制类型 1-球机;2-半球;3-固定枪机;4-遥控枪机; |
| | | StreamType int `json:"streamtype"` //(数字) 码流类型 0-H264;1-MPEG2;2-MPEG4;3-SVAC;4-3GP;5-H265; |
| | | RealRtspURL string `json:"realrtspurl"` //(字符串) 实时视频的rtsp地址 |
| | | } |
| | | |
| | | //CamerasInOnePage 一页的摄像机信息 |
| | | type CamerasInOnePage struct { |
| | | GbResult |
| | | TotalSize int `json:"totalsize"` //(数字) 设备总数 (下同) |
| | | OnePageSize int `json:"onepagesize"` //(数字) 每页大小 (下同) |
| | | TotalPage int `json:"totalpage"` //(数字) 总分页数 (下同) |
| | | PageNO int `json:"pageno"` //(数字) 当前第几页(下同) |
| | | Count int `json:"count"` //(数字) 当前有几条数据(下同) |
| | | Data []CameraInfo `json:"data"` //设备信息,参照“1.设备管理”定义 |
| | | } |
| New file |
| | |
| | | package gb28181api |
| | | |
| | | import ( |
| | | "bytes" |
| | | "encoding/json" |
| | | "fmt" |
| | | "strconv" |
| | | ) |
| | | |
| | | func SmartPrintStruct(src interface{}) string { |
| | | b, err := json.Marshal(src) |
| | | if err != nil { |
| | | return fmt.Sprintf("%+v", src) |
| | | } |
| | | var out bytes.Buffer |
| | | err = json.Indent(&out, b, "", " ") |
| | | if err != nil { |
| | | return fmt.Sprintf("%+v", src) |
| | | } |
| | | return out.String() |
| | | } |
| | | |
| | | type Gb28181Api struct{} |
| | | |
| | | //SetPlatformServerInfo 设置服务器信息 |
| | | func (api Gb28181Api) SetPlatformServerInfo(serverInfo GbServerInfo) bool { |
| | | url := BASIC_URL + DATA_URL_PREFIX + "/set_platform_server" |
| | | client := NewClient() |
| | | |
| | | paramBody := make(map[string]string, 0) |
| | | paramBody["gbsvrid"] = serverInfo.PublicID |
| | | paramBody["gbsvrport"] = strconv.Itoa(serverInfo.GbServerPort) |
| | | paramBody["gbsvrname"] = serverInfo.Name |
| | | paramBody["rtspsvrport"] = strconv.Itoa(serverInfo.RtspServrPort) |
| | | |
| | | // fmt.Println("url:", url) |
| | | body, err := client.DoGetRequest(url, paramBody, nil) |
| | | if err != nil { |
| | | return false |
| | | } |
| | | |
| | | var res GbResult |
| | | // fmt.Println("body", string(body)) |
| | | if err = json.Unmarshal(body, &res); err != nil { |
| | | fmt.Println("jsonErr:", err) |
| | | return false |
| | | } |
| | | |
| | | if res.ErrCode != 0 { |
| | | fmt.Println("errcode: ", res.ErrCode, " errdesc: ", res.ErrDesc) |
| | | return false |
| | | } |
| | | |
| | | return true |
| | | } |
| | | |
| | | type retGbServerInfo struct { |
| | | GbServerInfo |
| | | GbResult |
| | | } |
| | | |
| | | //GetPlatformServerInfo 获取服务器信息 |
| | | func (api Gb28181Api) GetPlatformServerInfo() (GbServerInfo, bool) { |
| | | url := BASIC_URL + DATA_URL_PREFIX + "/get_platform_server" |
| | | client := NewClient() |
| | | |
| | | var info GbServerInfo |
| | | body, err := client.DoGetRequest(url, nil, nil) |
| | | if err != nil { |
| | | fmt.Println("err:", err) |
| | | return info, false |
| | | } |
| | | |
| | | //解析retGbServerInfo |
| | | var res retGbServerInfo |
| | | if err = json.Unmarshal(body, &res); err != nil { |
| | | fmt.Println("jsonErr:", err) |
| | | return info, false |
| | | } |
| | | if res.ErrCode != 0 { |
| | | fmt.Println("errcode: ", res.ErrCode, " errdesc: ", res.ErrDesc) |
| | | return info, false |
| | | } |
| | | |
| | | return res.GbServerInfo, true |
| | | } |
| | | |
| | | //GetDevicesByPageNO 按页获取下级设备(平台或摄像机)列表 |
| | | //pageNo (数字) 指定获取第几页,第一次为1,返回总页数,总条数等,再根据这些信息去再次查询,直到取完全部 |
| | | func (api Gb28181Api) GetDevicesByPageNO(pageNo int) (DevicesInOnePage, bool) { |
| | | url := BASIC_URL + DATA_URL_PREFIX + "/get_all_device/" + strconv.Itoa(pageNo) |
| | | client := NewClient() |
| | | |
| | | var devicesPerPage DevicesInOnePage |
| | | body, err := client.DoGetRequest(url, nil, nil) |
| | | if err != nil { |
| | | fmt.Println("err:", err) |
| | | return devicesPerPage, false |
| | | } |
| | | |
| | | //解析 DevicesInOnePage |
| | | if err = json.Unmarshal(body, &devicesPerPage); err != nil { |
| | | fmt.Println("jsonErr:", err) |
| | | return devicesPerPage, false |
| | | } |
| | | if devicesPerPage.ErrCode != 0 { |
| | | fmt.Println("errcode: ", devicesPerPage.ErrCode, " errdesc: ", devicesPerPage.ErrDesc) |
| | | return devicesPerPage, false |
| | | } |
| | | |
| | | return devicesPerPage, true |
| | | } |
| | | |
| | | //GetAllDevices 获取全部下级设备(平台或摄像机)信息列表 |
| | | func (api Gb28181Api) GetAllDevices() ([]DeviceInfo, bool) { |
| | | var deviceSlice []DeviceInfo |
| | | devicesPerPage, flag := api.GetDevicesByPageNO(1) |
| | | if !flag { |
| | | fmt.Println("GetDevicesByPageNO Error, deviceSlice is nil") |
| | | return deviceSlice, false |
| | | } |
| | | deviceSlice = devicesPerPage.Data |
| | | |
| | | for i := 1; i < devicesPerPage.TotalPage; i++ { |
| | | devicesPerPage, flag := api.GetDevicesByPageNO(i + 1) |
| | | if !flag { |
| | | fmt.Println("GetDevicesByPageNO Error,pageno:" + strconv.Itoa(i+1) + " ,deviceSlice is not completed") |
| | | return deviceSlice, false |
| | | } |
| | | deviceSlice = append(deviceSlice, devicesPerPage.Data...) |
| | | } |
| | | |
| | | return deviceSlice, true |
| | | } |
| | | |
| | | //GetCamsByDevAndPage 按页获取下级设备的摄像机列表 |
| | | //devID (字符串) 注册的设备的20位id |
| | | //pageNo (数字) 指定获取第几页,第一次为1,返回总页数,总条数等,再根据这些信息去再次查询,直到取完全部 |
| | | //srcType (字符串) "all"-表示获取设备的所有资源 "node"-父节点下的第一级资源 |
| | | //注意:根据"restype"字段,忽略资源组,只保留通道资源------"restype":(数字)1-通道资源 2-资源组 |
| | | func (api Gb28181Api) GetCamsByDevAndPage(devID string, srcType string, pageNo int) (CamerasInOnePage, bool) { |
| | | url := BASIC_URL + DATA_URL_PREFIX + "/get_all_channel/" + devID + "/" + srcType + "/" + strconv.Itoa(pageNo) |
| | | client := NewClient() |
| | | |
| | | var camerasPerPage CamerasInOnePage |
| | | body, err := client.DoGetRequest(url, nil, nil) |
| | | if err != nil { |
| | | fmt.Println("err:", err) |
| | | return camerasPerPage, false |
| | | } |
| | | |
| | | //解析 CamerasInOnePage |
| | | if err = json.Unmarshal(body, &camerasPerPage); err != nil { |
| | | fmt.Println("jsonErr:", err) |
| | | return camerasPerPage, false |
| | | } |
| | | if camerasPerPage.ErrCode != 0 { |
| | | fmt.Println("errcode: ", camerasPerPage.ErrCode, " errdesc: ", camerasPerPage.ErrDesc) |
| | | return camerasPerPage, false |
| | | } |
| | | |
| | | if len(camerasPerPage.Data) > 0 { |
| | | for i, v := range camerasPerPage.Data { |
| | | if v.ResType == 2 { |
| | | fmt.Println("v.restype == 2") |
| | | camerasPerPage.Data = append(camerasPerPage.Data[:i], camerasPerPage.Data[i+1:]...) |
| | | } |
| | | } |
| | | } |
| | | |
| | | return camerasPerPage, true |
| | | } |
| | | |
| | | //GetAllCamerasByDevID 获取全部下级设备的摄像机列表 |
| | | //devID (字符串) 注册的设备的20位id |
| | | func (api Gb28181Api) GetAllCamerasByDevID(devID string) ([]CameraInfo, bool) { |
| | | var cameraSlice []CameraInfo |
| | | camerasPerPage, flag := api.GetCamsByDevAndPage(devID, "all", 1) |
| | | if !flag { |
| | | fmt.Println("GetCamsByDevAndPage Error, deviceSlice is nil") |
| | | return cameraSlice, false |
| | | } |
| | | cameraSlice = camerasPerPage.Data |
| | | |
| | | for i := 1; i < camerasPerPage.TotalPage; i++ { |
| | | camerasPerPage, flag := api.GetCamsByDevAndPage(devID, "all", i+1) |
| | | if !flag { |
| | | fmt.Println("GetCamsByDevAndPage Error! devID:" + devID + ",type:all,pageno:" + strconv.Itoa(i+1) + " ,cameraSlice is not completed") |
| | | return cameraSlice, false |
| | | } |
| | | cameraSlice = append(cameraSlice, camerasPerPage.Data...) |
| | | } |
| | | |
| | | return cameraSlice, true |
| | | } |
| | | |
| | | //SetCameraPtz 2.3 PTZ云台控制 |
| | | //"channelid": (字符串) 通道20位编号 |
| | | //"ptztype": (字符串) 控制类型:上"up",下"down",左"left",右"right",左上"leftup",左下"leftdown",右上"rightup",右下"rightdown",镜头近"zoomin",镜头远"zoomout", |
| | | // 焦距远"focusfar",焦距近"focusnear", 设置预置位"setpos",调预置位"callpos",停止"stop" |
| | | //"ptzparam": (数字) 参数,速度范围为1-255 |
| | | func (api Gb28181Api) SetCameraPtz(chanID string, ptzType string, ptzParam int) bool { |
| | | url := BASIC_URL + "/vss/ptz/" + ptzType + "/" + strconv.Itoa(ptzParam) + "/" + chanID |
| | | client := NewClient() |
| | | |
| | | body, err := client.DoGetRequest(url, nil, nil) |
| | | if err != nil { |
| | | fmt.Println("err:", err) |
| | | return false |
| | | } |
| | | |
| | | //解析 CamerasInOnePage |
| | | var res GbResult |
| | | if err = json.Unmarshal(body, &res); err != nil { |
| | | fmt.Println("jsonErr:", err) |
| | | return false |
| | | } |
| | | if res.ErrCode != 0 { |
| | | fmt.Println("errcode: ", res.ErrCode, " errdesc: ", res.ErrDesc) |
| | | return false |
| | | } |
| | | |
| | | return true |
| | | } |
| New file |
| | |
| | | package gb28181api |
| | | |
| | | import ( |
| | | "bytes" |
| | | "encoding/json" |
| | | "io/ioutil" |
| | | "log" |
| | | "net/http" |
| | | ) |
| | | |
| | | type HttpClient struct{} |
| | | |
| | | //发起GET请求 |
| | | func (httpApi HttpClient) DoGetRequest(url string, params map[string]string, headers map[string]string) ([]byte, error) { |
| | | var body []byte |
| | | request, err := http.NewRequest("GET", url, nil) |
| | | if err != nil { |
| | | return body, err |
| | | } |
| | | // add params |
| | | query := request.URL.Query() |
| | | if params != nil { |
| | | for key, val := range params { |
| | | query.Add(key, val) |
| | | } |
| | | request.URL.RawQuery = query.Encode() |
| | | } |
| | | //add headers |
| | | client := &http.Client{} |
| | | resp, err := client.Do(request) |
| | | if err != nil { |
| | | return body, err |
| | | } |
| | | defer resp.Body.Close() |
| | | body, err = ioutil.ReadAll(resp.Body) |
| | | if err != nil { |
| | | return body, err |
| | | } |
| | | return body, nil |
| | | } |
| | | |
| | | //发起POST请求 |
| | | func (httpApi HttpClient) DoPostRequest(url string, contentType string, body map[string]interface{}, params map[string]string, headers map[string]string) ([]byte, error) { |
| | | var resultBytes []byte |
| | | var bodyJson []byte |
| | | if body != nil { |
| | | var err error |
| | | bodyJson, err = json.Marshal(body) |
| | | if err != nil { |
| | | return resultBytes, err |
| | | } |
| | | } |
| | | request, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyJson)) |
| | | if err != nil { |
| | | return resultBytes, err |
| | | } |
| | | request.Header.Set("Content-type", contentType) |
| | | //add params |
| | | q := request.URL.Query() |
| | | if params != nil { |
| | | for key, val := range params { |
| | | q.Add(key, val) |
| | | } |
| | | request.URL.RawQuery = q.Encode() |
| | | } |
| | | // add headers |
| | | if headers != nil { |
| | | for key, val := range headers { |
| | | request.Header.Add(key, val) |
| | | } |
| | | } |
| | | client := &http.Client{} |
| | | resp, err := client.Do(request) |
| | | if err != nil { |
| | | return resultBytes, err |
| | | } |
| | | defer resp.Body.Close() |
| | | resultBytes, err = ioutil.ReadAll(resp.Body) |
| | | if err != nil { |
| | | return resultBytes, err |
| | | } |
| | | return resultBytes, nil |
| | | } |
| | | |
| | | //构造put请求 |
| | | func (httpApi HttpClient) DoPutRequest(url string, contentType string, body map[string]interface{}, headers map[string]string) ([]byte, error) { |
| | | var resultBytes []byte |
| | | var bodyJson []byte |
| | | if body != nil { |
| | | var err error |
| | | bodyJson, err = json.Marshal(body) |
| | | if err != nil { |
| | | return resultBytes, err |
| | | } |
| | | } |
| | | request, err := http.NewRequest("PUT", url, bytes.NewBuffer(bodyJson)) |
| | | if err != nil { |
| | | log.Println(err) |
| | | return resultBytes, err |
| | | } |
| | | request.Header.Set("Content-type", contentType) |
| | | // add headers |
| | | if headers != nil { |
| | | for key, val := range headers { |
| | | request.Header.Add(key, val) |
| | | } |
| | | } |
| | | client := &http.Client{} |
| | | resp, err := client.Do(request) |
| | | if err != nil { |
| | | return resultBytes, err |
| | | } |
| | | defer resp.Body.Close() |
| | | resultBytes, err = ioutil.ReadAll(resp.Body) |
| | | if err != nil { |
| | | return resultBytes, err |
| | | } |
| | | return resultBytes, nil |
| | | } |
| | | |
| | | //构造delete请求 |
| | | func (httpApi HttpClient) DoDeleteRequest(url string, contentType string, body map[string]interface{}, headers map[string]string) ([]byte, error) { |
| | | var resultBytes []byte |
| | | var bodyJson []byte |
| | | if body != nil { |
| | | var err error |
| | | bodyJson, err = json.Marshal(body) |
| | | if err != nil { |
| | | return resultBytes, err |
| | | } |
| | | } |
| | | request, err := http.NewRequest("DELETE", url, bytes.NewBuffer(bodyJson)) |
| | | if err != nil { |
| | | log.Println(err) |
| | | return resultBytes, err |
| | | } |
| | | request.Header.Set("Content-type", contentType) |
| | | // add headers |
| | | if headers != nil { |
| | | for key, val := range headers { |
| | | request.Header.Add(key, val) |
| | | } |
| | | } |
| | | client := &http.Client{} |
| | | resp, err := client.Do(request) |
| | | if err != nil { |
| | | return resultBytes, err |
| | | } |
| | | defer resp.Body.Close() |
| | | resultBytes, err = ioutil.ReadAll(resp.Body) |
| | | if err != nil { |
| | | return resultBytes, err |
| | | } |
| | | return resultBytes, nil |
| | | } |