Advertisement
Guest User

Untitled

a guest
Aug 29th, 2022
321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. addEventListener("fetch", event => {
  2.   /*event.respondWith(handleRequest(event.request))*/
  3.   event.respondWith(handleRequest(event))
  4. })
  5.  
  6. /**
  7.  * Fetch and log a request
  8.  * @param {Request} request
  9.  */
  10.  
  11. async function handleRequest(event) {
  12.   const request = event.request
  13. //  console.log(request.url)
  14.   if(request.method == "GET") {
  15.       // Your Worker is responsible for automatic format negotiation. Check the Accept header. Avoid the cache returning an unsupported image format. Instead, check the acceptable format and cache the different formats independently.
  16.       const accept = request.headers.get("Accept");
  17.       let format = ""
  18.       if (/image\/avif/.test(accept)) {
  19.         // format = "avif"
  20.         format = "native"
  21.       } else if (/image\/webp/.test(accept)) {
  22.         format = "webp"
  23.       } else {
  24.         format = "native"
  25.       }
  26.  
  27.       // Hook in to the cache and have any cache-control headers respected
  28.       const cache = caches.default;
  29.       let resp = await cache.match(request.url + "&" + format)
  30.       // let resp = null; //test code
  31.      
  32.       if (!resp) { // If not found in the edge cache, proceed to R2 check
  33.  
  34.         // Make some variables to get the original request's info and params
  35.         const cacheCheckURL = new URL(request.url);
  36.         const cacheCheckImagePath = cacheCheckURL.searchParams.get("image").substring(1); // get rid of that leading slash since it was issues
  37.         const cacheCheckImageQ = cacheCheckURL.searchParams.get("q");
  38.         const cacheCheckImageW = cacheCheckURL.searchParams.get("w");
  39.  
  40.         // Check if the image is in the R2 bucket
  41.         let R2Object = await IR_CACHE.get(cacheCheckImagePath + "&" + format + "&" + cacheCheckImageQ + "&" + cacheCheckImageW);
  42.  
  43.         // If R2Object is available [i.e., it exists or is not stale (2 weeks)], then we'll return it directly. Otherwise, we have to run Image Resizing again and add it into both Edge Cache and R2 bucket.
  44.         if (R2Object && new Date() - R2Object.uploaded < 1000 * 60 * 60 * 24 * 7 * 2) {
  45.           // The resized image is in the R2 bucket so we just return that in full
  46.           console.log("Matched R2 Cache");
  47.  
  48.           // Set the relevant headers as necessary
  49.           const R2ObjectHeaders = new Headers(request.headers);
  50.           R2ObjectHeaders.set("Cache-Control", "public, max-age=604800, stale-while-revalidate=86400");
  51.           R2ObjectHeaders.set('etag', R2Object.httpEtag);
  52.           R2ObjectHeaders.set("R2-Status", "HIT");
  53.           resp = new Response(R2Object.body, {headers: R2ObjectHeaders}); // return the R2 object
  54.  
  55.           // if R2 is hit that meant Edge Cache got evicted. Put request back into edge cache to still utilize that over R2 preferably.
  56.           event.waitUntil(cache.put(request.url + "&" + format, resp.clone()));
  57.         } else {
  58.           // Run Image Resizing per resize params
  59.           resp = await runResize(request)
  60.           // Use event waitUntil so we can send the response but
  61.           // script keeps executing until the response is saved in the cache
  62.           if(resp.status == 200) {
  63.             // Put the resized image into Colo Cache
  64.             event.waitUntil(cache.put(request.url + "&" + format, resp.clone()));
  65.  
  66.             // Put the resized image into R2 bucket
  67.             event.waitUntil(
  68.               IR_CACHE.put(cacheCheckImagePath + "&" + format + "&" + cacheCheckImageQ + "&" + cacheCheckImageW, resp.clone().body, {
  69.                 // Use the headers from the Image Resizing response so we maintain contentType and other HTTP headers
  70.                 httpMetadata: resp.headers,
  71.                 // Add some custom metadata to the R2 object just in case even though we'll probably not need it
  72.                 customMetadata: {
  73.                   format: format,
  74.                   putDate: new Date().toISOString()
  75.                 }
  76.               })
  77.             );
  78.           }
  79.         }
  80.       } else {
  81.         console.log("Matched Edge Cache")
  82.       }
  83.  
  84.       return resp
  85.   }
  86.  
  87.   // const resp = await runResize(request)
  88.   // console.log("second return")
  89.   // return resp
  90. }
  91.  
  92.  
  93. async function runResize(request) {
  94.   // Parse request URL to get access to query string
  95.   let url = new URL(request.url)
  96.  
  97.   // console.log(url.searchParams.get("w"))
  98.  
  99.   // Cloudflare-specific options are in the cf object.
  100.   let options = { cf: { image: {} } }
  101.  
  102.   // Copy parameters from query string to request options.
  103.   // You can implement various different parameters here.
  104.   options.cf.image.fit = "contain"
  105.   if (url.searchParams.has("w")) options.cf.image.width = url.searchParams.get("w")
  106.   if (url.searchParams.has("q")) {
  107.       options.cf.image.quality = url.searchParams.get("q")
  108.   } else {
  109.       options.cf.image.quality = "100"
  110.   }
  111.  
  112.   if ( options.cf.image.width == "2560" ) {
  113.     options.cf.image.draw = [{
  114.           url: "https://fjlaboratories.com/cdn/miscellaneous/watermark.png", // draw this image
  115.           bottom: 30, // 5 pixels from the bottom edge
  116.           right: 30, // 5 pixels from the right edge
  117.           fit: "contain", // make it fit within 100x50 area
  118.           width: 120,
  119.           opacity: 0.6, // 20% transparent
  120.     }]
  121.   }
  122.  
  123.   // console.log(options.cf.image)
  124.  
  125.   // Your Worker is responsible for automatic format negotiation. Check the Accept header.
  126.   const accept = request.headers.get("Accept");
  127.   if (/image\/avif/.test(accept)) {
  128.     //options.cf.image.format = 'avif';
  129.   } else if (/image\/webp/.test(accept)) {
  130.     options.cf.image.format = 'webp';
  131.   }
  132.  
  133.   // Get URL of the original (full size) image to resize.
  134.   // You could adjust the URL here, e.g., prefix it with a fixed address of your server,
  135.   // so that user-visible URLs are shorter and cleaner.
  136.   const imageURL = "https://fjlaboratories.com/r2-images/" + url.searchParams.get("image") + "?key=" + IR_KEY
  137.   if (!url.searchParams.get("image")) return new Response('Missing "image" value', { status: 400 })
  138.  
  139.   console.log(imageURL)
  140.  
  141.   try {
  142.     // TODO: Customize validation logic
  143.     const { hostname, pathname } = new URL(imageURL)
  144.  
  145.     // Optionally, only allow URLs with JPEG, PNG, GIF, or WebP file extensions
  146.     // @see https://developers.cloudflare.com/images/url-format#supported-formats-and-limitations
  147.     if (!/\.(jpe?g|png|gif|webp)$/i.test(pathname)) {
  148.       return new Response('Disallowed file extension', { status: 400 })
  149.     }
  150.  
  151.     // Demo: Only accept "example.com" images
  152. //    if (hostname !== 'r2-images-fetch.fj-homelab.workers.dev) {
  153. //      return new Response('Must use "fjlaboratories.com" source images', { status: 403 })
  154.  //   }
  155.   } catch (err) {
  156.     return new Response('Invalid "image" value', { status: 400 })
  157.   }
  158.  
  159.   // Build a request that passes through request headers
  160.   const imageRequest = new Request(imageURL, {
  161.     headers: request.headers
  162.   })
  163.  
  164.   // Returning fetch() with resizing options will pass through response with the resized image.
  165.   const resizedRes = await fetch(imageRequest, options);
  166.  
  167.   // console.log(resizedRes);
  168.  
  169.   const cachedHeaders = new Headers(resizedRes.headers);
  170.   cachedHeaders.set("Cache-Control", "public, max-age=604800, stale-while-revalidate=86400");
  171.  
  172.   return new Response(resizedRes.body, {
  173.     headers: cachedHeaders
  174.   });
  175.  
  176.   // https://dev-images.fjlaboratories.com/?image=/feature-images/shubham-dhage-fcbnWSjh1U8-unsplash.jpg&w=1920&q=70
  177.  
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement