How to access all Set-Cookie values from Southbound in javascript - apigee

We have Set-Cookie values coming from our southbound, one of which we need to manipulate within the gateway before returning to the requester.
When I do the request via curl using -v, the format in the headers is:
< Set-Cookie: COOKIE_ONE=-1%2C1; Path=/
< Set-Cookie: COOKIE_TWO=6tuDIqNZTQl%2FqbPXU0M13tcl0nM%3D%0A%3B2015-03-12+11%3A24%3A38.766_1426173878765-214752_1_-1002%2C-1%2CUSD_1; Expires=Sat, 11-Apr-15 15:24:38 GMT; Path=/
When I try to access them within javascript using the context variable context.targetResponse.headers['Set-Cookie'], it only returns the first value. I have tried other variations as well as inspecting the value(s) of Set-Cookie within trace. I am able to get the specific one using a pattern in an extract variables policy, but I would like to have access to all of them so I can edit it and then send them along.
I know that using cookies and cookie manipulation are not really in the spirit of RESTful APIs, but this is the southbound we have to deal with and the requirements of the consumer.

Please take a look at this blog post, which describes how to apply a workaround to implement what you're looking for. In essence, you need to concatenate all values from the list and then parse the string
var hdr = context.getVariable('response.header.set-cookie.values')+'';
// get the array of header values:
var a = hdr.substring(1, hdr.length-1).split(',');
Hope it helps!

Related

Ni-Fi Get request with headers using InvokeHTTP

I am trying to send a Get request with the following header:
Cookie: uac.csrftoken=VwJryg1rJBC3sddwHarr497lKgQgMq;
expires=Mon, 15-Nov-2021 12:12:24 GMT; Max-Age=31449600; Path=/;
uac.authorization=2dA2631879fc4dc2e9;
in NiFi I have sent a request to get the requiered parameters and assigned it to the flow file attributes :
Now I need to combine both to have the same format as the Header above,
what do I need to add to the field attributes to send to do that?
I tried multiple ways and nothing worked, it says here
I figured it out, This can be done by adding any custom Dynamic Property in the InvokeHTTPProcessor. Example in my case :

KDB: Difference between .Q.hp/.Q.hg and the built in HTTP request. And do either persist/Keep alive?

