How and where to set Access-Control-Expose-Headers for koa-cors - header

I am attempting to get some headers sent from my server to my front end via a fetch request.
In the controller function, I am explicitly sending some headers like this:
exports.getItems = async (ctx) => {
ctx.set('Search-type', 'category');
};
In postman, when I make a get request to my server I get these headers:
Connection →keep-alive
Content-Length →6442
Content-Type →application/json; charset=utf-8
Date →Thu, 19 Apr 2018 16:10:54 GMT
Search-type →category
However, when I try to access the header in the fetch request from the front end, I can only log the Content-Type. How do I get Search-type from my fetch?
After some googling, I found this issue on github which seems very similar to mine. This led me to another github issue page with the suggestion that I need to 'expose some explicitly needed headers'.
In the koa/cors documentation, there is an option allowHeaders Access-Control-Allow-Headers what I want to know is, how do I expose the headers so I can get them on my front end?

In the response to the GET, in addition to adding the Access-Control-Allow-Origin response header, you also need to include the Access-Control-Expose-Headers: <comma-separated-list-of-headers> response header.
If that header isn't returned by the server, even though the headers are sent by the server to the browser, the browser blocks any non-standard headers from being accessed by JavaScript. So you can see Content-Type (because it's a 'standard' response header), but not Search-type.
Basically, you need to ensure that the server responds with this
Access-Control-Expose-Headers: Search-type
(in addition to any other CORS response headers, like Access-Control-Allow-Origin, of course).

Related

How do ETags in the HTTP header actually work?

I don't know if I am not correctly understanding how the caching aspect of ETags work if there is some other issue I am dealing with, but I'll walk you through my situation.
From my understanding ETags are a unique hash that is created based on the file information and they are sent as part of Response header to uniquely identify the file. If the file is updated then the info is changed and hence the ETag for the file is also changed.
In my project, I need a fresh JS file to be fetched everytime I make changes to the file. I can't use version tags or unique hashes as part of the file name. I thought an ETag would work where
Http Request
GET myFile.js
Client ------------------> SERVER
Http Response 200
Http Response Header
accept-ranges: bytes
cache-control: max-age=86400, public
etag: "a7-58c3bb52101c4"
......
myFile.js
Client <------------------ SERVER
// myFile.js has not been changed
Http Request
GET myFile.js
Client ------------------> SERVER
Http Response 304
Http Response Header
accept-ranges: bytes
cache-control: max-age=86400, public
etag: "a7-58c3bb52101c4"
......
Client uses cached version of file
// myFile has been changed
Http Request
GET myFile.js
Client ------------------> SERVER
Http Response 200
Http Response Header
accept-ranges: bytes
cache-control: max-age=86400, public
etag: "88-58c3a1cb8474f" // new etag generated
......
myFile.js
Client <------------------ SERVER
So, if you request the file again and no changes have been made..the etag will remain the same and you'll get a 304 will indicate that the cached version should be used.
If the file has been changed the etag will be different as well and a fresh copy of the file will be sent by the server.
This is how I expected it to work.
MY PROBLEM:
When I update myFile.js it seems like I never get the new ETag has back. It just defaults to the cahced version of the file. If I clear the cache then I get the latest file and the new ETag. This to me seems to defeat the purpose. Is this how it works or am I understanding something incorrectly here?

How to Hide Allow: POST, GET, OPTIONS, HEAD and server name in tomcat response

< HTTP/1.1 405 Method Not Allowed
< Allow: POST, GET, OPTIONS, HEAD
< Content-Length: 0
< Date: Fri, 26 May 2017 12:05:36 GMT
< Server: myservername
Hi whenever i do a curl request to my application using HTTP TRACE method . The above response displays .
Can someone tell me the steps to hide the "Allow: POST, GET, OPTIONS, HEAD" and "Server: myservername" information. How to hide these two in my TOMCAT6
By default Tomcat automatically responds to TRACE requests with a status code 405 and the headers you showed.
To change this behaviour you can do the following:
Allow TRACE requests to reach your servlets. This is done by settings the allowTrace attribute to true on a connector: https://tomcat.apache.org/tomcat-5.5-doc/config/http.html#Common_Attributes
In your servlet detect and handle the TRACE request and the send only the headers you want to send.
I think you should not take so much attention about that.
You launched a HTTP request with the method TRACE.
The answer tells you that method TRACE is not supported (Status 405) and provides available and supported method in the header Allow : POST, GET, OPTIONS, HEAD
All of this is perfectly acceptable and seems like a normal behaviour.
About the Server header, you have some details here

