[FIX] website: move support for ir.attachment resources to web module
Commit 540b753bf8
introduced
support for resources stored as ir.attachment records in
asset bundles too.
This is specifically useful for customizations.
However the HTTP route for reaching those resources
when they are *not* in a bundle was originally created
in the `website` module (as a special handling for
404 requests)
This means that these dynamic resources would only
be partially supported when `website` is not installed,
causing various problems:
- missing resources in debug mode where bundles are skipped
- errors when trying to define new client-side Qweb templates
via XML resources - which are loaded with a direct request
- ...
This commit moves back the supporting code to the web module.
The `mimetype` column is not present in ir.attachment without
the `website` module, but sniffing it based on the attachment
name works fine at serving time too.
Closes #6002
This commit is contained in:
parent
c58121e8f1
commit
95b921d0f7
|
@ -1,6 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
import hashlib
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
@ -76,7 +74,7 @@ class ir_http(orm.AbstractModel):
|
|||
if self.geo_ip_resolver and request.httprequest.remote_addr:
|
||||
record = self.geo_ip_resolver.record_by_addr(request.httprequest.remote_addr) or {}
|
||||
request.session['geoip'] = record
|
||||
|
||||
|
||||
if request.website_enabled:
|
||||
try:
|
||||
if func:
|
||||
|
@ -163,38 +161,7 @@ class ir_http(orm.AbstractModel):
|
|||
path += '?' + request.httprequest.query_string
|
||||
return werkzeug.utils.redirect(path, code=301)
|
||||
|
||||
def _serve_attachment(self):
|
||||
domain = [('type', '=', 'binary'), ('url', '=', request.httprequest.path)]
|
||||
attach = self.pool['ir.attachment'].search_read(request.cr, openerp.SUPERUSER_ID, domain, ['__last_update', 'datas', 'mimetype'], context=request.context)
|
||||
if attach:
|
||||
wdate = attach[0]['__last_update']
|
||||
datas = attach[0]['datas']
|
||||
response = werkzeug.wrappers.Response()
|
||||
server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT
|
||||
try:
|
||||
response.last_modified = datetime.datetime.strptime(wdate, server_format + '.%f')
|
||||
except ValueError:
|
||||
# just in case we have a timestamp without microseconds
|
||||
response.last_modified = datetime.datetime.strptime(wdate, server_format)
|
||||
|
||||
response.set_etag(hashlib.sha1(datas).hexdigest())
|
||||
response.make_conditional(request.httprequest)
|
||||
|
||||
if response.status_code == 304:
|
||||
return response
|
||||
|
||||
response.mimetype = attach[0]['mimetype'] or 'application/octet-stream'
|
||||
response.data = datas.decode('base64')
|
||||
return response
|
||||
|
||||
def _handle_exception(self, exception, code=500):
|
||||
# This is done first as the attachment path may
|
||||
# not match any HTTP controller, so the request
|
||||
# may not be website-enabled.
|
||||
attach = self._serve_attachment()
|
||||
if attach:
|
||||
return attach
|
||||
|
||||
is_website_request = bool(getattr(request, 'website_enabled', False) and request.website)
|
||||
if not is_website_request:
|
||||
# Don't touch non website requests exception handling
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
#----------------------------------------------------------
|
||||
# ir_http modular http routing
|
||||
#----------------------------------------------------------
|
||||
import datetime
|
||||
import hashlib
|
||||
import logging
|
||||
import mimetypes
|
||||
import re
|
||||
import sys
|
||||
|
||||
import werkzeug
|
||||
import werkzeug.exceptions
|
||||
import werkzeug.routing
|
||||
import werkzeug.urls
|
||||
|
@ -94,7 +98,41 @@ class ir_http(osv.AbstractModel):
|
|||
raise openerp.exceptions.AccessDenied()
|
||||
return auth_method
|
||||
|
||||
def _serve_attachment(self):
|
||||
domain = [('type', '=', 'binary'), ('url', '=', request.httprequest.path)]
|
||||
attach = self.pool['ir.attachment'].search_read(
|
||||
request.cr, openerp.SUPERUSER_ID, domain,
|
||||
['__last_update', 'datas', 'datas_fname'],
|
||||
context=request.context)
|
||||
if attach:
|
||||
wdate = attach[0]['__last_update']
|
||||
datas = attach[0]['datas']
|
||||
response = werkzeug.wrappers.Response()
|
||||
server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT
|
||||
try:
|
||||
response.last_modified = datetime.datetime.strptime(wdate, server_format + '.%f')
|
||||
except ValueError:
|
||||
# just in case we have a timestamp without microseconds
|
||||
response.last_modified = datetime.datetime.strptime(wdate, server_format)
|
||||
|
||||
response.set_etag(hashlib.sha1(datas).hexdigest())
|
||||
response.make_conditional(request.httprequest)
|
||||
|
||||
if response.status_code == 304:
|
||||
return response
|
||||
|
||||
response.mimetype = (mimetypes.guess_type(attach[0]['datas_fname'])[0] or
|
||||
'application/octet-stream')
|
||||
response.data = datas.decode('base64')
|
||||
return response
|
||||
|
||||
def _handle_exception(self, exception):
|
||||
# This is done first as the attachment path may
|
||||
# not match any HTTP controller.
|
||||
attach = self._serve_attachment()
|
||||
if attach:
|
||||
return attach
|
||||
|
||||
# If handle_exception returns something different than None, it will be used as a response
|
||||
try:
|
||||
return request._handle_exception(exception)
|
||||
|
|
Loading…
Reference in New Issue