public static CacheControl getCacheControl(IHttpHeaders headers, long requestTime) { CacheControl cc=new CacheControl(); bool proxyRevalidate=false; int sMaxAge=0; bool publicCache=false; bool privateCache=false; bool noCache=false; long expires=0; bool hasExpires=false; cc.uri=headers.getUrl(); string cacheControl=headers.getHeaderField("cache-control"); if(cacheControl!=null){ int index=0; int[] intval=new int[1]; while(index<cacheControl.Length){ int current=index; if((index=HeaderParser.parseToken(cacheControl,current,"private",true))!=current){ privateCache=true; } else if((index=HeaderParser.parseToken(cacheControl,current,"no-cache",true))!=current){ noCache=true; //Console.WriteLine("returning early because it saw no-cache"); return null; // return immediately, this is not cacheable } else if((index=HeaderParser.parseToken( cacheControl,current,"no-store",false))!=current){ cc.noStore=true; //Console.WriteLine("returning early because it saw no-store"); return null; // return immediately, this is not cacheable or storable } else if((index=HeaderParser.parseToken( cacheControl,current,"public",false))!=current){ publicCache=true; } else if((index=HeaderParser.parseToken( cacheControl,current,"no-transform",false))!=current){ cc.noTransform=true; } else if((index=HeaderParser.parseToken( cacheControl,current,"must-revalidate",false))!=current){ cc.mustRevalidate=true; } else if((index=HeaderParser.parseToken( cacheControl,current,"proxy-revalidate",false))!=current){ proxyRevalidate=true; } else if((index=HeaderParser.parseTokenWithDelta( cacheControl,current,"max-age",intval))!=current){ cc.maxAge=intval[0]; } else if((index=HeaderParser.parseTokenWithDelta( cacheControl,current,"s-maxage",intval))!=current){ sMaxAge=intval[0]; } else { index=HeaderParser.skipDirective(cacheControl,current); } } if(!publicCache && !privateCache && !noCache){ noCache=true; } } else { int code=headers.getResponseCode(); if((code==200 || code==203 || code==300 || code==301 || code==410) && headers.getHeaderField("authorization")==null){ publicCache=true; privateCache=false; } else { noCache=true; } } if(headers.getResponseCode()==206) { noCache=true; } string pragma=headers.getHeaderField("pragma"); if(pragma!=null && "no-cache".Equals(StringUtility.toLowerCaseAscii(pragma))){ noCache=true; //Console.WriteLine("returning early because it saw pragma no-cache"); return null; } long now=DateTimeUtility.getCurrentDate(); cc.code=headers.getResponseCode(); cc.date=now; cc.responseTime=now; cc.requestTime=requestTime; if(proxyRevalidate){ // Enable must-revalidate for simplicity; // proxyRevalidate usually only applies to shared caches cc.mustRevalidate=true; } if(headers.getHeaderField("date")!=null){ cc.date=headers.getHeaderFieldDate("date",Int64.MinValue); if(cc.date==Int64.MinValue) { noCache=true; } } else { noCache=true; } string expiresHeader=headers.getHeaderField("expires"); if(expiresHeader!=null){ expires=headers.getHeaderFieldDate("expires",Int64.MinValue); hasExpires=(cc.date!=Int64.MinValue); } if(headers.getHeaderField("age")!=null){ try { cc.age=Int32.Parse(headers.getHeaderField("age"),NumberStyles.AllowLeadingSign,CultureInfo.InvariantCulture); if(cc.age<0) { cc.age=0; } } catch(FormatException){ cc.age=-1; } } if(cc.maxAge>0 || sMaxAge>0){ long maxAge=cc.maxAge; // max age in seconds if(maxAge==0) { maxAge=sMaxAge; } if(cc.maxAge>0 && sMaxAge>0){ maxAge=Math.Max(cc.maxAge,sMaxAge); } cc.maxAge=maxAge*1000L; // max-age and s-maxage are in seconds hasExpires=false; } else if(hasExpires && !noCache){ long maxAge=expires-cc.date; cc.maxAge=(maxAge>Int32.MaxValue) ? Int32.MaxValue : (int)maxAge; } else if(noCache || cc.noStore){ cc.maxAge=0; } else { cc.maxAge=24L*3600L*1000L; } string reqmethod=headers.getRequestMethod(); if(reqmethod==null || ( !StringUtility.toLowerCaseAscii(reqmethod).Equals("get"))) // caching responses other than GET responses not supported return null; cc.requestMethod=StringUtility.toLowerCaseAscii(reqmethod); cc.cacheability=2; if(noCache) { cc.cacheability=0; } else if(privateCache) { cc.cacheability=1; } int i=0; cc.headers.Add(headers.getHeaderField(null)); while(true){ string newValue=headers.getHeaderField(i); if(newValue==null) { break; } string key=headers.getHeaderFieldKey(i); i++; if(key==null){ //Console.WriteLine("null key"); continue; } key=StringUtility.toLowerCaseAscii(key); // to simplify matters, don't include Age header fields; // so-called hop-by-hop headers are also not included if(!"age".Equals(key) && !"connection".Equals(key) && !"keep-alive".Equals(key) && !"proxy-authenticate".Equals(key) && !"proxy-authorization".Equals(key) && !"te".Equals(key) && !"trailer".Equals(key) && // NOTE: NOT Trailers !"transfer-encoding".Equals(key) && !"upgrade".Equals(key)){ cc.headers.Add(key); cc.headers.Add(newValue); } } //Console.WriteLine(" cc: %s",cc); return cc; }
public void writeObjectToStream(CacheControl o, Stream stream) { JSONObject jsonobj=new JSONObject(); jsonobj.put("cacheability",o.cacheability); jsonobj.put("noStore",o.noStore); jsonobj.put("noTransform",o.noTransform); jsonobj.put("mustRevalidate",o.mustRevalidate); jsonobj.put("requestTime",Convert.ToString(o.requestTime,CultureInfo.InvariantCulture)); jsonobj.put("responseTime",Convert.ToString(o.responseTime,CultureInfo.InvariantCulture)); jsonobj.put("maxAge",Convert.ToString(o.maxAge,CultureInfo.InvariantCulture)); jsonobj.put("date",Convert.ToString(o.date,CultureInfo.InvariantCulture)); jsonobj.put("uri",o.uri); jsonobj.put("requestMethod",o.requestMethod); jsonobj.put("code",o.code); jsonobj.put("age",Convert.ToString(o.age,CultureInfo.InvariantCulture)); JSONArray jsonarr=new JSONArray(); foreach(var header in o.headers){ jsonarr.put(header); } jsonobj.put("headers",jsonarr); StreamUtility.stringToStream(jsonobj.ToString(),stream); }
public AgedHeaders(CacheControl cc, long age, long length) { list.Add(cc.headers[0]); for(int i=1;i<cc.headers.Count;i+=2){ string key=cc.headers[i]; if(key!=null){ key=StringUtility.toLowerCaseAscii(key); if("content-length".Equals(key)||"age".Equals(key)) { continue; } } list.Add(cc.headers[i]); list.Add(cc.headers[i+1]); } this.age=age/1000; // convert age to seconds list.Add("age"); list.Add(Convert.ToString(this.age,CultureInfo.InvariantCulture)); list.Add("content-length"); list.Add(Convert.ToString(length,CultureInfo.InvariantCulture)); //Console.WriteLine("aged=%s",list); this.cc=cc; }
public CacheControl readObjectFromStream(PeterO.Support.InputStream stream) { try { JSONObject jsonobj=new JSONObject(StreamUtility.streamToString(stream)); CacheControl cc=new CacheControl(); cc.cacheability=jsonobj.getInt("cacheability"); cc.noStore=jsonobj.getBoolean("noStore"); cc.noTransform=jsonobj.getBoolean("noTransform"); cc.mustRevalidate=jsonobj.getBoolean("mustRevalidate"); cc.requestTime=Int64.Parse(jsonobj.getString("requestTime"),NumberStyles.AllowLeadingSign,CultureInfo.InvariantCulture); cc.responseTime=Int64.Parse(jsonobj.getString("responseTime"),NumberStyles.AllowLeadingSign,CultureInfo.InvariantCulture); cc.maxAge=Int64.Parse(jsonobj.getString("maxAge"),NumberStyles.AllowLeadingSign,CultureInfo.InvariantCulture); cc.date=Int64.Parse(jsonobj.getString("date"),NumberStyles.AllowLeadingSign,CultureInfo.InvariantCulture); cc.code=jsonobj.getInt("code"); cc.age=Int64.Parse(jsonobj.getString("age"),NumberStyles.AllowLeadingSign,CultureInfo.InvariantCulture); cc.uri=jsonobj.getString("uri"); cc.requestMethod=jsonobj.getString("requestMethod"); if(cc.requestMethod!=null) { cc.requestMethod=StringUtility.toLowerCaseAscii(cc.requestMethod); } cc.headers=new List<string>(); JSONArray jsonarr=jsonobj.getJSONArray("headers"); for(int i=0;i<jsonarr.Length;i++){ string str=jsonarr.getString(i); if(str!=null && (i%2)!=0){ str=StringUtility.toLowerCaseAscii(str); if("age".Equals(str) || "connection".Equals(str) || "keep-alive".Equals(str) || "proxy-authenticate".Equals(str) || "proxy-authorization".Equals(str) || "te".Equals(str) || "trailers".Equals(str) || "transfer-encoding".Equals(str) || "upgrade".Equals(str)){ // Skip "age" header field and // hop-by-hop header fields i++; continue; } } cc.headers.Add(str); } return cc; } catch(InvalidCastException e){ Console.WriteLine(e.StackTrace); return null; } catch(FormatException e){ Console.WriteLine(e.StackTrace); return null; } catch (Json.InvalidJsonException e) { Console.WriteLine(e.StackTrace); return null; } }
public static void toFile(CacheControl o, PeterO.Support.File file) { Stream fs=new FileStream((file).ToString(),FileMode.Create); try { new CacheControlSerializer().writeObjectToStream(o,fs); } finally { if(fs!=null) { fs.Close(); } } }