http headers 與 cache 機制

30
HTTP HEADERS 與 CACHE 與與 與與與 (ANSON CHEN)

Upload: -

Post on 15-Jan-2017

1.751 views

Category:

Software


1 download

TRANSCRIPT

Page 1: Http Headers 與 Cache 機制

HTTP HEADERS 與 CACHE 機制陳振揚 (ANSON CHEN)

Page 3: Http Headers 與 Cache 機制

AGENDA

1. 常見的 Http Headers2. Cache 的使用情境與最佳化3. Code example (.NET MVC - Web API) Code example (Android - okhttp)

Page 4: Http Headers 與 Cache 機制

https://github.com/

Page 5: Http Headers 與 Cache 機制
Page 6: Http Headers 與 Cache 機制

Http Header 是我們在向目標 Server 要求或取得內容時,依附在上面的一些屬性或參數

不管是使用哪一種 method , GET.POST.DELETE 還是 PUT 等等… . 都可以使用 Header 來傳遞資料

Header 分為三種- Request( 請求 ) 、 Response( 回應 ) 、 General( 通用 ) 

WHAT ARE HTTP HEADERS?

Page 7: Http Headers 與 Cache 機制

名稱 範例 簡介Date Wed, 20 Apr 2016 08:46:31

GMT時間戳記

Cache-Control no-cache,max-age=30 表示使用何種 Cache 機制,經常使用的 directive

有: no-store , no-cache , public , private , max-age

Pragma no-cache 表示使用何種 Cache 機制 ( 在 Http 1.1 後都改為參考 Cache-Control 了 )

Expires -1 表示 Cache 時間 ( 在 Http 1.1 後都改為參考 Cache-Control 了 )

General headers

Page 8: Http Headers 與 Cache 機制

名稱 範例 簡介Content-Length 145698 回應的內容長度Content-Type application/json 回應的格式,常見的有 text/html( 網頁 ) 、 text/

plain( 無格式純文字 ) 、 application/json(JSON 格式 ) 、application/xml(XML 格式 ) 、 text/xml(XML 格式 )

Content-Language en 回應的語言Content-Encoding gzip 回應的內容壓縮方式Server Microsoft-IIS/8.5 表示何種技術的 web server

ETag "12345678" Cache 機制中的 * 內容驗證權杖,需要用引號 ("") 包住Last-Modified Wed, 20 Apr 2016

08:46:31 GMTCache 機制中的 * 時間驗證權杖,需使用 Universal Time

X-Powered-By ASP.NET 表示何種技術的 web service ,特別說明一下, X 開頭系列的 Header 通常是非標準 ( 各個語言自定義的 ) ,雖說是非標準,但有些 X 開頭的 Header 幾乎是很常見的

X-Version 4.0.30319 web service 當前版本

Response headers

Page 9: Http Headers 與 Cache 機制

名稱 範例 簡介Accept */* 請求的內容的通用欄位Accept-Charset UTF-8 請求的內容編碼Accept-Encoding gzip, deflate 請求的內容壓縮方式Accept-Language zh-TW,zh-CN;q=0.6,en-

US;q=0.2請求的內容語言, q 代表請求權重 ( 範圍值介於 0~1 之間,不寫預設 =1) ,以這個範例來說,我指定可以接受 zh-TW( 繁中 )zh-CN( 簡中 )en-US( 英文 ) ,其中又以 zh-TW 權重最高=1 , zh-CN 其次 =0.6 , en-US 最低 =0.2

Authorization YWJjOjEyMw== 通常會放身份驗證 token , Http 1.0 時的規範格式為 base64

encode 後的 username:password , abc:123 → YWJjOjEyMw==

If-None-Match "12345678" 這裡會放上一次 Server 給的 ETag

If-Modified-Since Wed, 20 Apr 2016 08:46:31 GMT

這裡會放上一次 Server 給的 Last-Modified

Request headers

Page 10: Http Headers 與 Cache 機制

WHY CACHE?

1. 減少 request 次數2. 降低 response 資料• Glide• Picasso• Android Query• Universal Image Loader• ……

Page 11: Http Headers 與 Cache 機制

request• no-cache• no-store• max-age = delta-seconds • max-stale = delta-seconds • min-fresh = delta-seconds • no-transform• only-if-cached

response• public• private• no-store• no-cache• max-age = delta-seconds • no-transform• must-revalidate• proxy-revalidate• s-maxage = delta-seconds

Cache-Control directive

Page 12: Http Headers 與 Cache 機制

CACHE 的使用情境

Page 13: Http Headers 與 Cache 機制

no-store

Client Server

200 OKCache-Control →no-store...

200 OKCache-Control →no-store...

GET

Checkingcache

GET

Page 14: Http Headers 與 Cache 機制

max-age

Client Server

200 OKCache-Control →max-age=60...

…10s

…60s

GET

Checkingcache

GET

Checkingcache

200 OKCache-Control →max-age=60...

GET

Page 15: Http Headers 與 Cache 機制

no-cache + ETag

Client Server

GET

200 OKCache-Control →no-cache, privateETag →“123"...

GETIf-None-Match→“123"

Checkingcache

304 Not Modified

Page 16: Http Headers 與 Cache 機制

no-cache + Last-Modified

Client Server

GET

200 OKCache-Control →no-cache, publiceLast-Modified→ Sat, 01 Jan 2000 00:00:00 GMT...

GETIf-Modified-Since → Sat, 01 Jan 2000 00:00:00 GMT

Checkingcache

304 Not Modified

Page 18: Http Headers 與 Cache 機制

public class UserMaxAgeController : ApiController {

public HttpResponseMessage Get() {

User user = TestCacheHelper.getUser();

HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK,

user);

response.Headers.CacheControl = new CacheControlHeaderValue() {

Private = true,

MaxAge = TimeSpan.FromSeconds(10)

};

return response;

}

}

ONLY MAX-AGE

Page 19: Http Headers 與 Cache 機制

public class UserNoCacheController : ApiController {

public HttpResponseMessage Get() {

User user = TestCacheHelper.getUser();

HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, user);

response.Headers.ETag = new EntityTagHeaderValue(TestCacheHelper.convertToEtag(user.GetHashCode()));response.Content.Headers.LastModified = user.LastUpdatedAt.ToUniversalTime(); //GMT

response.Headers.CacheControl = new CacheControlHeaderValue() {Private = true,

MaxAge = TimeSpan.FromSeconds(10)

};

var modifiedSince = Request.Headers.IfModifiedSince;

var eTag = Request.Headers.IfNoneMatch.FirstOrDefault();

if (modifiedSince != null && modifiedSince.Value.ToUniversalTime().Equals(user.LastUpdatedAt)) {

response.StatusCode = HttpStatusCode.NotModified; //304

}

if (eTag != null && eTag.ToString().Equals(TestCacheHelper.convertToEtag(user.GetHashCode()))) {

response.StatusCode = HttpStatusCode.NotModified; //304

}

return response; }}

ETAG + LAST-MODIFIED + MAX-AGE

Page 20: Http Headers 與 Cache 機制

CODE EXAMPLE - ANDROID

Demo code : https://bitbucket.org/ct7ct7ct7/demo-android_test_cache

Page 21: Http Headers 與 Cache 機制

private final static int CACHE_SIZE = 10 * 1024 * 1024; // 10 MiB

/*reset code…*/

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();

