//Request is the base level method upon which all protocolink requests are handled //for the sake of being a valid protcollink it implements the method signature // (string,io.Reader) but for flexibilty string func (h *SSHProtocolLink) Request(path string, body io.Reader) flux.ActionStackInterface { req := flux.NewAction() err := flux.NewAction() act := req.Chain(2) st := flux.NewActionStackBy(act, err) if h.conn == nil { st.Complete(ErrorNoConnection) return st } act.OverrideBefore(1, func(b interface{}, next flux.ActionInterface) { se, ok := b.(*SSHClientSession) if !ok { return } se.Close() next.Fullfill(b) }) session, erro := h.conn.NewSession() if erro != nil { st.Complete(erro) } else { st.Complete(NewSSHClientSession(session, body)) } return st }
//FS creates a ftp client on the remote connection and allows file base op func (h *SSHProtocolLink) FS() flux.ActionStackInterface { req := flux.NewAction() eo := flux.NewAction() st := flux.NewActionStackBy(req, eo) ch := req.Chain(2) ch.OverrideBefore(1, func(b interface{}, next flux.ActionInterface) { ce, ok := b.(*sftp.Client) if !ok { return } ce.Close() }) cl, err := sftp.NewClient(h.conn) if err != nil { st.Complete(err) } else { st.Complete(cl) } return st }
//Command run a given command from the remote host through the ssh.Client connection func (h *SSHProtocolLink) Command(cmd string) flux.ActionStackInterface { rq := h.Request("", nil) dn := rq.Done() ch := flux.NewActDepend(dn, 2) ch.Then(WhenSSHClientSession(func(s *SSHClientSession, next flux.ActionInterface) { s.Run(cmd) next.Fullfill(s) })) avs := flux.UnwrapActDependWrap(dn) avs.MixLast(0, ch) room := flux.NewActionStackBy(ch, rq.Error()) return room }
//Request is the base level method upon which all protocolink requests are handled func (h *HTTPProtocolLink) Request(path string, body io.Reader) flux.ActionStackInterface { log.Printf("Initiating HTTPLink: New HTTP Request for %s", path) addr := fmt.Sprintf("%s:%d/%s", h.Descriptor().Address, h.Descriptor().Port, h.Descriptor().Service) addr = ExcessSlash.ReplaceAllString(addr, "/") addr = EndSlash.ReplaceAllString(addr, "") path = ExcessSlash.ReplaceAllString(path, "/") path = EndSlash.ReplaceAllString(path, "") resuri := fmt.Sprintf("%s/%s", addr, path) resuri = ExcessSlash.ReplaceAllString(resuri, "/") url := fmt.Sprintf("%s://%s", h.Descriptor().Scheme, resuri) log.Printf("HTTPLink: New HTTP Request for %s", url) red := flux.NewAction() erd := flux.NewAction() act := red.Chain(3) //we do these so we can override what happens after the user adds all they //want on the request act.OverrideBefore(1, func(b interface{}, next flux.ActionInterface) { rq, ok := b.(*http.Request) if !ok { // next.Fullfill(b interface) return } rq.Header.Set("X-Service-Request", h.Descriptor().Service) log.Printf("HTTPLink: Request Header Set,Initiaing RequestClient Sending...") res, err := h.client.Do(rq) if err == nil { log.Printf("HTTPLink: Recieved Request (%s) Response Status: %d", rq.URL, res.StatusCode) } else { log.Printf("HTTPLink: Recieved Request (%s) Response Error: %v", rq.URL, err) } pck := NewHTTPPacket(res, rq, err) next.Fullfill(pck) }) cl := flux.NewActionStackBy(act, erd) var req *http.Request var err error if body == nil { req, err = http.NewRequest("GET", url, body) if err != nil { cl.Complete(err) return cl } } else { req, err = http.NewRequest("POST", url, body) if err != nil { cl.Complete(err) return cl } } log.Printf("HTTPLink: Initiating Http Request Method: (%+s), URI: (%+s)", req.Method, req.URL) cl.Complete(req) return cl }