I'm trying to setup varnish to handle my default url which is example.url.co.uk.
If it hits example.url.co.uk or example.url.co.uk/ I want it to redirect or rewrite to example.url.co.uk/site which within the tomcat application sends it to a login page.
sub vcl_recv {
if ((req.url ~ "") || (req.url ~"^/")) {
set req.http.location = "https://example.url.co.uk/site" + req.url;
return (synth(750, "Found"));
}
}
sub vcl_synth {
if (resp.status == 301) {
set resp.http.Location = req.http.x-redir;
return (deliver);
}
if (resp.status == 750) {
set resp.http.Location = req.http.location;
set resp.status = 302;
return (deliver);
}
}
However when I use my attempt that this I get example.url.co.uk/site/site/site/site...
So I'm obviously stuck in a loop and I've been banging my head on this for a week trying to find the right solution! Please save me from my own stupidity I'm sure!
the problem is that req.url ~ "" matches everthing. as it is used as a regular expression. also your req.url ~ "^/" is too open.
changing it to:
if (req.url == "" || req.url ~"^/$") {
should fix it, verifying that it is either empty or / it self.
here is a simple varnishtest to verify the behaviour:
varnishtest "Test Redirect"
server s1 {
rxreq
txresp
rxreq
txresp
} -start
varnish v1 -vcl+backend {
sub vcl_recv {
if (req.url == "" || req.url ~"^/$") {
set req.http.location = "https://example.url.co.uk/site" + req.url;
return (synth(750, "Found"));
}
}
sub vcl_synth {
if (resp.status == 301) {
set resp.http.Location = req.http.x-redir;
return (deliver);
}
if (resp.status == 750) {
set resp.http.Location = req.http.location;
set resp.status = 302;
return (deliver);
}
}
} -start
client c1 {
txreq -url "/"
rxresp
expect resp.status == 302
} -run
client c1 {
txreq -url "/site"
rxresp
expect resp.status == 200
} -run
you can run it with varnishtest test.vtc
Related
I'm trying to setup multiple backends for my Varnish configuration after recently adding some new domains/websites to my server.
Complete VCL below...
backend default {
.host = "127.0.0.1";
.port = "8080";
.connect_timeout = 600s;
.first_byte_timeout = 600s;
.between_bytes_timeout = 600s;
}
backend scrum {
.host = "127.0.0.2";
.port = "8080";
.connect_timeout = 600s;
.first_byte_timeout = 600s;
.between_bytes_timeout = 600s;
}
backend striker {
.host = "127.0.0.3";
.port = "8080";
.connect_timeout = 600s;
.first_byte_timeout = 600s;
.between_bytes_timeout = 600s;
}
backend throttle {
.host = "127.0.0.4";
.port = "8080";
.connect_timeout = 600s;
.first_byte_timeout = 600s;
.between_bytes_timeout = 600s;
}
backend ussports {
.host = "127.0.0.5";
.port = "8080";
.connect_timeout = 600s;
.first_byte_timeout = 600s;
.between_bytes_timeout = 600s;
}
acl purge {
"localhost";
"127.0.0.1";
"127.0.0.2";
"127.0.0.3";
"127.0.0.4";
"127.0.0.5";
"127.0.0.6";
"127.0.0.7";
"127.0.0.8";
"54.253.117.205";
}
sub vcl_recv {
# Backends
set req.backend = default;
if (req.http.host ~ "(?i)^(www.)?scrum.com$") {
set req.http.host = "www.scrum.com";
set req.backend = scrum;
}
if (req.http.host ~ "(?i)^(www.)?striker.com$") {
set req.http.host = "www.striker.com";
set req.backend = striker;
}
if (req.http.host ~ "(?i)^(www.)?throttle.com$") {
set req.http.host = "www.throttle.com";
set req.backend = throttle;
}
if (req.http.host ~ "(?i)^(www.)?ussports.com$") {
set req.http.host = "www.ussports.com";
set req.backend = ussports;
}
# Don't cache these for now
if (req.http.host ~ "(www\.)?(digital.com|hanger.com|wicket.com)") {
return (pass);
}
# Don't cache admin
if (req.http.host == "sendy.tackle.com" || req.http.host == "admin.tackle.com" || req.http.host == "admin.hanger.com" || req.http.host == "admin.wicket.com" || req.http.host == "admin.striker.com" || req.http.host == "admin.scrum.com" || req.http.host == "admin.throttle.com" || req.http.host == "admin.ussports.com") {
return (pass);
}
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
ban("req.http.host == " + req.http.host);
}
# Normalize content-encoding
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|lzma|tbz)(\?.*|)$") {
remove req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
remove req.http.Accept-Encoding;
}
}
if (req.restarts == 0) {
if (req.http.CF-Connecting-IP) {
set req.http.X-Forwarded-For = req.http.CF-Connecting-IP;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
# Device detection
set req.http.X-Device = "desktop";
if ( req.http.User-Agent ~ "iP(hone|od)" || req.http.User-Agent ~ "Android" ) {
set req.http.X-Device = "smart";
}
# don't cache authenticated sessions
if (req.http.Cookie && req.http.Cookie ~ "(wordpress_|PHPSESSID)") {
return(pass);
}
# Remove cookies and query string for real static files
if (req.url ~ "^/[^?]+\.(gif|jpg|jpeg|swf|css|js|txt|flv|mp3|mp4|pdf|ico|png|gz|zip|lzma|bz2|tgz|tbz)(\?.*|)$") {
unset req.http.cookie;
set req.url = regsub(req.url, "\?.*$", "");
}
# Don't cache backend
if (req.url ~ "wp-(login|admin|comments-post.php|cron.php)" || req.url ~ "preview=true") {
return (pass);
}
# Don't cache backend
if (req.url ~ "(discussion|server-status|pick-your-test-team|pick-your-team|apc.php|xmlrpc.php|_showprocesslist.php)") {
return (pass);
}
if (req.request == "POST")
{
return(pass);
}
return (lookup);
}
sub vcl_hit {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}
sub vcl_fetch {
# Don't cache these for now
if (req.http.host ~ "(www\.)?(digital.com|hanger.com|wicket.com)") {
return (hit_for_pass);
}
# Don't cache admin
if (req.http.host == "sendy.tackle.com" || req.http.host == "admin.tackle.com" || req.http.host == "admin.hanger.com" || req.http.host == "admin.wicket.com" || req.http.host == "admin.striker.com" || req.http.host == "admin.scrum.com" || req.http.host == "admin.throttle.com" || req.http.host == "admin.ussports.com") {
return (hit_for_pass);
}
# Don't store backend
if (req.url ~ "wp-(login|admin|comments-post.php|cron.php)" || req.url ~ "preview=true") {
return (hit_for_pass);
}
# If WordPress cookies found then page is not cacheable
if (req.http.Cookie ~"(wp-postpass|wordpress_logged_in|comment_author_)") {
return (hit_for_pass);
}
# Don't cache backend
if (req.url ~ "(discussion|server-status|pick-your-test-team|pick-your-team|apc.php|xmlrpc.php|_showprocesslist.php)") {
return (hit_for_pass);
}
if ( (!(req.url ~ "(wp-(login|admin|comments-post.php|server-status|discussion|cron.php)|login)")) || (req.request == "GET") ) {
unset beresp.http.set-cookie;
set beresp.ttl = 4h;
}
if (req.url ~ "\.(gif|jpg|jpeg|swf|css|js|txt|flv|mp3|mp4|pdf|ico|png)(\?.*|)$") {
set beresp.ttl = 30d;
}
#else {
# set beresp.do_esi = true;
#}
}
sub vcl_deliver {
# add debugging headers, so we can see what's cached
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
# remove some headers added by varnish
unset resp.http.Via;
unset resp.http.X-Varnish;
}
#
sub vcl_hash {
hash_data( req.url );
# And then add the device to the hash (if its a mobile device)
if (req.http.X-Device ~ "^smart") {
hash_data( req.http.X-Device );
}
# altering hash so subdomains are ignored.
# don't do this if you actually run different sites on different subdomains
# if ( req.http.host ) {
# hash_data( regsub( req.http.host, "^([^\.]+\.)+([a-z]+)$", "\1\2" ) );
# } else {
# hash_data( server.ip );
# }
# ensure separate cache for mobile clients (WPTouch workaround)
if( req.http.User-Agent ~ "(iPod|iPhone|incognito|webmate|dream|CUPCAKE|WebOS|blackberry9\d\d\d)" ){
hash_data("touch");
}
return (hash);
}
Now, my default site www.tackle.com works fine and has for a while. As I said, I've since added some new sites to the server and would like to deliver them from Varnish.
I find that somewhat randomly, if I visit www.scrum/throttle/striker.com, I end up getting the www.tackle.com homepage. So, I've obviously got something wrong.
Any idea what I'm missing?
I'm having problem configuring default.vcl: varnish is blocking the Login into phpMyAdmin and always show me the Login page after authentication.
The web server must only host WordPress sites and the phpMyAdmin where each user can administer his database.
http://phpMyAdmin.domain.com //for phpMyAdmin where users access their database
http://www.site1.com
http://www.site2.com
http://www.site3.com //and so on
Where I'm in error or missing something?
This is my actual default.vcl
backend default {
.host = "127.0.0.1";
.port = "8000";
}
acl purge {
# Web server with plugin which will issue PURGE requests
"127.0.0.1";
"localhost";
}
sub vcl_recv {
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
ban("req.url ~ ^" + req.url + "$ && req.http.host == " + req.http.host);
}
# Normalize content-encoding
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|lzma|tbz)(\?.*|)$") {
remove req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
remove req.http.Accept-Encoding;
}
}
# Remove cookies and query string for real static files
if (req.url ~ "^/[^?]+\.(gif|jpg|jpeg|swf|css|js|txt|flv|mp3|mp4|pdf|ico|png|gz|zip|lzma|bz2|tgz|tbz)(\?.*|)$") {
unset req.http.cookie;
set req.url = regsub(req.url, "\?.*$", "");
}
# Don't cache backend
if (req.url ~ "wp-(login|admin|comments-post.php|cron.php)") {
return (pass);
}
if (req.url ~ "pmacloud") {
return(pass);
}
return (lookup);
}
sub vcl_fetch {
# Don't store backend
if (req.url ~ "wp-(login|admin|comments-post.php|cron.php)" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") {
return (hit_for_pass);
}
if ( (!(req.url ~ "(wp-(login|admin|comments-post.php|cron.php)|login)")) || (req.request == "GET") ) {
unset beresp.http.set-cookie;
set beresp.ttl = 4h;
}
if (req.url ~ "\.(gif|jpg|jpeg|swf|css|js|txt|flv|mp3|mp4|pdf|ico|png)(\?.*|)$") {
set beresp.ttl = 30d;
} #else {
# set beresp.do_esi = true;
#}
}
sub vcl_hit {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}
The solution to enable access to phpMyAdmin is to add in
sub vcl_recv
if (req.http.Host == "phpMyAdmin.domain.com") {
return (pass);
}
sub vcl_fetch
if (req.http.Host == "phpMyAdmin.domain.com") {
return (hit_for_pass);
}
In your vcl_fetch you are dropping set-cookie header for everything else but WordPress specific URLs.
Speficically:
# Don't store backend
if (req.url ~ "wp-(login|admin|comments-post.php|cron.php)" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") {
return (hit_for_pass);
}
if ( (!(req.url ~ "(wp-(login|admin|comments-post.php|cron.php)|login)")) || (req.request == "GET") ) {
unset beresp.http.set-cookie;
set beresp.ttl = 4h;
}
You need to adjust both these lines to look for phpMyAdmin specific URLs or domains.
For example if phpMyAdmin is always hosted on phpmyadmin.domain.com you could do the following:
# Don't store backend
if (
req.http.host ~ "phpmyadmin"
|| req.url ~ "wp-(login|admin|comments-post.php|cron.php)"
|| req.url ~ "preview=true"
|| req.url ~ "xmlrpc.php"
) {
return (hit_for_pass);
}
if (
req.http.host ~ "phpmyadmin"
|| (!(req.url ~ "(wp-(login|admin|comments-post.php|cron.php)|login)"))
|| (req.request == "GET")
) {
unset beresp.http.set-cookie;
set beresp.ttl = 4h;
}
Hi I have a very weird issue with Wordpress 3.5 Varnish 3.02 and Ubuntu where the visual editor has disappeared. The buttons to switch between the html/visual has disappeared and only the html editor is showing. The site is caching fine, no javascript error and no error in apache log. Varnish is listening on 80 and Apache on 8080. Everything else work fine except the editor.
When I bypass varnish the editor switch buttons appear and work fine. Here is what I have done so far without success:
- All plugins disabled
- Switched to Default theme
- Checked firebug for any jquery error (NONE)
- Bypassed Varnish (Everything works fine)
- Purged Varnish cache (No luck)
- Re-uploaded all default wordpress files
- Switched to an earlier version of Wordpress (3.5)
What do you think might be the problem? I have been scratching my head for a week now on this issue.
VCL FILE
backend default {
.host = "x.x.x.x";
.port = "8080";
}
sub vcl_recv {
if (req.http.host ~ "mydomain.com") {
set req.http.x-Redir-Url = "http://www.anotherdomain.com/specific_folder/";
error 750 req.http.x-Redir-Url;
}
}
include "devicedetect.vcl";
# Called after a document has been successfully retrieved from the backend.
sub vcl_recv {
call devicedetect;
# Allow the back-end to serve up stale content if it is responding slowly.
set req.grace = 2m;
# Always cache the following file types for all users.
if ( req.url ~ "(?i)\.(png|gif|jpeg|jpg|ico|swf|css|js|html|htm)(\?[a-z0-9]+)?$" ) {
unset req.http.cookie;
}
# Don't serve cached pages to logged in users
if ( req.http.cookie ~ "wordpress_logged_in" || req.url ~ "vaultpress=true" ) {
return( pass );
}
# Drop any cookies sent to WordPress.
if ( ! ( req.url ~ "wp-(login|admin)" ) ) {
unset req.http.cookie;
}
# Handle compression correctly. Different browsers send different
# "Accept-Encoding" headers, even though they mostly all support the same
# compression mechanisms. By consolidating these compression headers into
# a consistent format, we can reduce the size of the cache and get more hits.
# #see: http://varnish.projects.linpro.no/wiki/FAQ/Compression
if ( req.http.Accept-Encoding ) {
if ( req.http.Accept-Encoding ~ "gzip" ) {
# If the browser supports it, we'll use gzip.
set req.http.Accept-Encoding = "gzip";
}
else if ( req.http.Accept-Encoding ~ "deflate" ) {
# Next, try deflate if it is supported.
sset req.http.Accept-Encoding = "deflate";
}
else {
# Unknown algorithm. Remove it and send unencoded.
unset req.http.Accept-Encoding;
}
}
}
# MOBILE AND UA DETECTION - override the header before it is sent to the backend
sub vcl_miss { if (req.http.X-UA-Device) { set bereq.http.User-Agent = req.http.X-UA-Device; } }
sub vcl_pass { if (req.http.X-UA-Device) { set bereq.http.User-Agent = req.http.X-UA-Device; } }
sub vcl_fetch {
#SET UA BEFORE SENDING TO BACKEND
if (req.http.X-UA-Device) {
if (!beresp.http.Vary) { # no Vary at all
set beresp.http.Vary = "X-UA-Device";
} elseif (beresp.http.Vary !~ "X-UA-Device") { # add to existing Vary
set beresp.http.Vary = beresp.http.Vary + ", X-UA-Device";
}
}
set beresp.http.X-UA-Device = req.http.X-UA-Device;
#Fix Login under wordpress
if (beresp.http.set-cookie ~ "sessionid" || beresp.http.set-cookie ~ "csrftoken") {
# return (pass);
} else {
return (deliver);
}
set beresp.ttl = 20m;
# Allow items to be stale if needed.
set beresp.grace = 2m;
# Drop any cookies WordPress tries to send back to the client.
if ( ! req.url ~ "wp-(login|admin)" && ! req.http.cookie ~ "wordpress_logged_in" ) {
unset beresp.http.set-cookie;
}
}
sub vcl_error {
#REDIRECTION
if (obj.status == 750) {
set obj.http.Location = obj.response;
set obj.status = 301;
return (deliver);
}
set obj.http.Content-Type = "text/html; charset=utf-8";
set obj.http.Retry-After = "5";
synthetic {"
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>OOPS UNE ERREUR S'EST PRODUITE</title>
<style src="css/style.css"></style>
</head>
<body>
<h1>Oh! Oh! Nos excuses. Une erreure s'est produite. On s'en occupe.</h1>
</body>
</html>
"};
return (deliver);
}
sub vcl_deliver {
if ((req.http.X-UA-Device) && (resp.http.Vary)) {
set resp.http.Vary = regsub(resp.http.Vary, "X-UA-Device", "User-Agent");
}
}
**************THIS IS ANOTHER FILE(devicedetect.vcl)**********************
INCLUDED DEVICE DETECTION:
#
# detectdevice.vcl - regex based device detection for Varnish
# http://github.com/varnish/varnish-devicedetect/
#
# Author: Lasse Karstensen <lasse#varnish-software.com>
sub devicedetect {
unset req.http.X-UA-Device;
set req.http.X-UA-Device = "pc";
# Handle that a cookie may override the detection alltogether.
if (req.http.Cookie ~ "(?i)X-UA-Device-force") {
/* ;?? means zero or one ;, non-greedy to match the first. */
set req.http.X-UA-Device = regsub(req.http.Cookie, "(?i).*X-UA-Device-force=([^;]+);??.*", "\1");
/* Clean up our mess in the cookie header */
set req.http.Cookie = regsuball(req.http.Cookie, "(^|; ) *X-UA-Device-force=[^;]+;? *", "\1");
/* If the cookie header is now empty, or just whitespace, unset it. */
if (req.http.Cookie ~ "^ *$") { unset req.http.Cookie; }
} else {
if (req.http.User-Agent ~ "(?i)(ads|google|bing|msn|yandex|baidu|ro|career|)bot" ||
req.http.User-Agent ~ "(?i)(baidu|jike|symantec)spider" ||
req.http.User-Agent ~ "(?i)scanner" ||
req.http.User-Agent ~ "(?i)(web)crawler") {
set req.http.X-UA-Device = "bot"; }
elsif (req.http.User-Agent ~ "(?i)ipad") { set req.http.X-UA-Device = "tablet-ipad"; }
elsif (req.http.User-Agent ~ "(?i)ip(hone|od)") { set req.http.X-UA-Device = "mobile-iphone"; }
/* how do we differ between an android phone and an android tablet?
http://stackoverflow.com/questions/5341637/how-do-detect-android-tablets-in-general-useragent */
elsif (req.http.User-Agent ~ "(?i)android.*(mobile|mini)") { set req.http.X-UA-Device = "mobile-android"; }
// android 3/honeycomb was just about tablet-only, and any phones will probably handle a bigger page layout.
elsif (req.http.User-Agent ~ "(?i)android 3") { set req.http.X-UA-Device = "tablet-android"; }
// May very well give false positives towards android tablets. Suggestions welcome.
elsif (req.http.User-Agent ~ "(?i)android") { set req.http.X-UA-Device = "tablet-android"; }
elsif (req.http.User-Agent ~ "Mobile.+Firefox") { set req.http.X-UA-Device = "mobile-firefoxos"; }
elsif (req.http.User-Agent ~ "^HTC" ||
req.http.User-Agent ~ "Fennec" ||
req.http.User-Agent ~ "IEMobile" ||
req.http.User-Agent ~ "BlackBerry" ||
req.http.User-Agent ~ "SymbianOS.*AppleWebKit" ||
req.http.User-Agent ~ "Opera Mobi") {
set req.http.X-UA-Device = "mobile-smartphone";
}
elsif (req.http.User-Agent ~ "(?i)symbian" ||
req.http.User-Agent ~ "(?i)^sonyericsson" ||
req.http.User-Agent ~ "(?i)^nokia" ||
req.http.User-Agent ~ "(?i)^samsung" ||
req.http.User-Agent ~ "(?i)^lg" ||
req.http.User-Agent ~ "(?i)bada" ||
req.http.User-Agent ~ "(?i)blazer" ||
req.http.User-Agent ~ "(?i)cellphone" ||
req.http.User-Agent ~ "(?i)iemobile" ||
req.http.User-Agent ~ "(?i)midp-2.0" ||
req.http.User-Agent ~ "(?i)u990" ||
req.http.User-Agent ~ "(?i)netfront" ||
req.http.User-Agent ~ "(?i)opera mini" ||
req.http.User-Agent ~ "(?i)palm" ||
req.http.User-Agent ~ "(?i)nintendo wii" ||
req.http.User-Agent ~ "(?i)playstation portable" ||
req.http.User-Agent ~ "(?i)portalmmm" ||
req.http.User-Agent ~ "(?i)proxinet" ||
req.http.User-Agent ~ "(?i)sonyericsson" ||
req.http.User-Agent ~ "(?i)symbian" ||
req.http.User-Agent ~ "(?i)windows\ ?ce" ||
req.http.User-Agent ~ "(?i)winwap" ||
req.http.User-Agent ~ "(?i)eudoraweb" ||
req.http.User-Agent ~ "(?i)htc" ||
req.http.User-Agent ~ "(?i)240x320" ||
req.http.User-Agent ~ "(?i)avantgo") {
set req.http.X-UA-Device = "mobile-generic";
}
}
}
I've stumbled upon this question while having the same issue. I tried doing what the asker suggested in the follow-up "response" but I was out of luck.
The problem that was described in the question arises from the fact that Wordpress enables the TinyMCE (Visual) editor only when the user-agent matches a known one. For everything else, it will disable it by default. Combined with devicedetect.vcl, you can probably see where this is going...
So, because we are sending "pc", "mobile-platform" etc. to the backend (Wordpress), it will never actually know the browser you are using.
In my VCL I disable caching for /wp-admin completely with the following code:
if (req.url ~ "/wp-(login|admin)") {
return (pass);
}
When I implemented devicedetect.vcl I was calling the routine at the top of my sub vcl_recv, thus the user-agent was already reaching my backend in a modified state.
The solution is to return (pass) on /wp-(login|admin) BEFORE you call devicedetect, like this:
if (req.url ~ "/wp-(login|admin)") {
return (pass);
}
call devicedetect;
Yes it was happening whether logged in or not.
The issue was with the call to devicedetect in the vcl_recv. I created a new vcl_recv after the first to handle the devicedetect routine. This somehow fixed the problem.
Thanks
I have a website in ASP.NET.
After page load, I am getting below error.
Error:
Load denied by X-Frame-Options: http://www.youtube.com/v/lgZBsWGaQY0&feature does not permit cross-origin framing.
Due to this error, youtube video is not able to open in iframe.
<div style="display: none; position: relative;">
<div id="divYouTubeClasses">
<iframe id="Iframe1" style="background-color: White !important; border: 0;" width="835"
height="430" src="http://www.youtube.com/v/g5RM5StrMXY" scrolling="no"></iframe>
</div>
</div>
Please provide some solution for this error.
Original URL in Query
http://www.youtube.com/v/lgZBsWGaQY0&feature
Expected URL
http://www.youtube.com/embed/lgZBsWGaQY0?autoplay=1
YouTube Urls must be cleaned and normalized before inserting them into an iframe. Here is my Common js compliant library I created to clean and normalize YouTube urls.
var getVidId = function(url)
{
var vidId;
if(url.indexOf("youtube.com/watch?v=") !== -1)//https://m.youtube.com/watch?v=e3S9KINoH2M
{
vidId = url.substr(url.indexOf("youtube.com/watch?v=") + 20);
}
else if(url.indexOf("youtube.com/watch/?v=") !== -1)//https://m.youtube.com/watch/?v=e3S9KINoH2M
{
vidId = url.substr(url.indexOf("youtube.com/watch/?v=") + 21);
}
else if(url.indexOf("youtu.be") !== -1)
{
vidId = url.substr(url.indexOf("youtu.be") + 9);
}
else if(url.indexOf("www.youtube.com/embed/") !== -1)
{
vidId = url.substr(url.indexOf("www.youtube.com/embed/") + 22);
}
else if(url.indexOf("?v=") !== -1)// http://m.youtube.com/?v=tbBTNCfe1Bc
{
vidId = url.substr(url.indexOf("?v=")+3, 11);
}
else
{
console.warn("YouTubeUrlNormalize getVidId not a youTube Video: "+url);
vidId = null;
}
if(vidId.indexOf("&") !== -1)
{
vidId = vidId.substr(0, vidId.indexOf("&") );
}
return vidId;
};
var YouTubeUrlNormalize = function(url)
{
var rtn = url;
if(url)
{
var vidId = getVidId(url);
if(vidId)
{
rtn = "https://www.youtube.com/embed/"+vidId;
}
else
{
rtn = url;
}
}
return rtn;
};
YouTubeUrlNormalize.getThumbnail = function(url, num)
{
var rtn, vidId = getVidId(url);
if(vidId)
{
if(!isNaN(num) && num <= 4 && num >= 0)
{
rtn = "http://img.youtube.com/vi/"+vidId+"/"+num+".jpg";
}
else
{
rtn = "http://img.youtube.com/vi/"+getVidId(url)+"/default.jpg";
}
}
else
{
return null;
}
return rtn;
};
YouTubeUrlNormalize.getFullImage = function(url)
{
var vidId = getVidId(url);
if(vidId)
{
return "http://img.youtube.com/vi/"+vidId+"/0.jpg";
}
else
{
return null;
}
};
if ( typeof exports !== "undefined" ) {
module.exports = YouTubeUrlNormalize;
}
else if ( typeof define === "function" ) {
define( function () {
return YouTubeUrlNormalize;
} );
}
else {
window.YouTubeUrlNormalize = YouTubeUrlNormalize;
}
Updated to accommodate YouTube Mobile urls. ie: m.youtube.com
Updated to get images as well, and protect against GET vars in the url
These steps will make you understand how it is done :
Use the youtube site to find the video you want
Click the 'Share' button below the video
Click the 'Embed' button next to the link they show you
Copy the iframe code given and paste it into the html of your web
page.
You can see well here that the url is generated by /embed which goes with the first ansewer.
Is it possible to set a content-type dependent expires header in nginx? I'm quite new to nginx and tried the following:
location ~ /files\.php$ {
...
if ($content_type = "text/css") {
add_header X-TEST1 123;
expires 7d;
}
if ($content_type = "image/png") {
add_header X-TEST2 123;
expires 30d;
}
if ($content_type = "application/javascript") {
add_header X-TEST3 123;
expires 1d;
}
#testing
if ($content_type != "text/css") {
add_header X-TEST4 abc;
}
#testing
if ($content_type = text/css) {
add_header X-TEST5 123;
}
}
But the only header added is "X-TEST4" on all requests.
I know about the other solution using file extension:
location ~* \.(ico|css|js|gif|jp?g|png)\?[0-9]+$
But it's not applicable for my application.
I think the code should be in location / { } instead of location ~ /files\.php$ { }...
Have you tried
$content_type ~= application/javascript
Also, make sure to read this:
http://wiki.nginx.org/IfIsEvil
If you have the lua module installed you could do something similar like this:
server {
location / {...}
header_filter_by_lua_block {
local cct = {} -- # cached content types
cct["text/css"] = true
cct["application/javascript"] = true
cct["application/x-javascript"] = true
cct["text/javascript"] = true
cct["image/jpeg"] = true
cct["image/png"] = true
cct["application/vnd.ms-fontobject"] = true
cct["application/font-woff"] = true
cct["application/x-font-truetype"] = true
cct["image/svg+xml"] = true
cct["application/x-font-opentype"] = true
if cct[ngx.header.content_type] ~= nil and ngx.header["expires"] == nil then
local now = os.time()
local expires = os.date("%a, %d-%b-%Y %H:%I:%S GMT", now+604800) -- # one week in seconds
ngx.header["expires"] = expires
end
}
}
Responses with the specified content-type will now get an expires-header.
When the response already has an expires-header the lua block will not touch the header.