interceptor.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY :

HttpLoggingInterceptor.Level.NONE);

okHttpClient = new OkHttpClient.Builder()

.cache(new Cache(Example1Activity.this.getExternalCacheDir(),

CACHE_SIZE))

.addInterceptor(interceptor)

.build();

設定 cache size 與 directory path

EXAMPLE - 1

Page 22: Http Headers 與 Cache 機制

EXAMPLE - 2

/*reset code…*/

@Overridepublic Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); Response originalResponse = chain.proceed(chain.request());

String eTag = originalResponse.headers().get("ETag"); String lastModified = originalResponse.headers().get("Last-Modified");

cacheSharedPreferences.set(originalRequest.method(),originalRequest.url().toString(), CacheSharedPreferences.Type.E_TAG,eTag); cacheSharedPreferences.set(originalRequest.method(),originalRequest.url().toString(), CacheSharedPreferences.Type.LAST_MODIFIED,lastModified); return originalResponse;}

透過 interceptor 將 response header 中的 ETag 與 Last-Modified 記下來

Page 23: Http Headers 與 Cache 機制

EXAMPLE - 2/*reset code…*/

@Overridepublic Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request();

String eTag = cacheSharedPreferences.get(originalRequest.method(),originalRequest.url().toString(), CacheSharedPreferences.Type.E_TAG);

String lastModified = cacheSharedPreferences.get(originalRequest.method(),originalRequest.url().toString(), CacheSharedPreferences.Type.LAST_MODIFIED);

Request compressedRequest = originalRequest.newBuilder() .header("If-Modified-Since", lastModified) .header("If-None-Match", eTag) .build(); return chain.proceed(compressedRequest);}

透過 interceptor 在 request header 中添加驗證權杖If-Modified-Since 與 If-None-Match

Page 24: Http Headers 與 Cache 機制

EXAMPLE - 3

透過 interceptor 在 request header 中添加Cache-Control -> max-stale

/*reset code…*/

@Overridepublic Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request();

if (CommonUtils.checkNetwork(context) == false) { int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale Request compressedRequest = originalRequest.newBuilder() .header("Cache-Control", "public, max-stale=" + maxStale) .build(); return chain.proceed(compressedRequest); } return chain.proceed(originalRequest);}

Page 25: Http Headers 與 Cache 機制

OKHTTP - INTERCEPTOR

Application Interceptor

• Log handler• Exception error handler• Cache handler• …..

Network Interceptor

• Log handler• Header or parameter handler• Exception error handler• ……

Page 26: Http Headers 與 Cache 機制

CACHE 最佳化策略

Add Last-Modified header

Page 27: Http Headers 與 Cache 機制

1. 檢查網路狀態1. 無→使用 cache 資料2. 有→檢查 cache 使用期限

1. 期限內→使用 cache 資料2. 已過期→添加驗證權杖在 header

發送 request 時: 收到 response 時:1. 200→ 儲存資料及相關 header 至 cache

中2. 304→ 使用 cache 資料

CACHE 最佳化策略

Page 28: Http Headers 與 Cache 機制

1. Cache 原則:減少 request 次數 & 降低 response 資料量2. max-age 要謹慎使用3. 為你的 api 加上內容驗證 ( ETag ) 與時間驗證 ( Last-Modified )

CONCLUSION