Syntax highlight on nginx for every cpp without human interaction - c++

Basically, I've a webserver, where I stated in my nginx conf, to show every .cpp as plain text - but I want to make a syntax highlight for more readability.
Any idea how could I proceed?
I want to use google highlights, so any idea about how to insert before an html file before and after every .cpp would suffice.
I thought and tried in the far past using header and footer tags in nginx conf, with no luck whatsoever.
Thanks in advance!
cheers!

As was already pointed out, Nginx is not quite suitable for generating HTML documents by itself. Usually this is a job for a server-side processing language like PHP or Perl. However, there are several ways of solving the problem solely with Nginx.
The first obvious choice would be to use a server-side processing language from within Nginx. There are at least three optional modules for three different languages (Perl, Lua and a dialect of Javascript) that could be used for that.
The problem with this approach is that these modules are rarely available by default, and in many cases you will have to build Nginx manually to enable any of them. Sometimes it can be painful, because as soon as you get your own custom build of Nginx, you will have to support and upgrade it yourself.
There is, however, another option, which involves SSI. It might not be the prettiest solution but it will work. And unlike above-mentioned modules, the SSI support comes with almost every distribution of Nginx. My bet is, your Nginx can do SSI out of the box, without having to compile anything.
So, the configuration goes like this:
# Define a special virtual location for your cpp files
location ~* \.(cpp|h)$ {
# Unless a GET parameter 'raw' is set with 'yes'
if ($arg_raw = 'yes') {
break;
}
# Redirect all the requests for *.cpp and *.h files to another location #js
try_files #js #js;
}
location #js {
ssi on; # Enable SSI in this location
default_type text/html; # Tell the browser that what is returned is HTML
# Generate a suitable HTML document with an SSI insertion
return 200 '<!DOCTYPE html>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.9.0/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.9.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<pre><code class="cpp"><!--# include virtual="$uri?raw=yes" --></code></pre>';
}
Now here is what happens if you request some *.cpp file in your browser:
The request goes to the first location, because the URI ends with cpp.
Then it is redirected to the second location #js, because there is no GET parameter raw in your request.
In the second location the SSI template is generated with return and then immediately processed by the SSI engine because of ssi on.
The include virtual="$uri?raw=yes" tells the SSI engine to make another request (subrequest) from within Nginx to the originally requested file (the internal variable $uri stores the original URI, that is the web path to your cpp file). The difference between the request from your browser and the subrequest made by Nginx is ?raw=yes.
The subrequest again is handled by the first location, but it never goes to the second one, because of the raw GET parameter. In this case the raw contents of the cpp file is returned as a response to the subrequest.
The SSI engine combines this response with the rest of the template and returns the result to the browser. Additionally, default_type tells the browser to render the result as an HTML document.
You can see an example of the output here. I used this highlighting library for this example. You can change it with whatever you prefer simply modifying the SSI template.

Related

nginx pretty rewriting one parameter

I have a simple rewrite rule, but I can't get it to work (even with all the other answers here on SO)
I want the user to open this url:
www.example.com/mypage/abcd
and nginx should rewrite it to:
www.example.com/myrealpage/index.html?link=abcd
so actually I want my link parameter nicely embedded in the url.
This is the rule that almost works:
location /mypage {
rewrite ^/mypage/(.*)$ /myrealpage/index.html?link=$1 last;
}
It seems to work for the index.html file, but now all script and css imports are broken . Because every js/script.js or css/style.css becomes rewritten to mypage/abcd/css/style.css which obviously doesn't exist.
FYI:
I apparently need that rewrite mypage → myrealpage because my server provider automatically generates an alias config file that already contains a location /myrealpage so, I don't see any other option than just renaming it to add my own location rule.
How
can I alter that url to rewrite this one link parameter? It is only the one parameter.
You're rewriting every path to your /mypage directory. If you keep your scripts outside in a parent directory you'll be just fine.

replacing content in a page with varnish + regex

If I want my varnish cache server to replace content inside a page (ie: change the class on a div) from the backend before serving or storing the page (vcl_fetch?), how can this be done?
I would like to use simple regex to perform the replacement as I imagine it is supported natively in varnish.
Modifying response body is not natively supported by Varnish. You need a Varnish module (vmod) for this.
Aivars Kalvans has libvmod-rewrite, which does exactly what you are looking for. However the vmod is a proof of concept and according to Aivars it is not ready for production use. You can use it as a starting point in any case.
If you are using Apache, you can use mod_ext_filter to modify response body. Here's an example from mod_ext_filters documentation. Since you can pass the response body to any external command, it is very easy to do the necessary modifications to the content.
# mod_ext_filter directive to define a filter which
# replaces text in the response
#
ExtFilterDefine fixtext mode=output intype=text/html cmd="/bin/sed s/verdana/arial/g"
<Location />
# core directive to cause the fixtext filter to
# be run on output
SetOutputFilter fixtext
</Location>

