How does web (axios) cache works? - django

When server caches a page, I thought it worked like this, but apparently I'm wrong.
server stores http response contents in a cache-store with a key (that's generated for the endpoint)
one could create separate cache key for certain aspects of requests (such as user language)
when there's a request for the same key, and it's stored in cache-store (such as redis), webserver returns the cached response instead of recreating the response
I think the above understanding is flawed because,,
when I hit the endpoint with axios, first request is hit on the server, but the second request doesn't even hit the endpoint, it seems axios is reusing the previous response it received.
So, if I clear all cache store between two requests, the second request doesn't get to the request handler (view function in django)
for http request (browser reload) does work as I described in the above, it hits the web server and gets the cached response.
In django, I'm using from django.views.decorators.cache import cache_page
But the question is more of general working of web response cache
General web caching is explained very well here * https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching
I guess certain client never reaches out to server when cache-control timeout or expires is set, and some client does reach out to server..

Related

cypress browser sends all cookies in all requests

I am using cypress for e2e testing with the session storage feature enabled.
Until recently the only two cookies in the project were "access_token" and "refresh_token". Now I added 2 more cookies which store some data which will automatically be written and read while you're using the website.
When browsing the website with any native browser (chrome, firefox, edge), no cookies get sent by the frontend to the backend in the request. Only the "access_token"s content will be used as the Authentication bearer.
When browsing in any browser inside cypress or letting cypress automatically browse, all cookies which exist will be added to every sent request. Not only requests sent by cy.request() but also the requests which the frontend natively sends.
This is a problem since the header size gets to large and the backend wont accept it. The quickfix was to increase the accepted header size in the backend but I'd prefer not sending the cookies at all.
Is there a way to tell cypress which cookies to send or prevent sending cookies at all? I don't really care which cookies will be stored in the cypress session. Only which cookies get sent.
EDIT:
All cookies use "strict" same site settings.
When testing against a deployed system https is used but with an invalid certificate.
When testing against a locally running system http is used.
The cookies only get sent when running cypress against a local system (localhost).
Using samesite=strict means that the cookie will never be included in requests to other sites, so I guess that is your core problem here. You need to use samesite=none to get cookies included in HTTP POST Request across sites.

AWS nginx as a service?

I'm looking for a service that allows me to proxy/modify incoming requests inside AWS.
Currently I am using cloudfront, but that has limited functions.
I need to be able to see user agent strings and make proxy decisions based on that - like reverse proxying to another domain, or routing all requests to /index.html.
Anyone know of a service that within AWS - or outside of AWS.
It sounds like you are describing Lambda#Edge, which is a CloudFront enhancement that allows you to define Lambda functions that will fire at any of 4 hook points in the CloudFront signal flow, and modify the request or generate a dynamic response.
Viewer Request triggers allow inspection/modification of requests and dynamic generation of small responses before the cache lookup.
Origin Request triggers are similar, but fire after the cache is checked. They allow you to inspect and modify the request, including changing the origin server, path, and/or query string, or to generate a response instead of allowing CloudFront to proceed with the connection to the origin.
If the request goes to the origin, then once it returns, an Origin Response trigger can fire to modify the response headers or replace the response body with a different body you generate. The response after this trigger is finished with it is what gets stored in the cache, if cacheable.
Once a reaponse is cached, further firing of the Origin Request and Origin Response triggers doesn't occur for subsequent requests that can be served from the cache.
Finally, when the response is ready, whether it came from the cache or the origin, a Viewer Response trigger can modify it further, if desired.
Response triggers can also inspect many of the headers from the original request.
Lambda#Edge functions are written in Node.js, and are presented with the request or responses as simple structured objects that you inspect and/or modify.

Best way to cache statistics that don't change often

I am writing a django app and as part of the job I need to crunch some data and generate statistics and serve them on a RESTful API. The statistics don't change that often, however when the statistics do change, the next request needs to serve the most up to date request. What I am currently doing is using a caching mechanism like django-redis to store the statistics and when a request is made, the view calls the cache client and serve its content. What I would prefer is a caching mechanism that prevents my view from ever being called and also provides up to date content. Is there such away (django plugin) that would allow me to do this?
One way to accomplish this would be to use a 'reverse proxy cache' such as Nginx or Varnish.
Basically when a request would be made to your Django application, it would first pass through your proxy cache. The proxy cache would check to see if the request is available in the cache, and if so, it would serve the response from cache. If the request isn't in the cache, it would hand the request off to django to process te request and issue a response. The response would then pass back through the proxy cache and set the contents of the response into cache so that subsequent requests use the response from the cache.
Invalidating items in the cache per a write through policy as updating an item in the database could accomplished by issuing a cache purge command that is specific to the reverse proxy cache server that you have installed.

Ember Data sending OPTIONS requests after save

After sucessfully updating an ember-data model, ember-data sends an OPTIONS request.
First of all, I would like to know why it sends an OPTIONS request.
And the actual problem is, that this options request is sent to the "location" where the put request returned from. Which is problematic because, I am using grunt-proxy and forward my requests to another domain. But the response from my PUT of course has this "other" domain as location. And the OPTIONS request ist then sent directly to this domain, which is of course not working due to CORS requests.
Additional Comment:
I found out that my PUT request returns a 302 Temporarily moved. I have to be honest, I have no idea, why because when I request my put Endpoint directly with some data, I never get a 302, always 204.
Could this be the reason why ember-data making the OPTIONS request?

Does every web request send the browser cookies?

Does every web request send the browser's cookies?
I'm not talking page views, but a request for an image, .js file, etc.
Update
If a web page has 50 elements, that is 50 requests. Why would it send the SAME cookie(s) for each request, doesn't it cache or know it already has it?
Yes, as long as the URL requested is within the same domain and path defined in the cookie (and all of the other restrictions -- secure, httponly, not expired, etc) hold, then the cookie will be sent for every request.
As others have said, if the cookie's host, path, etc. restrictions are met, it'll be sent, 50 times.
But you also asked why: because cookies are an HTTP feature, and HTTP is stateless. HTTP is designed to work without the server storing any state between requests.
In fact, the server doesn't have a solid way of recognizing which user is sending a given request; there could be a thousand users behind a single web proxy (and thus IP address). If the cookies were not sent every request, the server would have no way to know which user is requesting whatever resource.
Finally, the browser has no clue if the server needs the cookies or not, it just knows the server instructed it to send the cookie for any request to foo.com, so it does so. Sometimes images need them (e.g., dynamically-generated per-user), sometimes not, but the browser can't tell.
Yes. Every request sends the cookies that belong to the same domain. They're not cached as HTTP is stateless, what means every request must be enough for the server to figure out what to do with it. Say you have images that are only accessible by certain users; you must send your auth cookie with every one of those 50 requests, so the server knows it's you and not someone else, or a guest, among the pool of requests it's getting.
Having said that, cookies might not be sent given other restrictions mentioned in the other responses, such as HTTPS setting, path or domain. Especially there, an important thing to notice: cookies are not shared between domains. That helps with reducing the size of HTTP calls for static files, such as the images and scripts you mentioned.
Example: you have 4 cookies at www.stackoverflow.com; if you make a request to www.stackoverflow.com/images/logo.png, all those 4 cookies will be sent.
However, if you request stackoverflow.com/images/logo.png (notice the subdomain change) or images.stackoverflow.com/logo.png, those 4 cookies won't be present - but maybe those related to these domains will.
You can read more about cookies and images requesting, for example, at this StackOverflow Blog Post.
No. Not every request sends the cookies. It depends on the cookie configuration and client-server connection.
For example, if your cookie's secure option is set to true then it must be transmitted over a secure HTTPS connection. Means when you see that website with HTTP protocol then these cookies won't be sent by browsers as the secure flag is true.
3 years have passed
There's another reason why a browser wouldn't send cookies. You can add a crossOrigin attribute to your <script> tag, and the value to "anonymous". This will prevent cookies to be sent to the destination server. 99.9% of the time, your javascripts are static files, and you don't generate that js code based on the request's cookies. If you have 1KB of cookies, and you have 200 resources on your page, then your user is uploading 200KB, and that might take some time on 3G and have zero effect on the result page. Visit HTML attribute: crossorigin for reference.
Cookie has a "path" property. If "path=/" , the answer is Yes.
I know this is an old thread. But I've just noticed that most browsers won't sent cookies for a domain if you add a trailing dot. For example http://example.com. won't receive cookies set for .example.com. Apache on the other hand treats them as the same host. I find this useful to make cross domain tracking more difficult for external resources I include, but you could also use it for performance reasons. Note this brakes validation of https certificates. I've run a few tests using browsershots and my own devices. The hack works on almost all browsers except for safari (mobile and desktop), which will include cookies in the request.
Short answer is Yes. The below lines are from the JS documentation
Cookies were once used for general client-side storage. While this was legitimate when they were the only way to store data on the client, it is now recommended to use modern storage APIs. Cookies are sent with every request, so they can worsen performance (especially for mobile data connections).