this code snippet is taken from Postman. cURL taken from the postman works fine and java code generated from postman gives a 200 response for the particular call. but the response body is not there.
what should be the user agent header?
Do I need to use this postman token in my java code as well?
Do I need to add additional headers?
My Goal is to fetch some data from this GET call.
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://blahblah=60041441&attributes=blah,blah,blah")
.get()
.addHeader("User-Agent", "PostmanRuntime/7.13.0")
.addHeader("Accept", "*/*")
.addHeader("Cache-Control", "no-cache")
.addHeader("Postman-Token", "7af03a15-blah,364c160f-92d7-459f-b261-4993801944a7")
.addHeader("Host", "blahblah.na.blah.net:9081")
.addHeader("cookie", "someURL=1800; com.ibm.isim.lastActivity=blahblahToekn; JSESSIONID=blahblahblah:1ajblahi8; LtpaToken2=blahblahbalah")
.addHeader("accept-encoding", "gzip, deflate")
.addHeader("Connection", "keep-alive")
.addHeader("cache-control", "no-cache")
.addHeader("User-Agent", "postman")
.build();
okhttp3.Response response= client.newCall(request).execute();
System.out.println(response.body().toString());
Suppose for simple get request following will do just fine, all other details can be omitted:
Request request = new Request.Builder()
.url("http://blahblah=60041441&attributes=blah,blah,blah")
.get()
.build();
Most of the headers (like user-agent, accept-encoding etc) will be automatically added by OkHttp client, so you can safely remove those from request:
.addHeader("User-Agent", "PostmanRuntime/7.13.0")
.addHeader("Host", "blahblah.na.blah.net:9081")
.addHeader("accept-encoding", "gzip, deflate")
.addHeader("Cache-Control", "no-cache")
.addHeader("Connection", "keep-alive")
.addHeader("cache-control", "no-cache")
.addHeader("User-Agent", "postman")
Since / is a wildcard, suppose you can skip it as well.
.addHeader("Accept", "*/*")
If you endpoint requires authentication, suppose before sending this particular Get request you need to send authentication request first. To automatically handle authentication cookies you can try to add CookieJar to your client, so those can be omitted as well (assume headers names were altered somehow, btw?):
.addHeader("Postman-Token", "7af03a15-blah,364c160f-92d7-459f-b261-4993801944a7")
.addHeader("cookie", "someURL=1800; com.ibm.isim.lastActivity=blahblahToekn; JSESSIONID=blahblahblah:1ajblahi8; LtpaToken2=blahblahbalah")
You can also check answers for that question about the ways to add CookieJar.
Related
As I see from the answer for this question: Karate will automatically send any cookies returned by the server in the next request.
But when I send the request I see two sets of cookies in Set-Cookie of response: one is auto-created and another is real, that returned from the server.
When I printed responseCookies, I saw there only automatic cookies
and for the next request new cookies are generated and sent.
For my test I need to use cookies returned after the first request because it is a call to login service.
Feature: Using cookies in next request
Background:
Given url baseUrl
And path LOGOUT_SERVICE_ENDPOINT
And configure headers = read('classpath:headers.js')
And def filename = 'classpath:resources/users/' + brand.toLowerCase() + '/user.json'
And json user = read(filename)
Scenario: Login
When def login = callonce read('classpath:features/login_service/login.feature') user
* print login.responseCookies
And request { arg1: '#(brand)'}
And method post
Then status 200
What is wrong in my feature or it is Karate issue?
two sets of cookies in Set-Cookie of response:
Maybe that is a bug in the server ?
Also try using "shared scope", because cookies also will be part of the "global" variables etc.
* callonce read('classpath:features/login_service/login.feature') user
* request { arg1: '#(brand)'}
If you are still stuck, please follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue
I have created an API using AWS api gateway like https://api.mydomain.com/v1/download?id=1234". The download resource has GET method. And the GET method is invoking lambda function using Lambda Proxy Integration.
The Lambda function needs to act as Proxy. It needs to resolve correct backend endpoint based on header x-clientId and then forward the request to that backend endpoint and return response as it is. So it needs to be generic to handle GET request of different content-type.
My lambda function looks like ( .NET Core)
public async Task<APIGatewayProxyResponse> Route(APIGatewayProxyRequest input, ILambdaContext context)
{
var clientId = headers["x-clientId"];
var mappings = new Mappings();
var url = await mappings.GetBackendUrl(clientId, input.Resource);
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
var proxyResponse = new APIGatewayProxyResponse()
{
Headers = new Dictionary<string, string>(),
StatusCode = (int)System.Net.HttpStatusCode.OK,
IsBase64Encoded = false,
Body = await response.Content.ReadAsString())
};
}
The handler above works as long as request and response's content-type is application/json or application/xml. However i am not sure how to handle response when backend returns stream.
For download API, the backend returns Content-Disposition: attachment; filename="somefilename and ContentType may be one of the following:
application/pdf
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
application/vnd.openxmlformats-officedocument.wordprocessingml.document
application/x-zip-compressed
application/octet-stream
For these streams, How do i set APIGatewayProxyResponse.Body?
For Excel file I have tried setting body like below
var proxyResponse = new APIGatewayProxyResponse()
{
Headers = new Dictionary<string, string>(),
StatusCode = (int)System.Net.HttpStatusCode.OK,
IsBase64Encoded = true,
Body = Convert.ToBase64String(await response.Content.ReadAsByteArrayAsync())
};
proxyResponse.Headers.Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
proxyResponse.Headers.Add("Content-Disposition", "attachment; filename=\"Report.xlsx\"");
When i access the Url from the browser and try to open the file. I get error
Excel cannot open the fileReport.xlsxbecuase the file format or file extension is not valid. Verify that the file has not been corrupted and that the extention matches the format of the file
I think the issue is how i am setting the response body
Update 1
So based on AWS doc Binary Data Now Supported by API Gateway. Now as per the documentation
you can specify if you would like API Gateway to either pass the
Integration Request and Response bodies through, convert them to text
(Base64 encoding), or convert them to binary (Base64 decoding). These
options are available for HTTP, AWS Service, and HTTP Proxy
integrations. In the case of Lambda Function and Lambda Function Proxy
Integrations, which currently only support JSON, the request body is
always converted to JSON.
I am using Lambda Function Proxy, which currently support JSON. However the example here shows how to do it with Lambda Proxy.
I think what i am missing here is Binary Media Types setting and Method Response settings. Below is my setting. Not sure if these settings are correct
Binary Media
Method Response
here how solved it
1>add Binary Media Types. API->Settings->Binary Media Types -> add
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
2>In Method Response Add Content-Disposition and Content-Type headers for thestatus 200
3>In Integration Response map these headers to headers that are coming from the backend. And also set content handling convert to binary. (our backend api is returning file blob in body)
This is a good way to grab the request before the response: useragent = getHttpRequestData().headers["User-Agent"];
What I noticed is that it will not grab the request unless it is on the actual list of header request. An example is I that it seems to only pull the basic request data. For instance if I set the cache control in the web.config file it does set cache, max age and etag, but when setting etags = getHttpRequestData().headers["ETag"]; and trying to output the data for the ETag generated by the web.config file/server it will not grab the ETag data to output. A few others that I tested are:
useragent = getHttpRequestData().headers["User-Agent"];
acceptencoding = getHttpRequestData().headers["Accept-Encoding"];
acceptlanugage = getHttpRequestData().headers["Accept-Language"];
cachecontrol = getHttpRequestData().headers["Cache-Control"];
connection = getHttpRequestData().headers["Connection"];
accept = getHttpRequestData().headers['Accept'];
contentlength = getHttpRequestData().headers['Content-Length'];
Request data is sent from the browser. You can see that with ColdFusion. But IIS sets response headers (such as etag) after ColdFusion is done processing. It's a response not a request. You cannot see that with ColdFusion, but you can in your browser. EX:
I'm doing a BrowserClient POST across domains and don't see my cookies being included.
This the response I'm getting:
When I send another POST request, I don't see the cookies being included:
Going straight to the test page, I can see the cookies being included:
The Dart code I use to make a POST:
var client = new BrowserClient();
client.post(url, body: request, headers:{"Content-Type" : "application/json", "Access-Control-Allow-Credentials":"true"}).then((res) {
if (res.statusCode == 200) {
var response = JSON.decode(res.body);
callback(response);
} else {
print(res.body);
print(res.reasonPhrase);
}
}).whenComplete(() {
client.close();
});
Not sure about the Access-Control-Allow-Credentials header I'm including, with or without it, nothing changes.
Am I missing headers on the server side that needs to be set on the response or is Dartium blocking cross-domain cookies?
More details on Information Security and the reasoning behind setting cookies via the server.
Update: Enhancement request logged: https://code.google.com/p/dart/issues/detail?id=23088
Update: Enhancement implemented, one should now be able to do var client = new BrowserClient()..withCredentials=true; based on
https://github.com/dart-lang/http/commit/9d76e5e3c08e526b12d545517860c092e089a313
For cookies being sent to CORS requests, you need to set withCredentials = true. The browser client in the http package doesn't support this argument. You can use the HttpRequest from dart:html instead.
See How to use dart-protobuf for an example.
I am trying to send mails with attachment by using Amazon SES
HttpRequest httpReq = new HttpRequest();
httpReq.setMethod('POST');
httpReq.setEndpoint('https://email.us-east-1.amazonaws.com');
Blob bsig = Crypto.generateMac('HmacSHA256', Blob.valueOf(awsFormattedNow), Blob.valueOf(secret));
httpReq.setHeader('X-Amzn-Authorization','AWS3-HTTPS AWSAccessKeyId='+key+', Algorithm=HmacSHA256, Signature='+EncodingUtil.base64Encode(bsig));
httpReq.setHeader('Date',awsFormattedNow);
httpReq.setHeader('From','sample#gmail.com');
httpReq.setHeader('To','sample#gmail.com');
httpReq.setHeader('Subject','Hello');
httpReq.setHeader('Accept-Language','en-US');
httpReq.setHeader('Content-Language','en-US');
httpReq.setHeader('Content-Type','multipart/mixed;boundary=\"_003_97DCB304C5294779BEBCFC8357FCC4D2\"');
httpReq.setHeader('MIME-Version','1.0');
// httpReq.setHeader('Action','SendRawEmail');
String email = 'Action=SendRawEmail';
email += '--_003_97DCB304C5294779BEBCFC8357FCC4D2 \n Content-Type: text/plain; charset="us-ascii" \n Content-Transfer-Encoding: quoted-printable \n';
email +='Hi Andrew. Here are the customer service names and telephone numbers I promised you.';
httpReq.setBody(email);
System.debug(httpReq.getBody());
Http http = new Http();
HttpResponse response = http.send(httpReq);
I am getting error like
<AccessDeniedException>
<Message>Unable to determine service/operation name to be authorized</Message>
</AccessDeniedException>
Kindly please help me where i am doing wrong .Thanks in advance
Take another look at the documentation. There are several issues with your code.
SES expects an HTTP POST with all of the parameters strung together consistent with application/x-www-form-urlencoded POST requests.
Your HTTP request needs to be Content-type: application/x-www-form-urlencoded, not multipart/mixed... -- that's part of the raw message you're trying to send.
You are mixing up things that should be in the body, and setting HTTP request headers, instead. For example, these are also incorrect:
httpReq.setHeader('From','sample#gmail.com');
httpReq.setHeader('To','sample#gmail.com');
httpReq.setHeader('Subject','Hello');
These should go in the request body, not in the HTTP request headers. Also, the values are urlencoded. From the example code:
Action=SendEmail
&Source=user%40example.com
&Destination.ToAddresses.member.1=allan%40example.com
The line breaks were added for clarity.
Your interests might be best served by trying to successfully send a simple e-mail, first, and then later attempting to modify your code to support attachments, because you have numerous errors that will need to be corrected before this code will work properly.
http://docs.aws.amazon.com/ses/latest/DeveloperGuide/query-interface-requests.html
http://docs.aws.amazon.com/ses/latest/APIReference/API_SendRawEmail.html