def writeCache(self, request, cache = None): logging.debug('writeCache') url = self.origin + request headers = {'User-Agent' : http.userAgent} # Bypass google cache headers['Cache-Control'] = 'no-cache, max-age=0, must-revalidate' if cache: headers['If-Modified-Since'] = web.httpdate(cache.lastModified) try: response = urlfetch.Fetch(url=url, headers=headers) except Exception, e: if cache: return cache logging.warning('urlfetch error, redirect to origin. (%s: %s)' % (type(e), e)) raise web.SeeOther(url, absolute=True)
def writeCache(self, request, cache=None, _beforeWriteCache=None): logging.debug('writeCache') url = self.origin + request if self.stripForwardedQueryString is True: url = url.split('?').pop(0) headers = {'User-Agent' : http.userAgent} # Bypass google cache headers['Cache-Control'] = 'no-cache, max-age=0, must-revalidate' if not self.disableIfModifiedSince and cache: headers['If-Modified-Since'] = web.httpdate(cache.lastModified) try: response = urlfetch.Fetch(url=url, headers=headers) except Exception, e: if cache: return cache logging.warning('urlfetch error, redirect to origin. (%s: %s)' % (type(e), e)) raise web.SeeOther(url, absolute=True)
def _post(self, f): now = datetime.now() web.lastmodified(now) web.httpdate(now) web.header('Cache-Control', 'no-cache,private') web.header('Pragma', 'no-cache') if isinstance(f, web.HTTPError) is True: raise f if self.download.type == self.DOWNLOAD_TYPE_NORMAL: # nomal process if self.__template__.media == "json": try: _r = simplejson.dumps(self.view) return _r except: raise web.internalerror() if f is True: path = '%s/%s.%s' % ( self.__template__.dir.replace("controller", ""), self.__template__.file.replace("controller", ""), self.__template__.media) try: _r = self.__mako_render(path, title='akiyoshi', view=self.view) return _r except: return exceptions.html_error_template().render(full=True) elif self.download.type == self.DOWNLOAD_TYPE_FILE: # file download if self.download.file is None or os.path.isfile(self.download.file) is False: self.log.error('Could not find files to download. - path=%s' % self.download.file) raise web.internalerror() web.header('Content-Type', 'Content-type: application/octet-stream', True) fp = open(self.download.file , "rb") try: _r = fp.read() finally: fp.close() if self.download.once is True and os.path.isfile(self.download.file) is True: os.unlink(self.download.file) return _r elif self.download.type == self.DOWNLOAD_TYPE_STREAM: # file stream download!! if self.download.stream is None: self.log.error("Data stream has not been set.") raise web.internalerror("Execution errors") return self.download.stream else: # Illegal Error. self.log.error('Was specified assuming no output type. - type=%d' % self.download.type) raise web.internalerror()
def httpdate(date): return web.httpdate(date)
def _post(self, f): """<comment-ja> HTTP Method別処理を実行した後の処理を行います。 1. HTTP Responseコード 4xx or 5xx についての処理 2. テンプレート処理 3. HTTP Headerをセット @param f: 実行結果 @type f: bool or web.HTTPError @return: HTTP Response </comment-ja> <comment-en> TODO: English Comment </comment-en> """ try: # default view set. self.view.me = self.me if self.is_standalone() is True: self.view.standalone = self.input.standalone except AttributeError: pass # Content-Type # TODO # "Resource interpreted as script but transferred with MIME type text/plain." # if self.__template__.media == 'part': # web.header('Content-Type', 'text/html; charset=utf-8', True) # elif self.__template__.media == 'input': # web.header('Content-Type', 'text/html; charset=utf-8', True) # elif self.__template__.media == 'html': # web.header('Content-Type', 'text/html; charset=utf-8', True) # elif self.__template__.media == 'json': # web.header('Content-Type', 'application/json; charset=utf-8', True) # elif self.__template__.media == 'xml':` # web.header('Content-Type', 'text/xml; charset=utf-8', True) # elif self.__template__.media == 'gif': # web.header('Content-Type', 'Content-type: image/gif', True) # elif self.__template__.media == 'png': # web.header('Content-Type', 'Content-type: image/png', True) # elif self.__template__.media == 'jpg': # web.header('Content-Type', 'Content-type: image/jpeg', True) # elif self.__template__.media == 'jpeg': # web.header('Content-Type', 'Content-type: image/jpeg', True) # elif self.__template__.media == 'ico': # web.header('Content-Type', 'Content-type: image/x-icon', True) # elif self.__template__.media == 'css': # web.header('Content-Type', 'Content-type: text/css; charset=utf-8', True) # elif self.__template__.media == 'js': # web.header('Content-Type', 'Content-type: text/javascript; charset=utf-8', True) # elif self.__template__.media == 'jar': # web.header('Content-Type', 'Content-type: application/java-archiver', True) # else: # web.header('Content-Type', 'text/plain; charset=utf-8', True) # HTTP Header - No Cache now = datetime.now() web.lastmodified(now) web.httpdate(now) # TODO # web.expire(0) # web.header('Expires', web.httpdate(datetime(1970,1,1))) # web.header('Last-Modified', web.httpdate(datetime(1970,1,1))) # web.header('ETag', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') web.header("Cache-Control", "no-cache,private") web.header("Pragma", "no-cache") ## if self.download.type == OUTPUT_TYPE_NORMAL: # Nomal if self.me is None: self.view.USER_DATE_FORMAT = DEFAULT_LANGS[self.languages[0]]["DATE_FORMAT"] else: self.view.USER_DATE_FORMAT = DEFAULT_LANGS[self.me.languages]["DATE_FORMAT"] if isinstance(f, web.HTTPError) is True: self.logger.info("HTTP Response - %s Headers-->%s" % (f.__class__.__name__, web.ctx.headers)) raise f if f is True: path = "%s/%s.%s" % (self.__template__.dir, self.__template__.file, self.__template__.media) else: # if self.__template__.media in ERROR_MEDIA: # path = 'error/error.%s' % self.__template__.media # else: # path = 'error/error.%s' % DEFAULT_MEDIA self.logger.info('"gadget" execution error - %s' % str(self.__class__)) raise web.internalerror("Execution errors") self.logger.debug("lang=%s %s : template=%s" % (",".join(self.languages), str(self), path)) try: _r = mako_render(self._, path, title=self._("Karesansui"), view=self.view) return _r except: if web.wsgi._is_dev_mode() is True and os.environ.has_key("FCGI") is False: return exceptions.html_error_template().render(full=True) else: self.logger.error('"mako render" execution error - path=%s' % path) self.logger_trace.error(traceback.format_exc()) raise web.internalerror("Execution errors") elif self.download.type == OUTPUT_TYPE_FILE: # file download if self.download.file is None or os.path.isfile(self.download.file) is False: self.logger.error("Could not find files to download. - path=%s" % self.download.file) return web.internalerror() web.header("Content-Type", "Content-type: image/png", True) fp = open(self.download.file, "rb") try: _r = fp.read() finally: fp.close() if self.download.once is True and os.path.isfile(self.download.file) is True: os.unlink(self.download.file) return _r elif self.download.type == OUTPUT_TYPE_STREAM: # io stream download if self.download.stream is None: self.logger.error("Data stream has not been set.") return self.download.stream else: self.logger.error("Was specified assuming no output type. - type=%d" % self.download.type) raise web.internalerror()
class Service(object): """Cache service This service implements the content delivering caching mechanism. All requests handled by this service produces cache manipulation on the Google Datastore (with a Memcache top layer). - origin: Set the origin url (type: String; mandatory) - forceTTL: Does not honor CacheControl value, replacing cache TTL by this value (type: Integer) - maxTTL: When the CacheControl value is honored (forceTTL not set), the cache TTL value cannot be greater than this value (otherwise, it is overriden). (type: Integer) - ignoreQueryString: Tell if the trailing HTTP query string is not taken into account to generate the cache object key in Datastore. In other terms, if this value is set to True, /url/path/obj.js?v=42 and /url/path/obj.js referer to the same object. (type: Boolean; default: False) - forwardPost: If it is True, POST requests will be forwarded, instead of being redirected (type: Boolean; default: True) - allowFlushFrom: Specify client IP which are allowed to make DELETE requests to flush cache object explicitly. (type: List) - disableIfModifiedSince: Disable IMS request during object refresh. (type: Boolean; default: False) - prefetch: (EXPERIMENTAL) Prefetch content from HTML or other pages. (type: Boolean; default: False) - headerBlacklist: Set list of origin headers to remove. (type: List) """ origin = None forceTTL = None maxTTL = None ignoreQueryString = False forwardPost = True # Set your client IP address to authorize cache entry deletion allowFlushFrom = ['127.0.0.1'] prefetch = False disableIfModifiedSince = False # undocumented: remove querystring before forwarding # the request to the origin stripForwardedQueryString = False # These headers won't be forwarded headerBlacklist = [] _headerBlacklist = [ 'date', 'last-modified', 'via', 'expires', 'etag' ] def __init__(self): self.name = self.__class__.__name__ self.cache = type(self.name, (Cache,), {}) # Register the dynamic object globally # if not, pickle cannot find it for serialization globals()[self.name] = self.cache def GET(self, request, _beforeWriteCache=None): if self.ignoreQueryString is False: request += web.ctx.query try: cache = self.readCache(request) if cache is None: cache = self.writeCache(request, _beforeWriteCache=_beforeWriteCache) except runtime.DeadlineExceededError: raise web.SeeOther(self.origin + request, absolute=True) except CacheExpired, cache: cache = self.writeCache(request, cache=cache(), _beforeWriteCache=_beforeWriteCache) if not web.modified(cache.lastModified): raise web.HTTPError(status='304 Not Modified') web.header('Expires', web.httpdate(cache.expires)) for h in cache.headers: print h return cache.data
def _post(self, f): """<comment-ja> HTTP Method別処理を実行した後の処理を行います。 1. HTTP Responseコード 4xx or 5xx についての処理 2. テンプレート処理 3. HTTP Headerをセット @param f: 実行結果 @type f: bool or web.HTTPError @return: HTTP Response </comment-ja> <comment-en> TODO: English Comment </comment-en> """ try: # default view set. self.view.me = self.me if self.is_standalone() is True: self.view.standalone = self.input.standalone except AttributeError: pass # Content-Type # TODO # "Resource interpreted as script but transferred with MIME type text/plain." #if self.__template__.media == 'part': # web.header('Content-Type', 'text/html; charset=utf-8', True) #elif self.__template__.media == 'input': # web.header('Content-Type', 'text/html; charset=utf-8', True) #elif self.__template__.media == 'html': # web.header('Content-Type', 'text/html; charset=utf-8', True) #elif self.__template__.media == 'json': # web.header('Content-Type', 'application/json; charset=utf-8', True) #elif self.__template__.media == 'xml':` # web.header('Content-Type', 'text/xml; charset=utf-8', True) #elif self.__template__.media == 'gif': # web.header('Content-Type', 'Content-type: image/gif', True) #elif self.__template__.media == 'png': # web.header('Content-Type', 'Content-type: image/png', True) #elif self.__template__.media == 'jpg': # web.header('Content-Type', 'Content-type: image/jpeg', True) #elif self.__template__.media == 'jpeg': # web.header('Content-Type', 'Content-type: image/jpeg', True) #elif self.__template__.media == 'ico': # web.header('Content-Type', 'Content-type: image/x-icon', True) #elif self.__template__.media == 'css': # web.header('Content-Type', 'Content-type: text/css; charset=utf-8', True) #elif self.__template__.media == 'js': # web.header('Content-Type', 'Content-type: text/javascript; charset=utf-8', True) #elif self.__template__.media == 'jar': # web.header('Content-Type', 'Content-type: application/java-archiver', True) #else: # web.header('Content-Type', 'text/plain; charset=utf-8', True) # HTTP Header - No Cache now = datetime.now() web.lastmodified(now) web.httpdate(now) # TODO #web.expire(0) #web.header('Expires', web.httpdate(datetime(1970,1,1))) #web.header('Last-Modified', web.httpdate(datetime(1970,1,1))) #web.header('ETag', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') web.header('Cache-Control', 'no-cache,private') web.header('Pragma', 'no-cache') ## if self.download.type == OUTPUT_TYPE_NORMAL: # Nomal if self.me is None: self.view.USER_DATE_FORMAT = DEFAULT_LANGS[ self.languages[0]]['DATE_FORMAT'] else: self.view.USER_DATE_FORMAT = DEFAULT_LANGS[ self.me.languages]['DATE_FORMAT'] if isinstance(f, web.HTTPError) is True: self.logger.info('HTTP Response - %s Headers-->%s' % (f.__class__.__name__, web.ctx.headers)) raise f if f is True: path = '%s/%s.%s' % ( self.__template__.dir, self.__template__.file, self.__template__.media, ) else: #if self.__template__.media in ERROR_MEDIA: # path = 'error/error.%s' % self.__template__.media #else: # path = 'error/error.%s' % DEFAULT_MEDIA self.logger.info('"gadget" execution error - %s' % str(self.__class__)) raise web.internalerror("Execution errors") self.logger.debug('lang=%s %s : template=%s' \ % (','.join(self.languages), str(self), path)) try: _r = mako_render(self._, path, title=self._('Karesansui'), view=self.view) return _r except: if web.wsgi._is_dev_mode() is True and os.environ.has_key( 'FCGI') is False: return exceptions.html_error_template().render(full=True) else: self.logger.error( '"mako render" execution error - path=%s' % path) self.logger_trace.error(traceback.format_exc()) raise web.internalerror("Execution errors") elif self.download.type == OUTPUT_TYPE_FILE: # file download if self.download.file is None or os.path.isfile( self.download.file) is False: self.logger.error( 'Could not find files to download. - path=%s' % self.download.file) return web.internalerror() web.header('Content-Type', 'Content-type: image/png', True) fp = open(self.download.file, "rb") try: _r = fp.read() finally: fp.close() if self.download.once is True and os.path.isfile( self.download.file) is True: os.unlink(self.download.file) return _r elif self.download.type == OUTPUT_TYPE_STREAM: # io stream download if self.download.stream is None: self.logger.error("Data stream has not been set.") return self.download.stream else: self.logger.error( 'Was specified assuming no output type. - type=%d' % self.download.type) raise web.internalerror()