Why are Golang http arguments (URL.Query()) map of lists? - go

When we call
r.URL.Query()
Inside a http route handler handler in Go, it returns a map[string][]string. I am wondering why is it a list and if I can use this property somehow when sending requests.

It is a list because it is allowed to send multiple copies of the same query string parameter in a URL, and yes, you can send query string parameters in requests.
E.g. for a URL like http://example.com/?foo=1&foo=2, Query() would return:
{"foo": ["1","2"]}

Related

Redirect to another endpoint after calling a function

I have a subrouter with prefix /api/a and I want to redirect, all requests to endopoint with prefix api/b/{aid}, to api/a after calling a function (which sets context.) How to achieve this?
When there is a call to /api/a/<whatever>, I take aid from cookies and add to request context but there are other endpoints where cookies doesn't contain aid parameter so I take it as a route param. What I want is any call to /api/b/{aid}/<whatever> is redirected to /api/a/<whatever> after I set aid in its request context (from route param).
I absolutely don't want to use client side redirects, he doesn't need to know.
Also I know that I can pass directly to any function with http.Handler signature. Its exactly what I want to avoid.
There are a fixed set of endpoints in which cookie won't be set (and thats intended, so I don't want to set one) and this set would always be prefixed by say /api/b/{aid}.
Since there are 150+ endpoints and handlers already configured to the subrouter prefixed /api/a (lets call it A). There is another subrouter B with prefix /api/b/{aid}. I want to redirect all calls to subrouter B to subrouter A after calling a function. It won't be logical to copy the entire list of handlers for separate subrouter if I want the exact same thing.
You cannot set a value in the request context, then redirect to some other URL and expect to get that value. You have to pass that value as part of the redirect using a query param, or a cookie, etc. Or you can do this without a redirect, and call the handler for the redirected URL directly.
If you want to do this with a cookie, you can get the aid in a handler, set a cookie containing aid using http.SetCookie, and redirect using http.Redirect. The other handler should receive the cookie.
If you want to do this using a query param, you can write the redirect URL with the added query parameter, redirect using http.Redirect, and parse it in the other handler.
If you want to do this without a redirect, you can get aid in one handler, put it into the request context, and call the other handler directly:
request.WithContext(context.WithValue(request.Context(),key,aid))
otherHandler(writer,request)
You can automate forwarding to the other caller using Router.Match with a single handler:
Register a handler for pathprefix /api/b/{aid}/
Handler parses aid
Handler rewrites a url /api/a/<remaining path>, sets request.URL to it, and uses router.Match to find the corresponding path under /api/a subtree
Handler calls the handler for /api/a/<remaining path>

How to pass multiple arguments to golang net rpc call

I am using net library in go and I want to make RPC call:
Client.Call("action", []string{"arg1", "arg2"}, &response)
But in JSON I see:
{"method":"action","params":[["arg1","arg2"]],"id":0}
Notice that arguments are enclosed with double square brackets.
In my case I need params to be a simple list:
{"method":"action","params":["arg1","arg2"],"id":0}
Any ideas how to accomplish this?
The codec that Go's JSON RPC uses on top of the rpc.Client will take whatever param you send and encode that as the first element of the array it uses for the params.
So the encoded request will always have a top level array with just one element, which will contain the params you sent, as you already noted.
See the WriteRequest function here:
https://golang.org/src/net/rpc/jsonrpc/client.go#L57
To achieve what you want, you can implement a custom rpc.ClientCodec.
The interface is documented here:
https://golang.org/pkg/net/rpc/#ClientCodec
You can borrow almost all of the implementation for the default JSON codec here:
https://golang.org/src/net/rpc/jsonrpc/client.go
And modify the params attribute of the request to read:
Params interface{} `json:"params"`
Then when writing your WriteRequest based on the standard one, you can just assign your params to the request params:
c.req.Params[0] = param
You can then use the rpc.NewClientWithCodec to create a client using your custom codec:
https://golang.org/pkg/net/rpc/#NewClientWithCodec

In JMeter Post Data Not Sent In Request When Certain Character Strings Are Included

In a test plan that I am trying to execute, there is a step that includes a post request with post data. One of the parameters in the post data includes special characters. The parameter name is '__RequestVerificationToken'. When the parameter name is spelled correctly, the request is sent with no post data included. The request fails. However when the parameter is changed slightly, post data will be included with the request. Because the correct parameter names are not sent, the request also fails. Below is a list of parameter names that do and do not break the sending of post data.
Parameter names that do break the sending of post data:
'__RequestVerificationToken'
'__RRequestVerificationToken'
'**RequestVerificationToken'
Parameter names that do not break the sending of post data:
'__TRequestVerificationToken'
'RequestVerificationToken'
Is there anything that I can do have my parameter name sent correctly without dropping post data from the request?
Did you try encoding them using 2 options:
In Http Request check the checkbox encode in the parameters table
Use function __urlencode

Direct ajax() or post() request of an URL

I have an url with query args:
var url = 'http://example.com/ajax.php?action=update_count&product=1234'
So, all query args I need to send for ajax request is already in URL, I tried this:
$.post( url, '', callback, 'json');
But, it won't send POST data.
So, I want to ask shall I do ajax/post request without data object/string, as query args are already in url.
Thanks.
If you put a parameter in the URL, it's treated like a GET parameter, not a POST parameter. You need to use whatever server-side mechanism is normally used for getting URL parameters. For instance, in PHP it would be $_GET['action'] and$_GET['product']`.
If you want to be able to send a parameter in either GET or POST, you can use PHP's $_REQUEST variable. It merges both sets of parameters.

How to send Object via Ajax to Servlet

How do I send an element of type object via ajax to a servlet?
In the ajax I am passing the value as follows below:
data: { mapList : mapLists }
To get the value in the Servlet am doing follows below:
Object o = request.getAttribute("mapList");
System.out.println(o);
However, the returned value is always null. What should I do to get around this problem?
Change your ajax datas by :
data: { 'mapList' : mapLists }
On HTTP GET or POST requests you can only send a list of key/value pairs as parameters to the server so you will have to manually serialize your object to send its attributes in this format.
You should better use HttpServletRequest.getParameter(String) in place of HttpServletRequest.getAttribute(String). Also, what you get as an HTTP GET/POST parameter will always be received in the servlet as a String.
I assume that you are using jQuery to send the ajax request. I also asume that your mapLists variable is a json object. As far as I know, jQuery doesn't automatically convert a json object to a key/value pair HTTP parameter list so you will have to do it by yourself and then parse it back in the servlet. You can use JSON.stringify() to convert your json object or you can serialize it manually.

Resources