Caching and CDN Optimization

Caching and CDN Optimization

Proper caching strategies can significantly reduce CSP overhead:

// CSP Caching Strategy
class CSPCachingOptimizer {
  constructor() {
    this.cacheStrategies = this.defineCacheStrategies();
  }
  
  defineCacheStrategies() {
    return {
      serverSide: {
        policyCache: `
          // Server-side CSP policy caching
          const NodeCache = require('node-cache');
          const policyCache = new NodeCache({ stdTTL: 3600 }); // 1 hour cache
          
          class CSPPolicyCache {
            generateCacheKey(req) {
              // Cache key based on user context
              return crypto.createHash('md5')
                .update(req.headers['user-agent'] || '')
                .update(req.user?.role || 'anonymous')
                .update(req.headers['accept-language'] || '')
                .digest('hex');
            }
            
            getPolicy(req) {
              const key = this.generateCacheKey(req);
              let policy = policyCache.get(key);
              
              if (!policy) {
                policy = this.generatePolicy(req);
                policyCache.set(key, policy);
              }
              
              return policy;
            }
            
            invalidateCache(pattern) {
              const keys = policyCache.keys();
              keys.forEach(key => {
                if (!pattern || key.includes(pattern)) {
                  policyCache.del(key);
                }
              });
            }
          }
        `,
        
        cdnIntegration: `
          // CDN-friendly CSP headers
          class CDNOptimizedCSP {
            constructor() {
              this.staticPolicies = new Map();
            }
            
            generateStaticPolicies() {
              // Pre-generate policies for common scenarios
              return {
                'public-cached': {
                  policy: "default-src 'self'; script-src 'self' 'sha256-...' https://cdn.example.com",
                  headers: {
                    'Cache-Control': 'public, max-age=86400',
                    'Vary': 'Accept-Encoding'
                  }
                },
                'user-specific': {
                  policy: "default-src 'self'; script-src 'self' 'nonce-PLACEHOLDER'",
                  headers: {
                    'Cache-Control': 'private, no-cache',
                    'Vary': 'Accept-Encoding, Authorization'
                  }
                }
              };
            }
            
            applyCDNOptimizations(req, res, next) {
              const path = req.path;
              
              // Static assets can use cached CSP
              if (path.match(/\.(js|css|jpg|png|gif|ico|woff|woff2)$/)) {
                res.setHeader('Content-Security-Policy', 
                  this.staticPolicies.get('public-cached').policy
                );
              } else {
                // Dynamic content needs fresh CSP
                const nonce = crypto.randomBytes(16).toString('base64');
                const policy = this.staticPolicies.get('user-specific').policy
                  .replace('PLACEHOLDER', nonce);
                res.setHeader('Content-Security-Policy', policy);
              }
              
              next();
            }
          }
        `
      },
      
      clientSide: {
        implementation: `
          // Client-side CSP caching
          class ClientCSPCache {
            constructor() {
              this.cache = new Map();
              this.maxAge = 3600000; // 1 hour
            }
            
            getCachedNonce() {
              const cached = this.cache.get('nonce');
              if (cached && Date.now() - cached.timestamp < this.maxAge) {
                return cached.value;
              }
              return null;
            }
            
            cacheNonce(nonce) {
              this.cache.set('nonce', {
                value: nonce,
                timestamp: Date.now()
              });
            }
            
            // Service Worker for CSP caching
            installServiceWorker() {
              if ('serviceWorker' in navigator) {
                navigator.serviceWorker.register('/sw.js').then(reg => {
                  console.log('Service Worker registered for CSP optimization');
                });
              }
            }
          }
        `,
        
        serviceWorker: `
          // sw.js - Service Worker for CSP optimization
          const CSP_CACHE = 'csp-cache-v1';
          const CSP_ASSETS = [
            '/js/csp-compliant-bundle.js',
            '/css/styles.css'
          ];
          
          self.addEventListener('install', event => {
            event.waitUntil(
              caches.open(CSP_CACHE).then(cache => {
                return cache.addAll(CSP_ASSETS);
              })
            );
          });
          
          self.addEventListener('fetch', event => {
            // Optimize CSP-compliant resource loading
            if (event.request.destination === 'script' || 
                event.request.destination === 'style') {
              event.respondWith(
                caches.match(event.request).then(response => {
                  if (response) {
                    // Cached response includes CSP compliance
                    return response;
                  }
                  
                  return fetch(event.request).then(response => {
                    // Cache CSP-compliant resources
                    if (response.status === 200) {
                      const responseToCache = response.clone();
                      caches.open(CSP_CACHE).then(cache => {
                        cache.put(event.request, responseToCache);
                      });
                    }
                    
                    return response;
                  });
                })
              );
            }
          });
        `
      }
    };
  }
}