lib/ensure_content_type.js
function checkContentType(hyper, req, next, expectedContentType, responsePromise) {
    return responsePromise
    .then((res) => {
        // Do not check or re-render if the response was only rendered within
        // the last two minutes.
        if (res.headers && res.headers.etag &&
            Date.now() - mwUtil.extractDateFromEtag(res.headers.etag) < 120000) {
            return res;
        }

        if (res.headers && res.headers === undefined) {
            delete res.headers['content-type'];
        }

        if (res.headers &&
                res.headers['content-type'] &&
                res.headers['content-type'] !== expectedContentType) {
            // Parse the expected & response content type, and compare profiles.
            const expectedProfile = cType.parse(expectedContentType).parameters.profile;
            const actualProfile = cType.parse(res.headers['content-type']).parameters.profile;

            if (actualProfile && actualProfile !== expectedProfile) {
                if (!expectedProfile) {
                    return res;
                }
                // Check if actual content type is newer than the spec
                const actualProfileParts = splitProfile(actualProfile);
                const expectedProfileParts = splitProfile(expectedProfile);
                if (actualProfileParts.path === expectedProfileParts.path &&
                        semver.gt(actualProfileParts.version, expectedProfileParts.version)) {
                    return res;
                }
            }

            // Re-try request with no-cache header
            if (!mwUtil.isNoCacheRequest(req)) {
                req.headers['cache-control'] = 'no-cache';
                return checkContentType(hyper, req, next, expectedContentType, next(hyper, req));
            } else {
                // Log issue
                hyper.logger.log('warn/content-type/upgrade_failed', {
                    msg: 'Could not update the content-type',
                    expected: expectedContentType,
                    actual: res.headers['content-type']
                });
                // Disable response caching, as we aren't setting a vary
                // either.
                res.headers['cache-control'] = 'max-age=0, s-maxage=0';
            }
        }
        // Default: Just return.
        return res;
    });
}
function checkContentType(hyper, req, next, expectedContentType, responsePromise) {
    return responsePromise
    .then((res) => {
        // Do not check or re-render if the response was only rendered within
        // the last two minutes.
        if (res.headers && res.headers.etag &&
            Date.now() - mwUtil.extractDateFromEtag(res.headers.etag) < 120000) {
            return res;
        }

        if (res.headers && res.headers === undefined) {
            delete res.headers['content-type'];
        }

        if (res.headers &&
                res.headers['content-type'] &&
                res.headers['content-type'] !== expectedContentType) {
            // Parse the expected & response content type, and compare profiles.
            const expectedProfile = cType.parse(expectedContentType).parameters.profile;
            const actualProfile = cType.parse(res.headers['content-type']).parameters.profile;

            if (actualProfile && actualProfile !== expectedProfile) {
                if (!expectedProfile) {
                    return res;
                }
                // Check if actual content type is newer than the spec
                const actualProfileParts = splitProfile(actualProfile);
                const expectedProfileParts = splitProfile(expectedProfile);
                if (actualProfileParts.path === expectedProfileParts.path &&
                        semver.gt(actualProfileParts.version, expectedProfileParts.version)) {
                    return res;
                }
            }

            // Re-try request with no-cache header
            if (!mwUtil.isNoCacheRequest(req)) {
                req.headers['cache-control'] = 'no-cache';
                return checkContentType(hyper, req, next, expectedContentType, next(hyper, req));
            } else {
                // Log issue
                hyper.logger.log('warn/content-type/upgrade_failed', {
                    msg: 'Could not update the content-type',
                    expected: expectedContentType,
                    actual: res.headers['content-type']
                });
                // Disable response caching, as we aren't setting a vary
                // either.
                res.headers['cache-control'] = 'max-age=0, s-maxage=0';
            }
        }
        // Default: Just return.
        return res;
    });
}
function checkContentType ( hyper , req , next , expectedContentType , responsePromise ) { return responsePromise . then ( ( res ) => { // Do not check or re-render if the response was only rendered within // the last two minutes. if ( res . headers && res . headers . etag && Date . now ( ) - mwUtil . extractDateFromEtag ( res . headers . etag ) < 120000 ) { return res ; } if ( res . headers && res . headers === undefined ) { delete res . headers [ 'content-type' ] ; } if ( res . headers && res . headers [ 'content-type' ] && res . headers [ 'content-type' ] !== expectedContentType ) { // Parse the expected & response content type, and compare profiles. const expectedProfile = cType . parse ( expectedContentType ) . parameters . profile ; const actualProfile = cType . parse ( res . headers [ 'content-type' ] ) . parameters . profile ; if ( actualProfile && actualProfile !== expectedProfile ) { if ( ! expectedProfile ) { return res ; } // Check if actual content type is newer than the spec const actualProfileParts = splitProfile ( actualProfile ) ; const expectedProfileParts = splitProfile ( expectedProfile ) ; if ( actualProfileParts . path === expectedProfileParts . path && semver . gt ( actualProfileParts . version , expectedProfileParts . version ) ) { return res ; } } // Re-try request with no-cache header if ( ! mwUtil . isNoCacheRequest ( req ) ) { req . headers [ 'cache-control' ] = 'no-cache' ; return checkContentType ( hyper , req , next , expectedContentType , next ( hyper , req ) ) ; } else { // Log issue hyper . logger . log ( 'warn/content-type/upgrade_failed' , { msg : 'Could not update the content-type' , expected : expectedContentType , actual : res . headers [ 'content-type' ] } ) ; // Disable response caching, as we aren't setting a vary // either. res . headers [ 'cache-control' ] = 'max-age=0, s-maxage=0' ; } } // Default: Just return. return res ; } ) ; }
Simple content type enforcement

- Assumes that the first `produces` array entry is the latest.
- Repeats request with `no-cache` header set if the content-type does not
match the latest version.
Simple content type enforcement