Safari 10 does not cache images - asp.net-mvc

I have an ASP.NET MVC website hosted on Azure AppService, and I am trying to enable the caching of dynamic images (served with help of the Controller#File() method) on client-side. I used a few techniques to achieve that:
Converted the query string based URL into the "classic" URL, e.g.
/file/i/Supplier/Logo/fed88a06-1157-4bbb-826d-365bdd8c89eb/png/cng.png
I am using the IIS Rewrite module to convert it back to the query string based URL.
Added the following attribute to the action method which returns the image:
[OutputCache(Duration = 31536000, Location = System.Web.UI.OutputCacheLocation.ServerAndClient)]
//31536000 seconds represent one year
Finally I forced the 304 status on all image requests where the If-Modified-Since header contains a date occurring less than 300 days ago (the images do not change often).
It works in all web browsers except Safari 10 and iOS 10. The images are being cached fine in Sarafi 9, 8, 7, iOS 8.3.3, Chrome, Edge, Firefox but in Safari 10 they are almost never get cached (on iOS 10 too but it is not that important). This condition can be reproduced on two physical Mac laptops as well as on the Mac VM on BrowserStack. Caching in Safari is not disabled.
Is there anything special about Apple's latest web browsers that they don't cache resources as expected? Or, am I doing anything wrong?
I don't know how to review request and response headers in Safari (is it possible at all?) but in Chrome the request and response headers are as follow.
I removed the Host, Referrer and Cookie headers for clarity.
The first run
Request
Accept:image/webp,image/*,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,ru;q=0.6,sr;q=0.4
Cache-Control:no-cache
Connection:keep-alive
DNT:1
Pragma:no-cache
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36
Response
Cache-Control:private, max-age=31533495
Content-Length:32300
Content-Type:image/png
Date:Mon, 17 Oct 2016 14:58:59 GMT
Expires:Tue, 17 Oct 2017 14:17:13 GMT
Last-Modified:Mon, 17 Oct 2016 14:17:13 GMT
Vary:*
X-Frame-Options:SAMEORIGIN
The second run
Request
Accept:image/webp,image/*,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,ru;q=0.6,sr;q=0.4
Connection:keep-alive
DNT:1
If-Modified-Since:Mon, 17 Oct 2016 14:17:12 GMT
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36
Response
Request URL:http://******/file/i/Supplier/Logo/1f70c0ac-309c-4629-9186-6ee1b3700d3e/png/crown-logo.png
Request Method:GET
Status Code:304 Not Modified
Cache-Control:private, max-age=31533237
Date:Mon, 17 Oct 2016 15:03:15 GMT
Expires:Tue, 17 Oct 2017 14:17:12 GMT
Last-Modified:Mon, 17 Oct 2016 14:17:12 GMT
Vary:*
X-Frame-Options:SAMEORIGIN

Related

Why I'm getting 500 error in MVC 4.0 Web application?

I am a web developer,I used to do some updates on website developed in ASP .NET MVC 4.0
Recently we hosted eCommerce website on IIS 10.The website was running very slow, so I had to work for speed optimization, I have only work with images and file compression.
I also use Google web master tools for optimization, during optimization mostly we get 500 internal server error, some urls showing which has not been created yet.
Unfortunately, we are getting 500 error while proceed to Checkout Now. I am not able to figure out why i am getting 500 error? I didn't modify anything in Model and Controller, but i do some changes in View.
Here we proceed to Check Out Now.https://www.preservawellness.com/shoppingcart/cart
Here the page is redirected to Payment options such as Net banking, Credit/debit, PayPal, Paytm
https://www.preservawellness.com/ShoppingCart/OrderReview?subscriptionid=&Ptype=online&uid=282&Ctype=P
When we click on "Place Order" Button The server returns 500 error which we are not able to diagnose. Below is the url after processing request(Place Order button) we are getting internal server error.
https://www.preservawellness.com/ShoppingCart/ProcessToPayment/397
Below is the page error details, we found on Chrome Developer Console(Network)
**Request URL:** https://www.preservawellness.com/ShoppingCart/ProcessToPayment/398
Request Method: GET
Status Code: 500
Remote Address: 103.35.123.182:443
Referrer Policy: no-referrer-when-downgrade
cache-control: private
content-length: 125200
content-type: text/html; charset=utf-8
date: Thu, 13 Dec 2018 06:11:23 GMT
server: Microsoft-IIS/10.0
**status: 500**
x-aspnet-version: 4.0.30319
x-aspnetmvc-version: 4.0
x-powered-by: ASP.NET
:authority: www.preservawellness.com
:**method: GET**
:path: /ShoppingCart/ProcessToPayment/398
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
cache-control: max-age=0
cookie: G_ENABLED_IDPS=google; _ga=GA1.2.1980725648.1544503724; iztoken=; __unam=31c7a61-1679bfb9e68-35018d90-1; UserActivity=ProductID=54,34,35,15,23; _gid=GA1.2.898897304.1544674779; _fbp=fb.1.1544674779709.1169244464; izstatus=1; ASP.NET_SessionId=13itm5jbgar1edaviq1id2fl; __RequestVerificationToken=yg9rIfvgB1xkV_9RGhApwCQydRIbnLFwgh9VLplBUhKnjKmbvDu-Ct2AdANFxppppwPwAN-olzYQUf7sbQrQQ0Sa9KWl-NgPMYzFjI8lypCwrDhqpL8uNsFzK9Y5GeA1fyjSgntOPqluH6E1S3HQvQ2; ispopupopen=30; ispopupopens=10; _gat_gtag_UA_92955094_1=1
referer: https://www.preservawellness.com/ShoppingCart/OrderReview?subscriptionid=&Ptype=online&uid=282&Ctype=P
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1
Error Page:
page with error
IIS must be using * instead of ip address and or host header

IE 10+ doesn't send cookies on cross-origin CSS url() request

I'm trying to show secure images for end user as a div with background (css background-image: url(...)) I have cross-domain configuration where my AngularJS client application is deployed on S3 bucket and server-side (Ruby-on-Rails) is deployed on heroku under different domain name.
All normal browsers are sending the auth cookie(which was set after authentication) within the image request so that server can understand if user has access to that particular image and response according to that.
But somehow IE10 and IE11 doesn't send any cookies on cross-origin requests. But when I set up both servers on the same machine (only ports are different) - everything works fine.
Can anyone help me with this issue?
Update:
Request headers:
Accept image/png, image/svg+xml, image/*;q=0.8, /;q=0.5
Referer my_referrer_url
Accept-Language ru-RU,en-US;q=0.5
User-Agent Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)
Accept-Encoding gzip, deflate
Host my_heroku_serverside_url
DNT 1
Connection Keep-Alive`
Response headers:
Response HTTP/1.1 401 Unauthorized
Server Cowboy
Date Thu, 26 Feb 2015 22:24:04 GMT
Connection keep-alive
Strict-Transport-Security max-age=31536000
X-Frame-Options SAMEORIGIN
X-Xss-Protection 1; mode=block
X-Content-Type-Options nosniff
Content-Type text/html; charset=utf-8
Cache-Control no-cache
X-Request-Id df2154b6-5c6f-4534-bff0-094576359b78
X-Runtime 0.005919
Transfer-Encoding chunked
Via 1.1 vegur
No need to use Restangular you can specify widthCredentials for every $http request like this:
.config(function ($routeProvider, $httpProvider) {
$httpProvider.defaults.withCredentials = true;
I previously answered a similar question like it here: $http doesn't send cookie in Requests
I had a similar issue a few months ago and I solved it using AngularJS with Restangular and then setting, in my JS app configuration:
angular.module('myApp', ['restangular'])
.config(['RestangularProvider', function (RestangularProvider) {
RestangularProvider.setBaseUrl(serverUrl);
RestangularProvider.setDefaultHttpFields({
'withCredentials': true
});
}]);
Everything worked just fine.

Azure-hosted ASP.NET MVC site drops client cache-related HTTP headers

We have recently begun moving some of our ASP.NET MVC websites from our own managed environment to Azure. One of the issues we have seen is that client side caching does not seem to be working properly when delivering dynamically created content. Specifically, the cache-related headers added to the HTTP response in code are stripped.
For example, the following headers are returned on the old environment in order to advise the client that the content may be cached:
Cache-Control: public, max-age=31533144
Content-Disposition: attachment; filename=picture.png
Content-Length: 64326
Content-Type: image/png
Date: Tue, 23 Jul 2013 15:44:57 GMT
Etag: "845D3DD630A7AEF5B68EA7A09B670A4D"
Expires: Fri, 23 Aug 2013 14:57:22 GMT
Last-Modified: Tue, 23 Jul 2013 14:57:22 GMT
Server: Microsoft-IIS/7.5
But on Azure, the following headers are returned instead:
Content-Disposition: attachment; filename=picture.png
Content-Length: 64326
Content-Type: image/png
Date: Tue, 23 Jul 2013 15:44:57 GMT
Server: Microsoft-IIS/8.0
X-Powered-By: ARR/2.5, ASP.NET
As you can see, the Cache-Control, Etag, Expires and Last-Modified headers have been dropped.
I have seen a number of suggestions regarding the caching of static content, but I do not believe that these will help in this case. Is it a case that the structure of the Azure CDN prevents caching in this way? Should Azure blobs be used instead? Is there a basic configuration change that may have been overlooked?
Thanks in advance
X-Powered-By: ARR/2.5, ASP.NET
ARR stands for Application Request Routing.
Go to inetmgr UI and click on the server name and you will find the option 'Application Request Routing Cache'.
You'll see 'Cache configuration', check options there. Also, check 'Cache control rules' there. Click 'Add rule...' and try play around with it.
Azure Websites site behind ARR. ARR will drop some HTTP headers and add its own, it's not something you have direct control over. A better fit for your problem may be using Azure CDN for static content. This does pay attention to and use the cache control headers. You can run a CDN on top of a blob storage container.

INDY - I really need cookies here?

I'm developing a project to auto-login in my router administration page... But it use cookies in the source code. When I do a GET with my web browser (Chrome), I get this:
GET http://192.168.1.1/ HTTP/1.1
Host: 192.168.1.1
Proxy-Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: FirstMenu=Admin_0; SecondMenu=Admin_0_0; ThirdMenu=Admin_0_0_0; Language=en
And when I'm doing a GET with Indy the result is:
GET http://192.168.1.1/ HTTP/1.1
Host: 192.168.1.1
Accept: text/html, */*
Accept-Encoding: identity
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV2)
Ok, I want to login doing a POST in the url same way that the HTML form does, passing the same parameters, but as result, I get one page saying 'Unknown Error'...
Here is when I'm doing the POST in my Chrome browser:
POST http://192.168.1.1/index/login.cgi HTTP/1.1
Host: 192.168.1.1
Proxy-Connection: keep-alive
Content-Length: 34
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Origin: http://192.168.1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://192.168.1.1/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: SessionID_R3=479900075; FirstMenu=Admin_0; SecondMenu=Admin_0_0; ThirdMenu=Admin_0_0_0; Language=en
Username=admin&Password=YWRtaW4%3D
Here is the post in my project with Indy:
POST http://192.168.1.1/index/login.cgi HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 36
Proxy-Connection: keep-alive
Host: 192.168.1.1
Accept: text/html, */*
Accept-Encoding: identity
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV2)
Username=admin&Password=YWRtaW4%3D
Okay, I'm almost sure that i'm getting this 'unknown error' because of the cookies. But they are really needed here? And how I'll setup them? I tried with cookies manager but no success, and I'm in Delphi 2010, dont know if Cookies Manager from Indy works fine in this version. Here is the code of my project:
http := TIDHttp.Create(nil);
PostData:= TStringList.Create;
AnswerData:= TStringStream.Create('');
http.ReadTimeout := 5000;
http.Request.UserAgent:='Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV2)';
http.ProxyParams.ProxyServer:= '127.0.0.1';
http.ProxyParams.ProxyPort:= 8080;
PostData.Text:= 'Username=admin&Password=YWRtaW4=';
try
http.Post('http://192.168.1.1/index/login.cgi', PostData, AnswerData);
except
on E: EIdHTTPProtocolException do
begin
HttpCode:= HTTP.ResponseCode;
HttpHeader:= HTTP.Response.RawHeaders.Values['Server'];
end;
end;
Memo1.Lines.Add(AnswerData.DataString);
end;
The web browser's requests are including a previously received cookie that you obviously have not received yet. You need to start at the same starting page that the web browser started at to receive the cookie. Also, because you are sending multiple requests, you need to make sure that you are re-using the same TIdCookieManager instance every time, so that cookies persist between requests. If you do not assign a TIdCookieManager to the TIdHTTP.CookieManager property, TIdHTTP creates one internally, so you either need to re-use the same TIdHTTP for each request, or you need to create a single TIdCookieManager that you assign to each TIdHTTP you create.
In this case, I just created one 'fake' cookie just passing in the header the same parameters as browser does... The router page used javascript cookies, so Indy could not work with them, I'll need to add them manually if necessary. But for me worked in this way:
http.Request.CustomHeaders.Text:= 'Cookie: FirstMenu=Admin_0; SecondMenu=Admin_0_0; ThirdMenu=Admin_0_0_0; Language=en';
I just put the cookie as header, in fact I have no cookie manager, only this fake header... For me it solved.

possible to get POSTed parameters and RESPONSE content in Opera Dragonfly?

When I look at the Network tab in Opera Dragonfly, I'm not seeing POSTEd parameters or the RESPONSE content. Here's what I see:
Raw Response
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Thu, 15 Jul 2010 12:43:19 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: text/html; charset=utf-8
Content-Length: 22320
In Dragonfly, is there a way to examine the parameters posted to the server and the actual response from the server?
The ability for Opera Dragonfly to get this information from the Opera rendering engine (Presto) should be included in Opera 11. We are currently working on implementing the client side code in Opera Dragonfly to support this and other Network Inspector features, such as editing headers and replaying requests.
EDIT:
As of July 2011 (Opera Dragonfly 1.1) it is possible.
To see POST parameters in Opera Dragonfly click on Network tab followed by Network log subtab. NOTE: It requires reloading the page, if the page was already loaded while opening Opera Dragonfly.
Not yet. Microsoft Fiddler HTTP debugger is a good replacement if you have an OS to run it on.

Resources