Skip to content

Commit

Permalink
CLOSES #35 Quoting issue (#39)
Browse files Browse the repository at this point in the history
* Implement and use template function for JSON.

We build GraphQL queries with Go templates. We were using a built-in
`js` template function for escaping arbitrary strings before using them
as JSON strings. Which _almost_ works; it's not the intended use case
for `js`. We actually needed a custom template function, as implemented
here.

Most of the changes in this commit are simply replacing `js` with
`json` where templates are defined. The meat of the commit is in
`query.go`.

* Redo template strings not to use explicit quotes.

Rather than the approach of the previous commit of the `json` template
function doing something special when the output of Marshal is a JSON
string, by stripping the beginning and ending quotation marks, simply
don't use the quotation marks in the templates in the first place.

* Add unit test for json template function.
  • Loading branch information
steven-collins-omega authored Jul 15, 2021
1 parent 07aad5a commit fb58ff1
Show file tree
Hide file tree
Showing 31 changed files with 73 additions and 38 deletions.
2 changes: 1 addition & 1 deletion client/actions/channels/add_channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

const (
QueryAddChannel = "addChannel"
AddChannelVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","name":"{{js .Name}}"{{end}}`
AddChannelVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"name":{{json .Name}}{{end}}`
)

// AddChannelVariables are the variables specific to adding a group.
Expand Down
2 changes: 1 addition & 1 deletion client/actions/channels/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

const (
QueryChannel = "channel"
ChannelVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","uuid":"{{js .UUID}}"{{end}}`
ChannelVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"uuid":{{json .UUID}}{{end}}`
)

// ChannelVariables to query channel
Expand Down
2 changes: 1 addition & 1 deletion client/actions/channels/channel_by_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

const (
QueryChannelByName = "channelByName"
ChannelByNameVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","name":"{{js .Name}}"{{end}}`
ChannelByNameVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"name":{{json .Name}}{{end}}`
)

// ChannelByNameVariables to query channel by name
Expand Down
2 changes: 1 addition & 1 deletion client/actions/channels/channels.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

const (
QueryChannels = "channels"
ChannelsVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}"{{end}}`
ChannelsVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}}{{end}}`
)

type ChannelsVariables struct {
Expand Down
2 changes: 1 addition & 1 deletion client/actions/channels/remove_channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

const (
QueryRemoveChannel = "removeChannel"
RemoveChannelVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","uuid":"{{js .UUID}}"{{end}}`
RemoveChannelVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"uuid":{{json .UUID}}{{end}}`
)

// RemoveChannelVariables are the variables specific to adding a group.
Expand Down
2 changes: 1 addition & 1 deletion client/actions/clusters/clusters_by_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

const (
QueryClusterByName = "clusterByName"
ClusterByNameVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","clusterName":"{{js .ClusterName}}"{{end}}`
ClusterByNameVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"clusterName":{{json .ClusterName}}{{end}}`
)

type ClusterByNameVariables struct {
Expand Down
2 changes: 1 addition & 1 deletion client/actions/clusters/clusters_by_org_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

const (
QueryClustersByOrgID = "clustersByOrgId"
ClustersByOrgIDVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}"{{end}}`
ClustersByOrgIDVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}}{{end}}`
)

type ClustersByOrgIDVariables struct {
Expand Down
2 changes: 1 addition & 1 deletion client/actions/clusters/delete_cluster_by_cluster_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

const (
QueryDeleteClusterByClusterID = "deleteClusterByClusterId"
DeleteClusterByClusterIDVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","clusterId":"{{js .ClusterID}}"{{end}}`
DeleteClusterByClusterIDVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"clusterId":{{json .ClusterID}}{{end}}`
)

type DeleteClusterByClusterIDVariables struct {
Expand Down
2 changes: 1 addition & 1 deletion client/actions/clusters/register_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (

const (
QueryRegisterCluster = "registerCluster"
RegisterClusterVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","registration":{{printf "%s" .Registration}}{{end}}`
RegisterClusterVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"registration":{{printf "%s" .Registration}}{{end}}`
)

// RegisterClusterVariables are the variables specific to cluster registration.
Expand Down
2 changes: 1 addition & 1 deletion client/actions/groups/add_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

const (
QueryAddGroup = "addGroup"
AddGroupVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","name":"{{js .Name}}"{{end}}`
AddGroupVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"name":{{json .Name}}{{end}}`
)

// AddGroupVariables are the variables specific to adding a group.
Expand Down
2 changes: 1 addition & 1 deletion client/actions/groups/group_by_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

const (
QueryGroupByName = "groupByName"
GroupByNameVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","name":"{{js .Name}}"{{end}}`
GroupByNameVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"name":{{json .Name}}{{end}}`
)

type GroupByNameVariables struct {
Expand Down
2 changes: 1 addition & 1 deletion client/actions/groups/group_clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

const (
QueryGroupClusters = "groupClusters"
GroupClustersVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","uuid":"{{js .UUID}}","clusters":[{{range $i,$e := .Clusters}}{{if gt $i 0}},{{end}}"{{js $e}}"{{end}}]{{end}}`
GroupClustersVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"uuid":{{json .UUID}},"clusters":[{{range $i,$e := .Clusters}}{{if gt $i 0}},{{end}}{{json $e}}{{end}}]{{end}}`
)

// GroupClustersVariables are the variables specific to grouping clusters.
Expand Down
2 changes: 1 addition & 1 deletion client/actions/groups/groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

const (
QueryGroups = "groups"
GroupsVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}"{{end}}`
GroupsVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}}{{end}}`
)

type GroupsVariables struct {
Expand Down
2 changes: 1 addition & 1 deletion client/actions/groups/remove_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "github.com/IBM/satcon-client-go/client/actions"

const (
QueryRemoveGroup = "removeGroup"
RemoveGroupVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","uuid":"{{js .UUID}}"{{end}}`
RemoveGroupVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"uuid":{{json .UUID}}{{end}}`
)

// RemoveGroupVariables are the variables specific to removing a group by name.
Expand Down
2 changes: 1 addition & 1 deletion client/actions/groups/remove_group_by_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "github.com/IBM/satcon-client-go/client/actions"

const (
QueryRemoveGroupByName = "removeGroupByName"
RemoveGroupByNameVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","name":"{{js .Name}}"{{end}}`
RemoveGroupByNameVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"name":{{json .Name}}{{end}}`
)

// RemoveGroupByNameVariables are the variables specific to removing a group by name.
Expand Down
13 changes: 10 additions & 3 deletions client/actions/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package actions

import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -59,6 +60,11 @@ func BuildArgVarsList(args map[string]string) string {
return "(" + strings.Join(argVarStrings, ", ") + ")"
}

func JsonMarshalToString(v interface{}) (string, error) {
bytes, err := json.Marshal(v)
return string(bytes), err
}

//BuildRequest builds the request and it sets the headers
func BuildRequest(payload io.Reader, endpoint string, authClient auth.AuthClient) (*http.Request, error) {
req, _ := http.NewRequest(http.MethodPost, endpoint, payload)
Expand All @@ -82,16 +88,17 @@ func BuildRequest(payload io.Reader, endpoint string, authClient auth.AuthClient
// e.g.:
// `{{define "vars"}}"var_1":"{{.Var1}},"var2":"{{.Var2}}"{{end}}`
func BuildRequestBody(requestTemplate string, vars interface{}, funcs template.FuncMap) (io.Reader, RequestBodyError) {
// First we scan to make sure all variables are escaped using the "js" built-in function
reString := `\{\{\w*(?:js){0}\w*\.`
// First we scan to make sure all variables are escaped using the "json" function
reString := `\{\{\w*(?:json){0}\w*\.`
re, _ := regexp.Compile(reString)
if re.MatchString(requestTemplate) {
return nil, errors.New("All variables must be escaped using 'js' built-in")
return nil, errors.New("All variables must be escaped using 'json' template function")
}

defaultFuncs := template.FuncMap{
"buildArgsList": BuildArgsList,
"buildArgVarsList": BuildArgVarsList,
"json": JsonMarshalToString,
}

// Merge in user-supplied functions
Expand Down
40 changes: 34 additions & 6 deletions client/actions/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,34 @@ var _ = Describe("Query", func() {
}
})

