I wanted to test the status code if all the key headers are valid.
All I know is the Content-type key. I'm getting an error when doing this to other key headers.
var headers =pm.request.headers.toObject()
console.log(headers)
all headers send request can be accessed using above method in the test script
var headers = pm.request.headers.map()
console.log(headers.length)
_ = require("lodash")
let expectedHeaders = ["Accept","Content-Type"]
let requiredHeaders =_.filter(headers, function (n) {
return expectedHeaders.includes(n.key);
});
_.isEqual(requiredHeaders.map(n=>n.key).sort(), expectedHeaders.sort()) ? pm.test("sometest",function(){
pm.expect(pm.response.code).to.eql(200)
}):null
is here we are filtering out required headers and validating that all headers are present as expected and the running a test if the header is as expected else doing nothing
Related
This is a follow up to my issue at API Pagination in JSON Body (not Header) - How to Access with Power Query in Custom Connector?
I have built a custom connector for an API that sends its pagination data back in the body of the response, rather than the header. The way to use GetNextLink using header is documented in the GitHub custom connector example:
https://github.com/microsoft/DataConnectors/blob/master/samples/Github/github.pq
GetNextLink = (response, optional request) =>
let
// extract the "Link" header if it exists
link = Value.Metadata(response)[Headers][#"Link"]?,
links = Text.Split(link, ","),
splitLinks = List.Transform(links, each Text.Split(Text.Trim(_), ";")),
next = List.Select(splitLinks, each Text.Trim(_{1}) = "rel=""next"""),
first = List.First(next),
removedBrackets = Text.Range(first{0}, 1, Text.Length(first{0}) - 2)
in
try removedBrackets otherwise null;
Getting to the pagination data from the body of the response should be easier than the header, I've learned. But I am stumped. In the images, you can see the record I am trying to access that comes back through Web.Contents()
This is my code for the GetNextLink function. I am trying to get the "next" record above.
GetNextLink = (response) =>
// response is data already run through Web.Contents()
let
Source = Lines.FromBinary(response),
nextPage = Record.Field(Source[paging], "next")
in
try nextPage otherwise null;
I get the error back "We cannot convert a value of type Record to type Text". I feel like I am not getting the 'Source" correctly? I could certainly use help as I am a PowerQuery newbie!
Thanks!
GetNextLink = (response) =>
// response is data already run through Web.Contents()
let Source = Lines.FromBinary(response),
nextpage = try Source[paging][next] otherwise null
in nextpage
or
GetNextLink = (response) =>
// response is data already run through Web.Contents()
let Source = Lines.FromBinary(response)
nextpage = try Record.Field(Source[paging],"next") otherwise null
in nextpage
How do I parse a response cookie and sent back a specific value into a request header?
I'm making a request: it's sending back a token in a session cookie (token=longstrong). I need to grab that cookie, parse out token, and send back the value in a x-token: request header for following requests.
Paw is only giving me the option to send the cookie (raw).
How can I parse the response cookie to send back the value of $.token (json pseudo-code)?
A late reply, sorry!
This might help (from How do i pick specific cookies?):
Use a Custom dynamic value (right click on the field, and pick Extensions > Custom), instead, and use the following JavaScript code snippet:
function evaluate(context){
// Set here the cookies you'd like to return
var wantedCookies = ["datr", "reg_fb_ref"];
var regex = /^(\w+)\=([^;\s]+)/g;
// Request
// Uses here the current request, you can use getRequestByName("name of the request") instead
var request = context.getCurrentRequest();
// Get response cookies
var cookies = request.getLastExchange().getResponseHeaderByName("Set-Cookie").split(", ");
var filteredCookies = [];
for (var i in cookies) {
var cookie = cookies[i];
var match = regex.exec(cookie);
if (match && wantedCookies.indexOf(match[1]) >= 0) {
filteredCookies.push(match[0]);
}
}
return filteredCookies.join(",");
};
That basically parses manually the response cookies, and returns the ones you need.
This other question might help: Routes using cookie authentication from previous version of Paw no longer work on new version
By definition the http response is split in 3 parts, status-code -> headers -> body, and when doing akka client http requests the http response is received after the first 2 parts have been completely
received.
val responseFuture: Future[HttpResponse]
responseFuture.map {
case HttpResponse(statusCode:StatusCode, headers:Seq[HttpHeader], entity:ResponseEntity, protocol:HttpProtocol)
}
This is completely fine for most use cases, but in my particular case I need access to the headers before all the headers are received (a third party server is returning progress by writing custom progress headers until the response is ready). Is there any way to access the headers the same way we access the body?
val entity: ResponseEntity
val entitySource:Source[ByteString, Any] = entity.dataBytes
In the perfect world there would be a way to access the headers as a source as well
HttpResponse(statusCode:StatusCode, headers:Source[HttpHeader, NotUsed], entity:ResponseEntity, protocol:HttpProtocol)
Not Possible With akka-http
The representation of HttpResponse treats the headers as a Seq[HttpHeader] instead of an Iterator or an akka-stream Source. Therefore, as explained in the question, it is not possible to instantiate an HttpResponse object without having all the header values available first.
I do not know the exact reason behind this design decision but I suspect it is because it would be difficult to support a Source for the headers and a Source for the body. The body Source would not be able to be consumed without first consuming the header Source, so there would have to be a strict ordering of accessing the response's member variables. This would lead to confusion and unexpected errors.
Lower Level Processing with akka-stream
The hypertext transfer protocol is just an application layer protocol, usually on top of TCP. And, it is a fairly simple message format:
The response message consists of the following:
A status line which includes the status code and reason message (e.g.,
HTTP/1.1 200 OK, which indicates that the client's request succeeded).
Response header fields (e.g., Content-Type: text/html).
An empty line.
An optional message body.
Therefore, you could use the Tcp binding to get a connection and parse the message ByteString Source yourself to get at the headers:
val maximumFrameLength = 1024 * 1024
val endOfMessageLine : () => Byte => Boolean = () => {
var previousWasCarriage = false
(byte) =>
if(byte == '\r') {
previousWasCarriage = true
false
}
else if(byte == '\n' && previousWasCarriage) {
previousWasCarriage = false
true
}
else {
previousWasCarriage = false
false
}
}
def subFlow =
Flow[ByteString].flatMapConcat(str => Source.fromIterable(str))
.splitAfter(endOfMessageLine())
Unfortunately this probably requires that your request be sent as a raw ByteString via the Tcp binding as well.
I am using ember vesrion 2.15.1 for my application. I am using ember-file-upload node module to support file upload and that is successful. Challenge is I am not able to add auth token to the request header. My request header looks like this:
I am not able to add userAuthToken in request header of file upload like below which I am able to add for other api calls:
I have tried uploading the file via
set(file, 'headers.userAuthToken', localStorage.getItem("userToken")); // this line is creating problems
let response = yield file.upload(url);
But unable to add userAuthToken in request header.
Any fix or workaround will be appreciated.
You can pass options as second parameter of upload method. One of possible options is headers. Something like this should work:
let response = yield file.upload(url, {
headers: {userAuthToken: localStorage.getItem("userToken")}
});
You can find other possible options here
You can add additional headers in application adapter, for example:
import ActiveModelAdapter from 'active-model-adapter';
var token = $('meta[name="csrf-token"]').attr('content');
export default ActiveModelAdapter.extend({
headers: {
"X-CSRF-Token": token
}
});
I'm new to Coldfusion and can't understand why I'm having so much trouble adding a couple of headers to an http request that I'm making with cfhttp. I'm trying to write the request using cfscript, and from everything I've read I should be able to simply do:
httpService.addParam(type="header", name="Content-Type", value="application/json");
or
httpService.addParam(type="header", name="Authorization", value=local.authPasscode);
But the outgoing request doesn't seem to contain these headers. I can tell it's not working because:
I'm getting errors back in my response
I'm doing a writeDump(GetHttpRequestData()), which shows all the details of the request (and this output does not show the Authorization header at all and shows the Content-Type header as:
multipart/form-data; boundary=----WebKitFormBoundaryZs9TyOQV02N3fQop
I also seem to have difficulty adding the body of the message in a similar way so I'm thinking I'm doing something wrong with addParam(). I'm attempting that like so:
httpService.addParam(type="body", value="hello");
Again, the response I get back has a bunch of missing field errors and the output of writeDump(GetHttpRequestData()) shows a missing body.
Am I supposed to be able to use addParam() in this way?
Full code:
httpService = new http();
httpService.setMethod("POST");
httpService.setUrl(application.config.beanstream.postURL);
local.authPasscode = "Passcode " & ToBase64(application.config.beanstream.merchantid & ":" & application.config.beanstream.APIPasscode, "utf-8");
// Set headers.
httpService.addParam(type="header", name="Authorization", value=local.authPasscode);
httpService.addParam(type="header", name="Content-Type", value="application/json");
// Construct the message body.
local.body = {
"test": "hello"
};
httpService.addParam(type="body", value=SerializeJSON(local.body));
writeDump(GetHttpRequestData());
local.result = httpService.send().getPrefix();
Update:
Okay, so I changed my postURL to that of another local page and on that page I'm using GetHttpRequestData() to log the method, protocol, headers and content all out to a file. Here's what I get:
POST
HTTP/1.1
{host={www.mysite.com},user-agent={ColdFusion},connection={close},content-length={16},authorization={Passcode Mjc1ODMwMDAwOjIwMTI5NGUwMjI2MzQxMzlBZjBFMDE2RmViRjg0RDAz},content-type={application/json}}
{"test":"hello"}
So it looks to me like I am indeed correctly sending a POST to the correct URL and the headers are getting set correctly as well. My content even seems like it's there so this is starting to feel like I'm sending invalid body data to the API. Unless anybody can think of anything else to check I'm going to investigate that further.
instead of
local.body = {
"test": "hello"
};
try
local.body = {};
local.body["test"] = "hello";
then you can
SerializeJSON(local.body)