In my use-case, I need to post data to url, however the data itself is a query string.
Example:
curl -POST -d "username=abc&rememberme=on&authtype=intenal" "https..somemdpoint"
What I have is a method which takes in 3 values
function makePostRequest(username string, rememberme string, authtype string, endpoint string) {
// post a curl request.
}
I am struggling to find any library that would return me a query string if I provided it with parameters.
I tried doing this:
q := req.URL.Query()
q.Add("api_key", "key_from_environment_or_flag")
q.Add("another_thing", "foobar")
fmt.Print(q)
But realized it actually returns Values which is a map so its no good.
Is there any method in golang that creates a queryString ?
You almost got it. Call Values.Encode() to encode the map in URL-encoded form.
fmt.Print(q.Encode()) // another_thing=foobar&api_key=key_from_environment_or_flag
Create the map directly instead of using req.URL.Query() to return an empty map:
values := url.Values{}
values.Add("api_key", "key_from_environment_or_flag")
values.Add("another_thing", "foobar")
query := values.Encode()
Use strings.NewReader(query) to get an io.Reader for the POST request body.
Related
I have a form whose one field is type IS_JSON
db.define_table('vmPowerOpsTable',
Field('launchId',label=T('Launch ID'),default =datetime.datetime.now().strftime("%d%m%y%H%M%S")),
Field('launchDate',label=T('Launched On'),default=datetime.datetime.now()),
Field('launchBy',label=T('Launched By'),default = auth.user.email if auth.user else "Anonymous"),
Field('inputJson','text',label=T('Input JSON*'),
requires = [IS_NOT_EMPTY(error_message='Input JSON is required'),IS_JSON(error_message='Invalid JSON')]),
migrate=True)
When the user submits this Form, this data is also simultaneously inserted to another table.
db.opStatus.insert(launchId=vmops_launchid,launchDate=vmops_launchdate
,launchBy=vmops_launchBy,opsType=operation_type,
opsData=vmops_inputJson,
statusDetail="Pending")
db.commit()
Now from the scheduler, I am trying to retrieve this data and make a POST request.
vm_power_opStatus_row_data = vm_power_opStatus_row.opsData
Note in the above step I am able to retrieve the data. (I inserted it in a DB and saw the field exactly matches what the user has entered.
Then from the scheduler, I do a POST.
power_response = requests.post(vm_power_op_url, json=vm_power_opStatus_row_data)
The POST request is handled by a function in my controller.
Controller Function:
#request.restful()
def vmPowerOperation():
response.view = 'generic.json'
si = None
def POST(*args, **vars):
jsonBody = request.vars
print "Debug 1"+ str(jsonBody) ##-> Here it returns blank in jsonBody.
But if I do the same request from Outside(POSTMAN client or even python request ) I get the desired result.
Is anything going wrong with the data type when I am trying to fetch it from the table.
power_response = requests.post(vm_power_op_url,
json=vm_power_opStatus_row_data)
It appears that vm_power_opStatus_row_data is already a JSON-encoded string. However, the json argument to requests.post() should be a Python object, not a string (requests will automatically encode the Python object to JSON and set the content type appropriately). So, the above should be:
power_response = requests.post(vm_power_op_url,
json=json.loads(vm_power_opStatus_row_data))
Alternatively, you can use the data argument and set the content type to JSON:
power_response = requests.post(vm_power_op_url,
data=vm_power_opStatus_row_data,
headers={'Content-Type': 'application/json')
Also, note that in your REST POST function, request.vars is already passed to the function as **vars, so within the function, you can simply refer to vars rather than request.vars.
I'm trying to do a request like this:
http://example.com/hello?name=username
But in the Docs I can't find a way to pass the payload parameter. (http.Get() only receives the url)
How can I do this request?
The simplest way it to simply add it to the URL:
http.Get("http://example.com/hello?name=username")
The way I prefer to do it is to use url.Values to build the query string:
v := url.Values{}
v.Set("name", "username")
url := fmt.Sprintf("http://example.com/hello?%s", v.Encode())
http.Get(url)
So I'm receiving a request to my server that looks a little something like this
http://localhost:8080/#access_token=tokenhere&scope=scopeshere
and I can't seem to find a way to parse the token from the url.
If the # were a ? I could just parse it a standard query param.
I tried to just getting everything after the / and even the full URL, but with no luck.
Any help is greatly appreciated.
edit:
So I've solved the issue now, and the correct answer is you can't really do it in GO. So I made a simple package that will do it on the browser side and then send the token back to the server.
Check it out if you're trying to do local twitch API stuff in GO:
https://github.com/SimplySerenity/twitchOAuth
Anchor part is not even (generally) sent by a client to the server.
Eg, browsers don't send it.
For parse urls use the golang net/url package: https://golang.org/pkg/net/url/
OBS: You should use the Authorization header for send auth tokens.
Example code with extracted data from your example url:
package main
import (
"fmt"
"net"
"net/url"
)
func main() {
// Your url with hash
s := "http://localhost:8080/#access_token=tokenhere&scope=scopeshere"
// Parse the URL and ensure there are no errors.
u, err := url.Parse(s)
if err != nil {
panic(err)
}
// ---> here is where you will get the url hash #
fmt.Println(u.Fragment)
fragments, _ := url.ParseQuery(u.Fragment)
fmt.Println("Fragments:", fragments)
if fragments["access_token"] != nil {
fmt.Println("Access token:", fragments["access_token"][0])
} else {
fmt.Println("Access token not found")
}
// ---> Others data get from URL:
fmt.Println("\n\nOther data:\n")
// Accessing the scheme is straightforward.
fmt.Println("Scheme:", u.Scheme)
// The `Host` contains both the hostname and the port,
// if present. Use `SplitHostPort` to extract them.
fmt.Println("Host:", u.Host)
host, port, _ := net.SplitHostPort(u.Host)
fmt.Println("Host without port:", host)
fmt.Println("Port:",port)
// To get query params in a string of `k=v` format,
// use `RawQuery`. You can also parse query params
// into a map. The parsed query param maps are from
// strings to slices of strings, so index into `[0]`
// if you only want the first value.
fmt.Println("Raw query:", u.RawQuery)
m, _ := url.ParseQuery(u.RawQuery)
fmt.Println(m)
}
// part of this code was get from: https://gobyexample.com/url-parsing
What is the correct way to insert a new line in a Meteor.http POST call?
Here's what I usually do:
var result = HTTP.call("POST", URL, {
params: {
field: value
},
headers:{
"[HEADER FIELD]":"[HEADER VALUE]"
}
});
I want the value in this case to be multiple strings separated by new lines. I have tried:
value = "firstItem" + "%0A" + secondItem + "%0A" + thirdItem
The API I am using expects value to be different items, each on a new line. When I post this request, the API consumes this as a string and doesn't identify the items as separate inputs. Any thoughts?
A POST request usually has it's parameters separated by & if you're using application/x-www-form-urlencoded:
parameter=value&also=another
That being said, if you use application/x-www-form-urlencoded, the W3C spec states that "%0D%0A" is a new line so you can try that too.
https://www.w3.org/MarkUp/html-spec/html-spec_8.html#SEC8.2.1
I am quite new to lua. I trying to convert a string of the form
{"result": "success", "data":{"shouldLoad":"true"}"}
into lua map. So that I can access it like json. e.g. someMap[data][shouldLoad] => true
I dont have any json bindings in lua. I also tried loadstring to convert string of the form {"result" = "success", "data"={"shouldLoad"="true"}"}, which is not working.
Following, is the code snippet, where I am calling getLocation hook, which in turn returns json stringified map. Now I want to access some keys from this response body and take some decisions accordingly.
access_by_lua "
local res = ngx.location.capture('/getLocation')
//res.body = {"result"= "success", "data" = {"shouldLoad" = "true"}}
local resData = loadstring('return '..res.body)()
local shoulLoad = resData['data']['shouldLoad']
"
When I try to load shouldLoad value, nginx error log reports error saying trying to index nil value.
How do I access key value with either of the string formats. Please help.
The best answer is to consider a pre-existing JSON module, as suggested by Alexey Ten. Here's the list of JSON modules from Alexey.
I also wrote a short pure-Lua json module that you are free to use however you like. It's public domain, so you can use it, modify it, sell it, and don't need to provide any credit for it. To use that module you would write code like this:
local json = require 'json' -- At the top of your script.
local jsonStr = '{"result": "success", "data":{"shouldLoad":"true"}"}'
local myTable = json.parse(jsonStr)
-- Now you can access your table in the usual ways:
if myTable.result == 'success' then
print('shouldLoad =', myTable.data.shouldLoad)
end