Describe("json template function", func() {
type Special struct {
A string
B string
C string
}

FIt("Correctly escapes special characters", func() {
testSpecial := Special{
A: `'apostrophes'`,
B: `"quotes"`,
C: `\backslashes\`,
}
funcs := template.FuncMap{
"json": JsonMarshalToString,
}

tmpl, err := template.New("test").Funcs(funcs).Parse("{{json .A}} {{json .B}} {{json .C}}")
Expect(err).NotTo(HaveOccurred())

buf := &bytes.Buffer{}
err = tmpl.Execute(buf, testSpecial)
Expect(err).NotTo(HaveOccurred())
finalBytes, err := ioutil.ReadAll(buf)
Expect(err).NotTo(HaveOccurred())
Expect(finalBytes).To(Equal([]byte(`"'apostrophes'" "\"quotes\"" "\\backslashes\\"`)))
})
})
Describe("BuildArgsList", func() {
It("Returns a string containing a list delimited by ', '", func() {
argList := BuildArgsList(argMap)
Expand Down Expand Up @@ -147,7 +175,7 @@ var _ = Describe("Query", func() {
)

BeforeEach(func() {
requestTemplate = `{{define "vars"}}"first":"{{js .First}}","last":"{{js .Last}}"{{end}}`
requestTemplate = `{{define "vars"}}"first":{{json .First}},"last":{{json .Last}}{{end}}`
vars = requestVars{
First: "Don",
Last: "Quixote",
Expand Down Expand Up @@ -219,7 +247,7 @@ var _ = Describe("Query", func() {

Context("When additional helper functions are passed in", func() {
BeforeEach(func() {
requestTemplate = `{{define "vars"}}"first":"{{js (toUpper .First)}}"{{end}}`
requestTemplate = `{{define "vars"}}"first":{{json (toUpper .First)}}{{end}}`
funcs = template.FuncMap{
"toUpper": strings.ToUpper,
}
Expand All @@ -234,9 +262,9 @@ var _ = Describe("Query", func() {
})
})

Context("When the variable template does not escape js for all variables", func() {
Context("When the variable template does not escape json for all variables", func() {
BeforeEach(func() {
requestTemplate = `{{define "vars"}}"first":"{{js .First}}","last":"{{.Last}}"{{end}}`
requestTemplate = `{{define "vars"}}"first":{{json .First}},"last":"{{.Last}}"{{end}}`
})

It("Returns nil and an error", func() {
Expand All @@ -248,7 +276,7 @@ var _ = Describe("Query", func() {

Context("When the variable template is not valid", func() {
BeforeEach(func() {
requestTemplate = `{{define "vars"}}{{js .First}}`
requestTemplate = `{{define "vars"}}{{json .First}}`
})

It("Returns nil and an error", func() {
Expand All @@ -260,7 +288,7 @@ var _ = Describe("Query", func() {

Context("When the template references variables not part of the struct", func() {
BeforeEach(func() {
requestTemplate = `{{define "vars"}}"first":"{{js .Foo}}"{{end}}`
requestTemplate = `{{define "vars"}}"first":{{json .Foo}}{{end}}`
})

It("Returns nil and an error", func() {
Expand Down
2 changes: 1 addition & 1 deletion client/actions/resources/resource_content.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

const (
QueryResourceContent = "resourceContent"
ResourceContentVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}", "clusterId":"{{js .ClusterID}}", "resourceSelfLink":"{{js .ResourceSelfLink}}"{{end}}`
ResourceContentVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}}, "clusterId":{{json .ClusterID}}, "resourceSelfLink":{{json .ResourceSelfLink}}{{end}}`
)

// ResourceContentVariables variable to query resources for specified cluster
Expand Down
2 changes: 1 addition & 1 deletion client/actions/resources/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

const (
QueryResources = "resources"
ResourcesVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}"{{end}}`
ResourcesVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}}{{end}}`
)

// ResourcesVariables variable to query resources for specified cluster
Expand Down
2 changes: 1 addition & 1 deletion client/actions/resources/resources_by_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

const (
QueryResourcesByCluster = "resourcesByCluster"
ResourcesByClusterVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","clusterId":"{{js .ClusterID}}", "filter":"{{js .Filter}}","limit":{{js .Limit}}{{end}}`
ResourcesByClusterVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"clusterId":{{json .ClusterID}}, "filter":{{json .Filter}},"limit":{{json .Limit}}{{end}}`
)

// ResourcesByClusterVariables variable to query resources for specified cluster
Expand Down
2 changes: 1 addition & 1 deletion client/actions/subscriptions/add_subscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

const (
QueryAddSubscription = "addSubscription"
AddSubscriptionVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","name":"{{js .Name}}","groups":[{{range $i,$e := .Groups}}{{if gt $i 0}},{{end}}"{{js $e}}"{{end}}],"channelUuid":"{{js .ChannelUUID}}","versionUuid":"{{js .VersionUUID}}"{{end}}`
AddSubscriptionVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"name":{{json .Name}},"groups":[{{range $i,$e := .Groups}}{{if gt $i 0}},{{end}}{{json $e}}{{end}}],"channelUuid":{{json .ChannelUUID}},"versionUuid":{{json .VersionUUID}}{{end}}`
)

type AddSubscriptionVariables struct {
Expand Down
2 changes: 1 addition & 1 deletion client/actions/subscriptions/remove_subscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

const (
QueryRemoveSubscription = "removeSubscription"
RemoveSubscriptionVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","uuid":"{{js .UUID}}"{{end}}`
RemoveSubscriptionVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"uuid":{{json .UUID}}{{end}}`
)

// RemoveSubscriptionVariables are the variables specific to adding a group.
Expand Down
2 changes: 1 addition & 1 deletion client/actions/subscriptions/set_subscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

const (
QuerySetSubscription = "setSubscription"
SetSubscriptionVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","uuid":"{{js .UUID}}","versionUuid":"{{js .VersionUUID}}"{{end}}`
SetSubscriptionVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"uuid":{{json .UUID}},"versionUuid":{{json .VersionUUID}}{{end}}`
)

type SetSubscriptionVariables struct {
Expand Down
2 changes: 1 addition & 1 deletion client/actions/subscriptions/subscriptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const (
//QuerySubscriptions specifies the query
QuerySubscriptions = "subscriptions"
//SubscriptionsVarTemplate is the template used to create the graphql query
SubscriptionsVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}"{{end}}`
SubscriptionsVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}}{{end}}`
)

//SubscriptionsVariables are the variables used for the subscription query
Expand Down
2 changes: 1 addition & 1 deletion client/actions/versions/add_channel_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
const (
ContentType = "application/yaml"
QueryAddChannelVersion = "addChannelVersion"
AddChannelVersionVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","channelUuid":"{{js .ChannelUUID}}","name":"{{js .Name}}","type":"{{js .ContentType}}","content":"{{js .Content}}","description":"{{js .Description}}"{{end}}`
AddChannelVersionVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"channelUuid":{{json .ChannelUUID}},"name":{{json .Name}},"type":{{json .ContentType}},"content":{{json .Content}},"description":{{json .Description}}{{end}}`
)

// AddChannelVersionVariables to create addChannelVersion graphql request
Expand Down
2 changes: 1 addition & 1 deletion client/actions/versions/channel_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const (
//QueryChannelVersion specifies the query
QueryChannelVersion = "channelVersion"
// ChannelVersionVarTemplate is the template used to create the graphql query
ChannelVersionVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","channelUuid":"{{js .ChannelUUID}}","versionUuid":"{{js .VersionUUID}}"{{end}}`
ChannelVersionVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"channelUuid":{{json .ChannelUUID}},"versionUuid":{{json .VersionUUID}}{{end}}`
)

// ChannelVersionVariables are the variables used for the subscription query
Expand Down
2 changes: 1 addition & 1 deletion client/actions/versions/channel_version_by_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const (
//QueryChannelVersionByName specifies the query
QueryChannelVersionByName = "channelVersionByName"
// ChannelVersionByNameVarTemplate is the template used to create the graphql query
ChannelVersionByNameVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","channelName":"{{js .ChannelName}}","versionName":"{{js .VersionName}}"{{end}}`
ChannelVersionByNameVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"channelName":{{json .ChannelName}},"versionName":{{json .VersionName}}{{end}}`
)

//SubscriptionsVariables are the variables used for the subscription query
Expand Down
2 changes: 1 addition & 1 deletion client/actions/versions/remove_channel_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

const (
QueryRemoveChannelVersion = "removeChannelVersion"
RemoveChannelVersionVarTemplate = `{{define "vars"}}"orgId":"{{js .OrgID}}","uuid":"{{js .UUID}}"{{end}}`
RemoveChannelVersionVarTemplate = `{{define "vars"}}"orgId":{{json .OrgID}},"uuid":{{json .UUID}}{{end}}`
)

// RemoveChannelVersionVariables are the variables specific to adding a group.
Expand Down
2 changes: 1 addition & 1 deletion client/auth/local/sign_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

const (
MutationSignIn = "signIn"
SignInVarTemplate = `{{define "vars"}}"login":"{{js .Login}}","password":"{{js .Password}}"{{end}}`
SignInVarTemplate = `{{define "vars"}}"login":{{json .Login}},"password":{{json .Password}}{{end}}`
)

// AddSignInVariables are the variables specific to log in a user.
Expand Down
2 changes: 1 addition & 1 deletion client/auth/local/sign_up.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

const (
MutationSignUp = "signUp"
SignUpVarTemplate = `{{define "vars"}}"username":"{{js .Username}}","email":"{{js .Email}}","password":"{{js .Password}}","orgName":"{{js .OrgName}}","role":"{{js .Role}}"{{end}}`
SignUpVarTemplate = `{{define "vars"}}"username":{{json .Username}},"email":{{json .Email}},"password":{{json .Password}},"orgName":{{json .OrgName}},"role":{{json .Role}}{{end}}`
)

// AddSignUpVariables are the variables specific to adding a user.
Expand Down
2 changes: 1 addition & 1 deletion client/web/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ var _ = Describe("Client", func() {
h.DoReturns(response, nil)

// Setup the template
requestTemplate = `{{define "vars"}}"name":"{{js .Name}}"{{end}}`
requestTemplate = `{{define "vars"}}"name":{{json .Name}}{{end}}`
vars = QueryVars{
Name: "foo",
}
Expand Down

0 comments on commit fb58ff1

Please sign in to comment.