Strange case of HTTP headers: If-Modified-Since and If-None-Match

As part of a test application, I'm making HTTP requests to webpages. On receiving a response, I save the current date/time (GMT) and ETag header for subsequent requests. However, for some strange reason, some host servers are not validating the If-Modified-Since and If-None-Match headers on subsequent requests.
One such example is this webpage: www.foxsports.com/nba/cleveland-cavaliers-team-news (running Apache). It always returns the full body with a 200-Ok HTTP status, when a 304-NotModified status is expected, hence ignoring the If-Modified-Since and If-None-Match headers sent in the request. I tested it using curl and online Hurl.
Any ideas why the sent request headers are not validated by some host servers?

CORS complaint on Safari 5.1.7 (windows 7)

A page at http://www4.example.com that tries to an xhr connection to http://www6.example.com/
The browser sends a GET request with this header:
Origin: http://www4.example.com
The www6.example.com server sends back:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://www4.example.com
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/plain
Date: ...
Keep-Alive: timeout=5, max=100
Transfer-Encoding: Identity
Server: Apache/2.2.20 (Ubuntu)
Vary: Accept-Encoding
X-Powered-By: PHP/5.3.6-13ubuntu3.7
And yet I get:
XMLHttpRequest cannot load http://www6.example.com/myscript.php?xhr=1&t=1234333223. Origin http://www4.example.com is not allowed by Access-Control-Allow-Origin.
My code matches my understanding of the CORS standard, and works fine with Chrome, Firefox, Opera, etc. so I'm going to assume this is a Safari 5.1 bug? My question is what do I need to do to work around it?
After a lot of trial and error, and watching network traffic, I think I can self-answer.
The Safari bug is that it sends an OPTIONS pre-flight request first, even though it is a GET request.
To add some extra complexity, it appears to only send this on the 2nd request. (I think this is because my 2nd request sends an extra custom header... but I couldn't actually isolate that, so I think there is something else going on as well - perhaps cache interactions?)
Sending Access-Control-Allow-Headers in the main response does not fix the problem: it does the OPTIONS request first, so never gets that far.
The fix I did was to put this at the very top of the PHP script:
if($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
header("Access-Control-Allow-Origin: ".#$_SERVER['HTTP_ORIGIN']);
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Headers: Last-Event-Id, Origin, X-Requested-With, Content-Type, Accept, Authorization");
exit;
}
Sending back "Access-Control-Allow-Headers: *" did not work. You have to explicitly list the headers you want. I briefly experimented and it appears they are case-insensitive.
Sending back "Access-Control-Allow-Methods: POST, GET, OPTIONS" was not needed.
As an aside, Cookies are sent, but basic auth details are not sent (despite explicitly listing the Authorization header there). This might be a deliberate limitation of the CORS implementation, as of this version of WebKit (534.57.2), not a bug.

How to get a long url from a short url

I would like to determine what the long url of a short url is. I have tried using http HEAD requests, but very few of the returned header fields actually contain any data pertaining to the destination/long url.
Is there:
1. Any way to determine the long url?
2. If so, can it be done without downloading the body of the destination?
Thank you
Issue an HTTP GET request, don't follow the redirect, analyse the Location header. That's where the target of redirection is.
Specifically in Cocoa, use an asynchronous request with a delegate, handle the didReceiveResponse in the delegate. The first response will be the redirection one. Once you extract the URL in the handler, call [cancel] on the connection.
EDIT: depending on the provider, HEAD instead of GET might or might not work. And if you don't follow the redirect, the response data won't be loaded anyway, so there's no transmission overhead to having a GET.
Do a HEAD and look for the Location header.
% telnet bit.ly 80
Trying 168.143.173.13...
Connected to bit.ly.
Escape character is '^]'.
HEAD /cwz5Jd HTTP/1.1
Host: bit.ly
HTTP/1.1 301 Moved
Server: nginx/0.7.42
Date: Fri, 12 Mar 2010 18:37:46 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Set-Cookie: _bit=4b9a89fa-002bd-030af-baa08fa8;domain=.bit.ly;expires=Wed Sep 8 14:37:46 2010;path=/; HttpOnly
Location: http://www.engadget.com/2010/03/12/motorola-milestone-with-android-2-1-hitting-bulgaria-by-march-20/?utm_source=twitterfeed&utm_medium=twitter
MIME-Version: 1.0
Content-Length: 404
LongUrlPlease offers an API which expands short urls.