Is there a "clean URL" (mod_rewrite) equivalent for iPlanet?

I'm working with Coldfusion (because I have to) and we use iPlanet 7 (because we have to), and I would like to pass clean URL's instead of the query-param junk (for numerous reasons). My problem is I don't have access to the overall obj.conf file, and was wondering if there were .htaccess equivalents I could pass on the fly per directory. Currently I am using Application.cfc to force the server to look at index.cfm in root before loading the requested page, but this requires a .cfm file is passed, so it just 404's out if the user provides /path/to/file but no extension. Ultimately, I would like to allow the user to pass domain.com/path/to/file but serve domain.com/index.cfm?q1=path&q2=to&q3=file. Any ideas?
You can mod_dir with the DirectoryIndex directive to set which page is served on /directory/ requests.
http://httpd.apache.org/docs/2.2/mod/mod_dir.html
I'm not sure what exists for iPlanet, haven't had to work with it before. But it would be possible to use a url like index.cfm/path/to/file, and pull the extra path information via the cgi.path_info variable. Not exactly what you're looking for, but cleaner that query-params.

Django, Serving combined static files behine nginx with apache proxies?

I've been looking into combining static files and serving them as one file. But how would I go about doing this when my django stack is on a apache proxy with a nginx loadbalancer?
regards
Bjarni I.
You might want to look into nginx's try_files directive. Write a view in your Django code that will compress the files and put them onto your nginx server (or something else it can access, like an NFS share), and then have nginx try_files for the version it has first, before falling back to your Django file cruncher if the file doesn't exist yet (at which point nginx would serve it next time).
You might try django-compress. In your settings module, you define groups of static files (js, css), that compress will, well, compress into one file per group. There's then a couple of template tags that you use to include the compressed files in your templates.
For example
#settings.py
COMPRESS_CSS = {
'main': {
'source_filenames': ('css/960gs.css',
'css/main.css',
),
'output_filename': 'css/main.min.r?.css',
'extra_context': {
'media': 'screen,projection',
},
},
# other CSS groups goes here
}
Then, somewhere in your templates (most likely your base template), you use {% compressed_css 'main' %}.
You can define multiple groups if you have some css/js that you want to include in all pages, but some you only want to include in certain pages, or whatever you need. It's pretty flexible.
You can also easily turn compression off for easy debugging.
It also adds a unique version number to the resulting compressed file(s) to get around browser caching problem. This is the r? portion of output_filename.

Django return large file

I am trying to find the best way (most efficient way) to return large files from Django back to an http client.
receive http get request
read large file from disk
return the content of that file
I don't want to read the file then post the response using HttpResponse as the file content is first stored in RAM if I am correct. How can I do that efficiently ?
Laurent
Look into mod_xsendfile on Apache (or equivalents for nginx, etc) if you like to use Django for authentication. Otherwise, there's no need to hit django, and just server straight from Apache.
There is a ticket that aims to deal with this problem here: http://code.djangoproject.com/ticket/2131
It adds an HttpResponseSendFile class that uses sendfile() to send the file, which transparently sends the file as it's read.
However, the standard HttpResponse is implemented as an iterator, so if you pass it a file-like object, it will follow its iteration semantics, so presumably you could create a file-like object wrapper that chunks the file in small enough pieces before sending them out.
I believe the semantics of iterating over a standard file object in python is that it reads line-by-line, which most likely won't solve your problem if you're dealing with binary files.
Of course, you could always put the static files in another location and serve that with a normal web server, unless you require intricate control (like access control requiring knowledge of the Django database)
My preference for all of this is to synthesize django with your http server so that when you want to serve static files, you simply refer them to a path that will never reach django. The strategy will look something like this:
Configure http server so that some requests go to django and some go to a static document root
link to static documents from any web pages that obviously need the static documents (e.g. css, javascript, etc.)
for any non-obvious return of a static document, use an HttpRedirect("/web-path/to/doc").
If you need to include the static document inside a dynamic document (maybe a page-viewer wrapping a large text or binary file), then return a wrapper page that populates a div with an ajax call to your static document.