I want to turn off the access log using the response header .
As in the following set .
You do not want to output a log when there is a header .
It does not work .
server {
listen 80;
server_name localhost;
access_log logs/access_debug.log debug_val_format if=$logging;
set $logging 1;
if ( $upstream_http_logoff ){
set $logging 0;
}
Response headers are sent .
Connection:keep-alive
Content-Length:5
Content-Type:text/html; charset=UTF-8
Date:Wed, 11 May 2016 12:04:57 GMT
logoff:1
Server:nginx/1.7.11
X-Powered-By:PHP/5.3.3
You should use map:
map $upstream_http_logoff $logging {
default 1;
1 0;
}
Maybe you should consider to inverse upstream logic, so it would be easier to understand:
Upstream header logging:0
map $upstream_http_logging $logging {
default 1;
0 0;
1 1;
}
Related
I am trying to setup prerender.io for my react platform on AWS ECS along with load balancer, but I keep getting 301 redirect loops, when I visit primary domain.
According to official documentation and github source code, I configured AWS Load balancer accordingly in Load balancer listener rules:
For HTTPS:443, if Host is www2.example.com Forward to ecs_website_container
For HTTPS:443, if Host is example.com OR www.example.com Forward to ecs_prerender_io_container
For HTTP:80, redirect all traffic to https://#{host}:443/#{path}?#{query}
When I check prerender docker logs, every time I visit primary domain example.com I do see some activity in logs, for example:
[13/Aug/2022:18:32:57 +0000] "GET / HTTP/1.1" 301 134 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "12.34.56.789"
So thats the 301 redirect error. It doesnt get to the point of forwarding to www2.example.com.
The source code is exactly same as in official github repository, just the variables are changed obviously. If I go to www2.example.com directly, website works normally, so the problem must be somewhere in the middleware configuration.
I tracked down the redirects and it is as follows (from 1 to 2, from 2 to 3, etc):
1. http://example.com
2. https://example.com:443/
3. https://www.example.com:443/
4. https://www.example.com:443/
5. https://www.example.com:443/
... infinite loop ...
For the sake of clarity, here is default.conf.template nginx configuration which is used:
map $http_user_agent $prerender_ua {
default 0;
"~*Prerender" 0;
"~*googlebot" 1;
"~*yahoo!\ slurp" 1;
"~*bingbot" 1;
"~*yandex" 1;
"~*baiduspider" 1;
"~*facebookexternalhit" 1;
"~*twitterbot" 1;
"~*rogerbot" 1;
"~*linkedinbot" 1;
"~*embedly" 1;
"~*quora\ link\ preview" 1;
"~*showyoubot" 1;
"~*outbrain" 1;
"~*pinterest\/0\." 1;
"~*developers.google.com\/\+\/web\/snippet" 1;
"~*slackbot" 1;
"~*vkshare" 1;
"~*w3c_validator" 1;
"~*redditbot" 1;
"~*applebot" 1;
"~*whatsapp" 1;
"~*flipboard" 1;
"~*tumblr" 1;
"~*bitlybot" 1;
"~*skypeuripreview" 1;
"~*nuzzel" 1;
"~*discordbot" 1;
"~*google\ page\ speed" 1;
"~*qwantify" 1;
"~*pinterestbot" 1;
"~*bitrix\ link\ preview" 1;
"~*xing-contenttabreceiver" 1;
"~*chrome-lighthouse" 1;
"~*telegrambot" 1;
}
map $args $prerender_args {
default $prerender_ua;
"~(^|&)_escaped_fragment_=" 1;
}
map $http_x_prerender $x_prerender {
default $prerender_args;
"1" 0;
}
map $uri $prerender {
default $x_prerender;
"~*\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)" 0;
}
server {
listen 80;
listen [::]:80;
server_name ${PRIMARY_DOMAIN};
location / {
if ($prerender = 1) {
rewrite (.*) /prerenderio last;
}
proxy_set_header Host $SERVER_NAME;
proxy_set_header Connection "";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_hide_header Cache-Control;
add_header Cache-Control "public,max-age=31536000";
#resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
resolver 8.8.8.8 8.8.4.4;
#setting backend as a variable forces DNS resolution since nginx caches IPs and doesnt play well with load balancing
set $backend "${SECONDARY_DOMAIN}";
rewrite .* $uri break;
proxy_pass http://$backend;
}
location /prerenderio {
if ($prerender = 0) {
return 404;
}
proxy_set_header X-Prerender-Token ${PRERENDER_API_KEY};
proxy_hide_header Cache-Control;
add_header Cache-Control "private,max-age=600,must-revalidate";
#resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
resolver 8.8.8.8 8.8.4.4;
set $prerenderio_host "${PRERENDER_HOST}";
proxy_pass http://$prerenderio_host;
rewrite .* /https://${PRIMARY_DOMAIN}$request_uri break;
}
}
Tried to contact support but no response.
I want to achieve something like this:
server {
listen 80;
location / {
return 200 <html><body>Hello World</body></html>
}
}
i.e., any request should return the inline html. Is this possible with NGINX?
EDIT:
I tried this:
server {
listen 80;
location / {
return 200 '<html><body>Hello World</body></html>'
}
}
But testing in browser did not render the html, instead the browser tried to download a file containing the html which is not the behavior I wanted.
Use the return directive to return HTML code. Remember to set proper content type, otherwise the browser will asume raw text and won’t render the code:
server {
listen 80;
location / {
add_header Content-Type text/html;
return 200 '<html><body>Hello World</body></html>';
}
}
just setting the content type header seems to work on some browsers, however safari on ios stil tries to download the file.
You might have set the content type somwhere else, resulting in 2 content type headers this way.
e.g. in my case curl showed me:
< date: Thu, 11 Nov 2021 01:00:06 GMT
< content-type: application/octet-stream
< content-length: 49
< content-type: text/html
The fix is to clear the global type and set one for a given url
server {
server_name example.com;
listen 80;
location / {
types {}
default_type text/html;
return 200 '<html><body>Hello World</body></html>';
}
}
In the following example:
http {
server { # simple reverse-proxy
listen 8080;
location / {
set $token $arg_token;
#return 200 $token;
add_header test "test $token";
proxy_pass http://localhost:5601;
}
} ...
}
if I leave return 200 $token I obtain the token as response + in header (which is a normal behavior) but when I delete return I obtain only "test" as test header value, what am I missing please ?
The proxy_set_header sets header that NGINX will use while communicating to the upstream/backend.
You won't see that added header in the response of NGINX back to the client.
If you want to see it, use add_header as well.
It may sound like a code golf question, but what is the simplest / lightest way to return $remote_addr in text/plain?
So, it should return several bytes of the IP address in a plain text.
216.58.221.164
Use case: An API to learn the client's own external (NAT), global IP address.
Is it possible to do it with Nginx alone and without any backends? If so, how?
The simplest way is:
location /remote_addr {
default_type text/plain;
return 200 "$remote_addr\n";
}
The above should be added to the server block of your nginx.conf.
No need to use any 3rd party module (echo, lua etc.)
Here's an approach you can use to consider proxied connections:
# Map IP address to variable
map ":$http_x_forwarded_for" $IP_ADDR {
":" $remote_addr; # Forwarded for not set
default $http_x_forwarded_for; # Forwarded for is set
}
server {
...
location / {
default_type text/plain;
return 200 "$IP_ADDR";
}
}
Use ngx_echo:
location /ip {
default_type text/plain;
echo $remote_addr;
}
Use ngx_lua:
location /b {
default_type text/plain;
content_by_lua '
ngx.say(ngx.var.remote_addr)
';
}
i have the following config:
map $host $variant_a {
default 'a';
}
map $host $variant_b {
default 'b';
}
map $host $variant_c {
default 'c';
}
map $host $variant_d {
default 'd';
}
map $host $variant_default {
default 'default';
}
# a/b testing
split_clients "abtest${remote_addr}${http_user_agent}${date_gmt}" $variant_chosen {
20% $variant_a;
20% $variant_b;
20% $variant_c;
20% $variant_d;
20% $variant_default;
}
server {
# defaults test independent
listen 80;
server_name _;
root /home/vagrant/www;
index index.html;
error_page 404 = 404.html;
error_page 403 = 404.html;
location / {
echo a=$variant_a,variant_chosen=$variant_chosen
}
}
when i execute a query against the server:
curl -i http://192.168.33.10/
i can see that the variables inside the 'split_clients' get never expanded.
sample output:
vagrant#precise32:~/www$ curl -i http://192.168.33.10/
HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Mon, 04 May 2015 15:46:17 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive
a=a,variant_chosen=$variant_default
anybody any idea why the variables are not expanded?
any help highly appreciated
cheers
marcel