Its seems a http get can be performed using either .Q.hg or using the built in HTTP request like
`:http://host:port "string to send as HTTP method etc"
(from https://code.kx.com/q/kb/programming-examples/)
Is there any difference?
And do either persist/keep-alive by default?
Thank you
Using .Q.hg allows you to use a string which is formatted in a way that is consistent with a web-based url request, .e.g for requesting some csv data from a server:
t:.Q.hg`$":http://www.website.com/report1/format=csv&cols=sym&cols=price&date=20200630";
/the resulting string contains the data only (no metadata/headers) and can be parsed directly
("SF";1#csv)0:t
The GET equivalent is not like a browser url, however it does return the metadata/headers (which in turn makes it messier to parse), e.g.
t:(hsym`$"http://www.website.com") "GET /report1/format=csv&cols=sym&cols=price&date=20200630 HTTP/1.1\r\nhost:www.website.com\r\n\r\n";
/result looks like
"HTTP/1.1 200 OK\r\nDate: Fri, 03 Jul 2020 14:46:33 GMT\r\nContent-Type: application/txt\r\nContent-Length: 1345\r\nConnection: keep-alive ...."
/parsed using something like (strip away metadata to get to the data)
("SF";1#csv)0:_[;t]3+first t ss "\n\r\n"
The resulting metadata/header shows "Connection: keep-alive" in my example that I've just tested so perhaps that's the default? I'm not 100% on that.
.Q.hg also has the advantage of being compatible with HTTPS and making use of proxies as per the documentation: https://code.kx.com/q/ref/dotq/#qhg-http-get
.Q.hg and .Q.hp have a similar functionality to the example outlined in the link, without having to construct the HTTP requests as strings (these functions will construct the strings for you). The example was perhaps written before the .Q.hg/.Q.hp functions were introduced in v3.4.
I don't think either persist by default assuming they use HTTP 1.0 protocol.

API requires POST arguments in a query string?

I'm playing with the Twitter API and noticed something funny- For updates, they require POST methods but expect the arguments in the query string. (See for example, the status/update call in their developer console here.)
Obviously this is technically possible, but why would anyone do it like that? Don't POST arguments belong in the body?
Either option is just as valid. My favourite example for using parameters in the URL for a POST is an application that sets waypoints on a map. e.g.
POST /map/route/45/waypoints?lat=35&long=74
In this case, the parameters make more sense in the URI as identifiers of a location, than just parameters being passed in the body to generic resource.
In REST architecture, GET and POST are just the verbs, which tells either to retrieve or create/update the resource. URI defines the identification of resource.
Example:
POST /student?name=Tom&age=12 >> It will create a new student with name Tom and age 12.
POST /student/10?name=Tom&age=12 >> It will update student with id 20 with name Tom and age 12.
There is no rule that the data should be binded to body payload or URI. This is different from WEB 1.0 concepts where HTML form data is sent in POST.
If the arguments for WEB API are in the body or query depends on the Content-Type header you send in the POST.
If it forinstance is Content-Type: application/json; charset=UTF-8 then the arguments are expected in the body as json. If it is Content-Type: application/x-www-form-urlencoded; charset=UTF-8 then the arguments are expected in the query string

Is it possible to set some http headers while http-redirect(302 or 307)?

Is it possible to set some http headers while http-redirect(302 or 307)?
<?
header("some-header: xxx");
header("Location: http://other.domain.com/foo.php",TRUE,307);
?>
You can basically set whatever http headers you want either as the server or the client.
If you are indicating a redirect you should supply the Location header as your example suggests. You should also ensure that your response headers refer to that response rather than the resource that the client is being redirected to. i.e. your headers here could include Content-Length: 0, omit the Content-Type header and so on.
Not sure if this is what you're after - this question could do with a bit more detail.
You can always do the redirection 301/307.
There are ways to do it
1) Do it through java code :
response.setStatus(307);
response.setHeader("Location",url);
2) THe same thing can be done in JSPs.
A tip here is: Always use the setHeader function and not the addHeader function as they behave in different ways.

How should I implement a COUNT verb in my RESTful web service?

I've written a RESTful web service that supports the standard CRUD operations, and that can return a set of objects matching certain criteria (a SEARCH verb), but I'd like to add a higher-order COUNT verb, so clients can count the resources matching search criteria without having to fetch all of them.
A few options that occur to me:
Ignoring the HTTP specification and returning the object count in the response body of a HEAD request.
Duplicating the SEARCH verb's logic, but making a HEAD request instead of a GET request. The server then would encode the object count in a response header.
Defining a new HTTP method, COUNT, that returns the object count in the response body.
I'd prefer the API of the first approach, but I have to strike that option because it's non-compliant. The second approach seems most semantically correct, but the API isn't very convenient: clients will have to deal with response headers, when most of the time they want to be able to do something easy like response.count. So I'm leaning toward the third approach, but I'm concerned about the potential problems involved with defining a new HTTP method.
What would you do?
The main purpose of rest is to define a set of resources that you interact with using well defined verbs. You must thus avoid to define your own verbs. The number of resources should be considered as a different resource, with its own uri that you can simply GET.
For example:
GET resources?crit1=val1&crit2=val2
returns the list of resources and
GET resources/count?crit1=val1&crit2=val2
Another option is to use the conneg: e.g. Accept: text/uri-list returns the resources list and Accept: text/plain returns only the count
You can use HEAD without breaking the HTTP specification and you can indicate the count by using an HTTP Range header in the response:
HEAD /resource/?search=lorem
Response from the service, assuming that you return the first 20 results by default:
...
Content-Range: resources 0-20/12345
...
This way you transfer the amount of resources to the client within the header of the response message without the need to return a message body.
Update:
The solution suggested Yannick Loiseau will work fine. Just wanted to provide one other alternative approach which can be used to achieve what you need without the need to define a new resource of verb.
You can use GET and add the count into the body of the message. Then, if you API allows clients to request a range of results, you can use that in order to limit the size of message body to a minimum (since you only want the count). One way to do that would be to request an empty range (from 0 to 0), for example:
GET /resource/?search=lorem&range=0,0
The service could then respond as follows, indicating that there are 1234 matching resources in the result set:
<?xml version="1.0" encoding="UTF-8" ?>
<resources range="0-0/1234" />
Ignoring the HTTP specification and returning the object count in the response body of a HEAD request.
IMHO, this is a very bad idea. It may not work simply because you might have intermediaries that don't ignore the HTTP spec.
Defining a new HTTP method, COUNT, that returns the object count in the response body.
There is no problem with this approach. HTTP is extendable and you can define your own verbs. Some firewalls prohibit this, but they are usually also prohibit POST and DELETE and X-HTTP-Method-Override header is widely supported.
Another option, to add a query param to your url, something like: ?countOnly=true

Resources