Files
services/ping/handler/ping.go
Asim Aslam 420f0706b0 add a ping service (#372)
* add a ping service

* add examples and public api file

* add minecraft server ping
2022-02-14 15:05:28 +00:00

121 lines
2.4 KiB
Go

package handler
import (
"bufio"
"context"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"github.com/go-ping/ping"
"github.com/micro/micro/v3/service/errors"
"github.com/micro/micro/v3/service/logger"
pb "github.com/micro/services/ping/proto"
)
type Ping struct{}
func (p *Ping) Ip(ctx context.Context, req *pb.IpRequest, rsp *pb.IpResponse) error {
if len(req.Address) == 0 {
return errors.BadRequest("ping.ip", "missing address")
}
pinger, err := ping.NewPinger(req.Address)
if err != nil {
rsp.Status = err.Error()
return nil
}
pinger.Count = 4
pinger.SetPrivileged(true)
err = pinger.Run() // Blocks until finished.
if err != nil {
rsp.Status = err.Error()
return nil
}
pinger.Stop()
stats := pinger.Statistics()
rsp.Status = "OK"
rsp.Latency = fmt.Sprintf("%v", stats.AvgRtt)
return nil
}
func (p *Ping) Url(ctx context.Context, req *pb.UrlRequest, rsp *pb.UrlResponse) error {
if len(req.Address) == 0 {
return errors.BadRequest("ping.url", "missing address")
}
u, err := url.Parse(req.Address)
if err != nil {
return errors.BadRequest("ping.url", "failed to parse url: %v", err)
}
if u.Scheme == "" {
u.Scheme = "https"
}
if req.Method == "" {
req.Method = "GET"
}
logger.Infof("Calling %s %s", req.Method, u.String())
hreq, err := http.NewRequest(req.Method, u.String(), nil)
if err != nil {
return errors.InternalServerError("ping.url", "failed to make request: %v", err)
}
resp, err := http.DefaultClient.Do(hreq)
if err != nil {
return errors.InternalServerError("ping.url", "failed to call %v: %v", req.Address, err)
}
defer resp.Body.Close()
// read body
ioutil.ReadAll(resp.Body)
// set status
rsp.Status = resp.Status
rsp.Code = int32(resp.StatusCode)
return nil
}
func (p *Ping) Tcp(ctx context.Context, req *pb.TcpRequest, rsp *pb.TcpResponse) error {
if len(req.Address) == 0 {
return errors.BadRequest("ping.tcp", "missing address")
}
c, err := net.Dial("tcp", req.Address)
if err != nil {
rsp.Status = err.Error()
return nil
}
defer c.Close()
// if no data being sent then just return
if len(req.Data) == 0 {
rsp.Status = "OK"
return nil
}
// write data to the connection
fmt.Fprint(c, req.Data)
// wait for a response
data, err := bufio.NewReader(c).ReadString('\n')
if err != nil {
rsp.Status = err.Error()
return nil
}
rsp.Status = "OK"
rsp.Data = data
return nil
}