Documentation
¶
Overview ¶
Package morc provides a scriptable REST client.
Index ¶
- Constants
- func AssertHistEntryMatches(assert *assert.Assertions, expectedHist []HistoryEntry, ...) bool
- func AssertHistoriesMatch(assert *assert.Assertions, expected, actual []HistoryEntry) bool
- func AssertProjectInFileMatches(assert *assert.Assertions, expected Project, projFilePath string) bool
- func AssertSessionsMatch(assert *assert.Assertions, expected, actual Session) bool
- func AssertSetCookiesMatches(assert *assert.Assertions, expectedCookies []SetCookiesCall, ...) bool
- func NewFlowExistsError(name string) error
- func NewFlowNotFoundError(name string) error
- func NewReqExistsError(name string) error
- func NewReqNotFoundError(name string) error
- func OutputRequest(req *http.Request, opts OutputControl) error
- func OutputResponse(resp *http.Response, caps map[string]string, opts OutputControl) error
- func ParseVarName(name string) (string, error)
- type Flow
- type FlowStep
- type Format
- type HistoryEntry
- type OutputControl
- type Project
- func (p Project) CookiesForURL(u *url.URL) []*http.Cookie
- func (p Project) Dump(w io.Writer) error
- func (p Project) DumpHistory(w io.Writer) error
- func (p *Project) EvictOldCookies()
- func (p Project) FlowsWithTemplate(template string) []string
- func (p Project) IsExecableFlow(name string) bool
- func (p Project) PersistHistoryToDisk() error
- func (p Project) PersistSessionToDisk() error
- func (p Project) PersistToDisk(all bool) error
- func (p Project) VarPrefix() string
- func (p Project) WithConfig(cfg Settings) Project
- type RESTClient
- func (r *RESTClient) CreateRequest(method string, url string, data []byte, hdrs http.Header) (*http.Request, error)
- func (r *RESTClient) ReadState(rd io.Reader) error
- func (r *RESTClient) SendRequest(req *http.Request) (*http.Response, map[string]string, error)
- func (r *RESTClient) SetCookieJar(jar *TimedCookieJar)
- func (r *RESTClient) Substitute(s string) (string, error)
- func (r *RESTClient) WriteState(w io.Writer) error
- type RequestTemplate
- type SendOptions
- type SendResult
- type Session
- type SetCookiesCall
- type Settings
- type State
- type TimedCookieJar
- func (j *TimedCookieJar) Cookies(u *url.URL) []*http.Cookie
- func (j *TimedCookieJar) ForwardSetCookieCalls(fn func(u *url.URL, cookies []*http.Cookie)) int
- func (j *TimedCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie)
- func (j *TimedCookieJar) SetCookiesFromCalls(calls []SetCookiesCall)
- func (j *TimedCookieJar) StopForwardingSetCookieCalls(idx int)
- type TraversalStep
- type VarScraper
- type VarStore
- func (v *VarStore) All() []string
- func (v *VarStore) Count() int
- func (v *VarStore) Defined() []string
- func (v *VarStore) DefinedIn(env string) []string
- func (v *VarStore) DeleteEnv(env string)
- func (v *VarStore) EnvCount() int
- func (v *VarStore) EnvNames() []string
- func (v *VarStore) Get(key string) string
- func (v *VarStore) GetFrom(key, env string) string
- func (v *VarStore) IsDefined(key string) bool
- func (v *VarStore) IsDefinedIn(key, env string) bool
- func (v VarStore) MarshalJSON() ([]byte, error)
- func (v VarStore) MergedSet(overrides map[string]string) map[string]string
- func (v VarStore) NonDefaultEnvsWith(name string) []string
- func (v *VarStore) Remove(key string)
- func (v *VarStore) Set(key, value string)
- func (v *VarStore) SetIn(key, value, env string)
- func (v *VarStore) UnmarshalJSON(data []byte) error
- func (v *VarStore) Unset(key string)
- func (v *VarStore) UnsetIn(key, env string)
Constants ¶
const ( ProjDirVar = "::PROJ_DIR::" DefaultProjectPath = ".morc/project.json" DefaultSessionPath = ProjDirVar + "/session.json" DefaultHistoryPath = ProjDirVar + "/history.json" FiletypeProject = "MORC/PROJECT" FiletypeSession = "MORC/SESSION" FiletypeHistory = "MORC/HISTORY" CurFileVersion = 1 )
const Version = "0.4.2"
Variables ¶
This section is empty.
Functions ¶
func AssertHistEntryMatches ¶ added in v0.4.0
func AssertHistEntryMatches(assert *assert.Assertions, expectedHist []HistoryEntry, actualHist []HistoryEntry, idx int) bool
note: does not check time.
func AssertHistoriesMatch ¶ added in v0.4.0
func AssertHistoriesMatch(assert *assert.Assertions, expected, actual []HistoryEntry) bool
TODO: move all this to a custom asserter.
func AssertProjectInFileMatches ¶ added in v0.4.0
func AssertProjectInFileMatches(assert *assert.Assertions, expected Project, projFilePath string) bool
func AssertSessionsMatch ¶ added in v0.4.0
func AssertSessionsMatch(assert *assert.Assertions, expected, actual Session) bool
func AssertSetCookiesMatches ¶ added in v0.4.0
func AssertSetCookiesMatches(assert *assert.Assertions, expectedCookies []SetCookiesCall, actualCookies []SetCookiesCall, idx int) bool
note: does not check time.
func NewFlowExistsError ¶ added in v0.3.0
func NewFlowNotFoundError ¶ added in v0.3.0
func NewReqExistsError ¶ added in v0.3.0
func NewReqNotFoundError ¶ added in v0.3.0
func OutputRequest ¶
func OutputRequest(req *http.Request, opts OutputControl) error
func OutputResponse ¶
func ParseVarName ¶ added in v0.2.0
Types ¶
type HistoryEntry ¶
type HistoryEntry struct { Template string ReqTime time.Time RespTime time.Time Request *http.Request Response *http.Response Captures map[string]string }
func LoadHistory ¶ added in v0.4.0
func LoadHistory(r io.Reader) ([]HistoryEntry, error)
func LoadHistoryFromDisk ¶
func LoadHistoryFromDisk(histFilename string) ([]HistoryEntry, error)
func (HistoryEntry) MarshalJSON ¶
func (h HistoryEntry) MarshalJSON() ([]byte, error)
func (*HistoryEntry) UnmarshalJSON ¶
func (h *HistoryEntry) UnmarshalJSON(data []byte) error
type OutputControl ¶
type OutputControl struct { // Request controls whether the request should be output to stdout // immediately prior to sending it. All variable substitution will be // applied prior to outputting the request; the output will show the final // request exactly as it will be sent. Request bool // Captures controls whether captured variables and their values should be // output to stdout after the response is received. Captures bool // Headers controls whether the response headers should be output to stdout // after the response is received. Headers bool // SuppressResponseBody controls whether the response body should be output // to stdout after the response is received. SuppressResponseBody bool // Format sets the format of the output. The default is "pretty", which is // human-readable. "line" is a more compact format that is slightly more // machine-readable. "sr" is a format that is shorthand for "line" but // including only the status and response payload. Format Format // Writer is the writer to which output should be written. If not set, // output will be written to os.Stdout. Writer io.Writer }
type Project ¶
type Project struct { Name string Templates map[string]RequestTemplate // note: Names must be manually synched across Templates, Flows, and History Flows map[string]Flow Vars VarStore History []HistoryEntry Session Session Config Settings }
func LoadProject ¶ added in v0.4.0
LoadProject loads the project from the given reader. If seshR is set, the session file is loaded from there. If histR is set, the history file is loaded from there. The values of Settings.XFile in the read project is ignored; to automatically use that, call LoadProjectFromDisk.
func (Project) CookiesForURL ¶ added in v0.2.0
func (Project) Dump ¶ added in v0.2.0
Dump writes the contents of the project in "project-file" format to the given io.Writer.
func (Project) DumpHistory ¶ added in v0.2.0
DumpHistory writes the contents of the history in "history-file" format to the given io.Writer.
func (*Project) EvictOldCookies ¶ added in v0.2.0
func (p *Project) EvictOldCookies()
EvictOldCookies immediately applies the eviction of old cookie sets using the project's current cookie lifetime. If the project has not loaded its session, or if the session has no cookies, this method will do nothing.
func (Project) FlowsWithTemplate ¶
func (Project) IsExecableFlow ¶ added in v0.2.0
func (Project) PersistHistoryToDisk ¶
func (Project) PersistSessionToDisk ¶
func (Project) PersistToDisk ¶
PersistToDisk writes up to 3 files; one for the suite, one for the session, and one for the history. If p.ProjFile is not set either manually or automatically when created via LoadProjectFromDisk, the project will be written to the current working directory at path .morc/project.json. If p.SeshFile is empty, it will be written to the current working directory at path .morc/session.json. If p.HistFile is empty, it will be written to the current working directory at path .morc/history.json.
func (Project) WithConfig ¶ added in v0.4.0
type RESTClient ¶
type RESTClient struct { Vars map[string]string VarOverrides map[string]string // Cleared after every call to SendRequest. VarPrefix string Scrapers []VarScraper // contains filtered or unexported fields }
Do not use default RESTClient, call NewRESTClient instead.
func NewRESTClient ¶
func NewRESTClient(cookieLifetime time.Duration, httpClient *http.Client) *RESTClient
NewRESTClient creates a new RESTClient. 0 for cookie lifetime will default it to 24 hours. If an http.Client is provided, it will be used for making calls, but its cookie jar will be replaced with MORC's timeoutable variant. Callers should use other methods to load cookies in. If httpClient is set to nil, it will default to a new http.Client with a default transport and timeout of 30 seconds.
func (*RESTClient) CreateRequest ¶
func (r *RESTClient) CreateRequest(method string, url string, data []byte, hdrs http.Header) (*http.Request, error)
CreateRequest creates a request to the given endpoint. Values set in Vars and VarOverrides are used to fill any variables in the URL, data, and headers.
func (*RESTClient) SendRequest ¶
SendRequest sends the given request and returns the response. VarOverrides will be cleared after this is called. Prior to returning, the response is scanned for var captures and those that are captured are stored in Vars and re
func (*RESTClient) SetCookieJar ¶
func (r *RESTClient) SetCookieJar(jar *TimedCookieJar)
func (*RESTClient) Substitute ¶
func (r *RESTClient) Substitute(s string) (string, error)
func (*RESTClient) WriteState ¶
func (r *RESTClient) WriteState(w io.Writer) error
type RequestTemplate ¶
type RequestTemplate struct { Name string Captures map[string]VarScraper Body []byte URL string Method string Headers http.Header AuthFlow string }
func (RequestTemplate) Sendable ¶
func (r RequestTemplate) Sendable() bool
type SendOptions ¶
type SendOptions struct { // Vars are request variables and their values that are set only for this // request. A variable in Vars with the same name as one that is in any // loaded state (should that be requested) will override the loaded state // value, but will not be saved in resulting state. Vars map[string]string // Captures is a list of variable scrapers that will be used to extract // values from the response body. The captured values *will* be kept in any // saved state (should state save be requested). Captures []VarScraper // LoadStateFile is the path to a state file that should be loaded before // sending the request. If this is set, the state file will be loaded and // used to populate the initial RESTClient state before applying any further // options given in this struct. LoadStateFile string // SaveStateFile is the path to a state file that should be saved after // sending the request, for non-project based state saving. If set, state // will be saved in this file immediately after the response is received. SaveStateFile string // Body is bytes of data that make up the body of the request to be sent. If // not set, the request will be sent with no body. Variable substitution // will be performed on the data prior to sending. Body []byte // Headers is a map of headers to be sent with the request. If not set, the // request will be sent with default headers only. Variable substitution // will be performed on the header names and values prior to sending. Headers http.Header // Cookies loads the given cookies from a set of SetCookiesCalls into // the client before sending the request. Cookies []SetCookiesCall // CookieLifetime is the lifetime of cookie records in the client. It is // used to evict old cookie records regardless of actual lifetime in the // Set-Cookie header that originally caused it to be set. If not set, it // will default to 24 hours. CookieLifetime time.Duration // Output contains output control options that determine what output is // generated after the request is sent. Output OutputControl // Client is a user-provided HTTP client that will be used to make external // HTTP calls. If left nil, a default one is used. If provided, note that // its cookie jar will be replaced with an internal variant of a cookie jar // that allows for cookie record keeping. Also note that TLS configuration // provided in this struct will override any in the given client. // // TODO: this is almost entirely used for testing and should probably not // be exposed to callers. Perhaps via setting a global? Or even giving as // a ctor. Client *http.Client // InsecureSkipVerify is a flag that, if set, will cause the client to skip // verification of TLS certificates when making HTTPS requests. This is // useful for testing against self-signed certificates, but note that this // should generally NOT be used in production code. THIS IS INSECURE AND // SHOULD BE USED WITH CAUTION. InsecureSkipVerify bool }
SendOptions is used to encapsulate non-critical options for sending a request via the Send function.
type SendResult ¶
type SendResult struct { // SendTime is the time that the request was sent to the remote host. SendTime time.Time // RecvTime is the time that the response was received from the remote host. RecvTime time.Time // Request is the request exactly as it was sent. Request *http.Request // Response is the received response. Response *http.Response // Captures is map of variables to their values that were captured from the // response body Captures map[string]string // Cookies is all cookies available in the client after the request was // sent. Cookies []SetCookiesCall }
func Send ¶
func Send(method, URL, varSymbol string, opts SendOptions) (SendResult, error)
Send performs standardized sending of a request, along with standardized output control options. A RESTClient is built and populated and used to send the request. All requests sent from a CLI command should be sent using this function.
type Session ¶
type Session struct {
Cookies []SetCookiesCall
}
func LoadSessionFromDisk ¶
func (Session) Dump ¶ added in v0.2.0
Dump writes the contents of the session in "session-file" format to the given io.Writer.
func (Session) MarshalJSON ¶
func (Session) TotalCookieSets ¶
TotalCookieSets returns the total number of individual cookies that this Session has a record of being set across all URLs. This may include the same cookie being set multiple times.
func (*Session) UnmarshalJSON ¶
type SetCookiesCall ¶
type SetCookiesCall struct { Time time.Time `json:"time"` URL *url.URL `json:"url"` Cookies []*http.Cookie `json:"cookies"` }
func (SetCookiesCall) MarshalBinary ¶
func (sc SetCookiesCall) MarshalBinary() ([]byte, error)
func (SetCookiesCall) String ¶
func (sc SetCookiesCall) String() string
func (*SetCookiesCall) UnmarshalBinary ¶
func (sc *SetCookiesCall) UnmarshalBinary(data []byte) error
type Settings ¶
type Settings struct { ProjFile string `json:"-"` HistFile string `json:"history_file"` SeshFile string `json:"session_file"` CookieLifetime time.Duration `json:"cookie_lifetime"` RecordHistory bool `json:"record_history"` RecordSession bool `json:"record_cookies"` // VarPrefix could be empty if not set. To get the default when not set, // use Project.VarPrefix() instead. VarPrefix string `json:"var_prefix"` }
func (Settings) HistoryFSPath ¶
HistoryFSPath returns the file-system compatible path to the history file. If s.HistFile contains ProjDirVar, it will be replaced with the directory that the project file is in. If s.HistFile is empty, or if s.ProjFile is referred to with ProjDirVar and is itself empty, this will return the empty string.
func (Settings) SessionFSPath ¶
SessionFSPath returns the file-system compatible path to the session file. If s.SeshFile contains ProjDirVar, it will be replaced with the directory that the project file is in. If s.SeshFile is empty, or if s.ProjFile is referred to with ProjDirVar and is itself empty, this will return the empty string.
type State ¶
type State struct { Cookies []SetCookiesCall Vars map[string]string }
State holds all information in a saved state file.
type TimedCookieJar ¶
type TimedCookieJar struct {
// contains filtered or unexported fields
}
TimedCookieJar wraps a net/http.CookieJar implementation and does quick and dirty recording of all cookies that are received. Because it cannot examine the policy of the wrapped jar, it simply records calls to SetCookies and stores enough information to reproduce all said calls, and additionally records the time that each call was made.
This record can be persisted to bytes, and later played back to restore the state of the cookie jar. Note that depending on the policy of the wrapped jar, cookies that are valid at persistence time may be invalid at playback time.
The time of each call is used for record eviction. At load time and periodically during calls to other methods, the jar will remove any records that are older than a certain threshold. This threshold is stored in the Lifetime member of the TimedCookieJar.
The zero value of TimedCookieJar is not valid. Use NewTimedCookieJar to create one.
It uses trickiness inside of unmarshal that relies on assumption that it is being called on a valid one whose wrapped cookiejar hasn't yet been called.
TODO: this is a highly-coupled structure with RESTClient. Doesn't really make sense to export it.
func NewTimedCookieJar ¶
func NewTimedCookieJar(wrapped http.CookieJar, lifetime time.Duration) *TimedCookieJar
NewTimedCookieJar creates a new TimedCookieJar with the given lifetime. If lifetime is 0, the default lifetime of 24 hours is used. If wrapped is nil, a new net/http/cookiejar.Jar is created with default options and used as wrapped.
func (*TimedCookieJar) ForwardSetCookieCalls ¶
func (*TimedCookieJar) SetCookies ¶
func (j *TimedCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie)
func (*TimedCookieJar) SetCookiesFromCalls ¶
func (j *TimedCookieJar) SetCookiesFromCalls(calls []SetCookiesCall)
func (*TimedCookieJar) StopForwardingSetCookieCalls ¶
func (j *TimedCookieJar) StopForwardingSetCookieCalls(idx int)
type TraversalStep ¶
func (TraversalStep) String ¶
func (t TraversalStep) String() string
func (TraversalStep) Traverse ¶
func (t TraversalStep) Traverse(data interface{}) (interface{}, error)
type VarScraper ¶
type VarScraper struct { Name string OffsetStart int OffsetEnd int Steps []TraversalStep // if non-nil, OffsetStart and OffsetEnd are ignored }
func ParseVarScraper ¶
func ParseVarScraper(s string) (VarScraper, error)
func ParseVarScraperSpec ¶
func ParseVarScraperSpec(name, spec string) (VarScraper, error)
func (VarScraper) EqualSpec ¶ added in v0.3.0
func (v VarScraper) EqualSpec(other VarScraper) bool
func (VarScraper) IsJSONSpec ¶ added in v0.3.0
func (v VarScraper) IsJSONSpec() bool
func (VarScraper) IsOffsetSpec ¶ added in v0.3.0
func (v VarScraper) IsOffsetSpec() bool
func (VarScraper) Spec ¶ added in v0.3.0
func (v VarScraper) Spec() string
func (VarScraper) String ¶
func (v VarScraper) String() string
type VarStore ¶
type VarStore struct { Environment string // contains filtered or unexported fields }
VarStore is a collection of variables that can be accessed by name within multiple environments. The zero value of this type is not valid; create a new VarStore with NewVarStore().
func NewVarStore ¶
func NewVarStore() VarStore
func (*VarStore) All ¶
All returns the names of all variables defined between the current environment and the default environment. If a variable is defined in both environments, it will only be included once.
func (*VarStore) Count ¶
Count returns the number of variables accessible from the current environment. This includes any in the default environment that are not overridden by the current environment. This will match the number of elements returned by All().
func (*VarStore) Defined ¶
Defined returns the names of all variables defined in the current environment. It does not include any vars that are only defined in the default environment.
func (*VarStore) DefinedIn ¶
DefinedIn returns the names of all variables defined in the given environment. It does not include any vars that are only defined in the default environment unless "" is given as env.
func (*VarStore) DeleteEnv ¶ added in v0.2.0
DeleteEnv immediately removes the given environment and all of its variables. The given environment must not be the default environment.
func (*VarStore) IsDefinedIn ¶
func (VarStore) MarshalJSON ¶
func (VarStore) MergedSet ¶ added in v0.2.0
MergedSet returns the set of keys and values of all variables accessible from the current environment, with the given map of vars taking precedence over any that it has stored.
func (VarStore) NonDefaultEnvsWith ¶ added in v0.2.0
func (*VarStore) Remove ¶
Remove removes the variable from all environments, including the default one.
func (*VarStore) UnmarshalJSON ¶
func (*VarStore) Unset ¶
Unset removes the variable from the current environemnt. If the current environment is not the default environment, the variable will not be removed from the default environment. Use Remove to remove the variable from all environments.
If the current environment *is* the default environment, calling this method has the same effect as calling Remove, as variables are not allowed to exist in only a non-default environment.