Score:0

Configure NGINX to deliver different JSON content based on $http_referrer

cn flag

I am working on a service + webapp + mobile app combo where

  • the mobile app is used to consume content
  • created by an open community of authors on the web app
  • with the whole being serviced by a server running Nginx on Ubuntu (well some requests are proxied off to backend Nginx servers) but that is a detail

The issue that I want to deal with efficiently is the one arising from the fact that the content can be created by an open community - pretty much anyone can click a few buttons and start the process of creating content in response to which the server generates stub content in the form of a JSON file for the content authors to customize.

Now, here is the problem - I want to avoid wasting server time and disk storage creating stub JSON content for authors who start off the process but never really execute on it (translation = signup to create content and then never do).

In other words I want to create stub JSON content for authors only when I am sure that they are actually going to embark on the process of customizing it. At the same time I want to ensure that the mobile app gets a graceful 404 error for CDN pulled content that it attempts to grab via a CDN.

In other words there are two sets of "consumers" for the content

  1. Content authors who will typically request the content directly off my servers via a backoffice webapp which will turn up on NGINX as `$http_reffer = https://example.com/backoffice'
  2. The CDN which will attempt to pull that same content from the same location in response to requests from the mobile app.

The default responses for missing content are

  1. Content Authors: Stub JSON is generated and sent back
  2. CDN: No content JSON file exists so a 404 header is sent back

The solution I have in mind is along the following Nginx configuration block

location /cdn/appdata/content
{
 add_header Access-Control-Allow-Origin *;
 if ($http_referer ~* ^https://example.com/backoffice) 
 {
  if (!-e $request_filename) {rewrite ^/(.*)$ /pathto/stub-json-generator.php?$1 last;}
 } 
} else ??? /* squirt back existing JSON or respond with 404.  Both to the CDN requestor

I dabble with Nginx config from time to time but am no expert. My question - is what I have outlined a decent way of going about this task or do I need to delve deeper into Nginx scripting via JS or Lua? Lua scripting requires installation of Open Resty which is something I would like to avoid since I have Nginx already configured to work with NChan and Dart which I would then have to do all over again for Open Resty. That apart, attempting to access Redis and Postgres from within a Lua script will take me into unfamiliar territory.


I could quite simply delete this question but I am leaving it here with my solution for the benefit of anyone else looking to do something similar.

The solution is in fact blindingly simple and is not entirely an Nginx configuration issue. The important thing to realize is that Nginx is working on top of Ubuntu and has now way of distinguishing between a real folder and a symlink. So suppose we did the following

  • Assign the folder /path/to/authordata the symlink /path/to/readercontent thus
  • ln -s /path/to/authordata /path/to/readercontent

Now set up the following Nginx configuration blocks

location /path/to/authordata
{
 add_header Access-Control-Allow-Origin *;
 rewrite ^(.*)$ /path/to/authordata/index.php?$1 last;
}

 location /path/to/readercontent
 {
  add_header Access-Control-Allow-Origin *;
 }

Unbeknownst to each other these two blocks are actually addressing the same Ubuntu folder.

We use the former to access author data for editing. Since the contents are delivered by a PHP script we have the ability to generate stub content on-the-go. That way there is no never-to-be-used default author stub content clogging up the server.

We use the latter to get reading matter into the mobile app via a CDN pull request. A missing author data resource will result in a standard 404 response. The CORS header, which could be more specific, stops the CDN from having its attempt to pull data bounced off

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.