NGINX: How to return inline html? - nginx

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>';
}
}

Related

root context with preference over a regular expression

I have read the documentation and seems it is the same as explained here enter link description here, but during my tests the root context is having precedence over the regular expression one.
Does anyone know the reason?
See my nginx.conf file and a test curl I did to validate the configuration:
http {
server {
listen 80;
root /usr/share/nginx/html;
include /etc/nginx/mime.types;
location ~ /ui(/.*) {
try_files $1 $1/ #htmlext;
}
location #htmlext {
rewrite ^/ui(/\w*)(/.*)*$ $1.html last;
}
location / {
return 301 /ui$request_uri;
}
}
}
/ # curl -v http://localhost/ui/message?msg=error.forbidden
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /ui/message?msg=error.forbidden HTTP/1.1
> Host: localhost
> User-Agent: curl/7.67.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.19.0
< Date: Thu, 09 Jul 2020 22:34:49 GMT
< Content-Type: text/html
< Content-Length: 169
< Location: http://localhost/ui/ui/message?msg=error.forbidden
< Connection: keep-alive
<
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.19.0</center>
</body>
</html>
* Connection #0 to host localhost left intact
As you can see in the curl it is redirecting my /ui/message page instead of rendering it. If I remove the location / from the configuration it seems working, if I remove the #htmlext location and add that logic in the location ~ /ui(/.*) it seems working too. Then I think the reason of my error is the #htmlext redirect.
Does anyone know why?
Thanks

Hot change "Location" in the reply header 302 code from proxy-host.

I have the kubernetes-cluster and a few pods/containers with web-app. Pods connecting to each other by pod's name with listen port 9999 (like security-rest-api:9999, common-rest-api:9999, etc).
To outside listen nginx-pod with outside address http://e.net:30200/.
((app-pods:9999)-(nginx-pod:80)-(nginx-service:30200))-Network
Nginx use follow configuration for interactive with app-pods.
server {
listen 80;
server_name e.net;
location / {
proxy_pass http://web-console:9999/;
proxy_redirect http://web-console:9999/ http://e.net:30200/;
}
location /common {
proxy_pass http://common-rest-api:9999/common;
proxy_redirect http://common-rest-api:9999/ http://e.net:30200/;
}
location /security {
proxy_pass http://security-rest-api:9999/security;
proxy_redirect http://security-rest-api:9999/ http://e.net:30200/;
} }
It's working very well, but I have the one problem with 302-reply from app-pods:
If I try to login in my app, I get follow the 302 reply header:
HTTP/1.1 302 Found
Connection: keep-alive
Content-Length: 0
Date: Wed, 25 Apr 2018 10:37:50 GMT
Location: http://e.net:30200/security/rest/auth/login.html?callbackUrl=http://security-rest-api:9999/security/rest/namespace
Server: nginx/1.13.9
App-pods generated URL parameter "callbackUrl" from the Host request header Inside containers network and this URL parameter to get to the endpoint browser. Of course, next request get 404 code.
I can't to edit app-code (in app-pods don't use nginx), but I want to change 'security-rest-api:9999' to 'e.net:30200' parameter in the Location 302 reply header. How I can do it?
redirect isn't suitable since this generate new 302-reply and not solve my problem.
sub_filter change only reply body, but not reply head (where is Location parameter).
request_uri not working too, since this parameter work with request header only.
No, It's not working.
I tested this situation and finded work's config:
if ($args ~* (.*)(callbackUrl=http://security-rest-api:9999/)(.*)) {
set $args $1callbackUrl=http://e.net:30200/$3;
rewrite ^(.*)$ $1;
}
if ($args ~* (.*)(callbackURL=http%3A%2F%2Fsecurity-rest-api%3A9999%2F)(.*)) {
set $args $1callbackURL=http%3A%2F%2Fe.net%3A30200%2F$3;
rewrite ^(.*)$ $1;
}
location /security {
proxy_pass http://security-rest-api:9999/security;
proxy_set_header Host $http_host;
proxy_redirect http://security-rest-api:9999/ http://e.net:30200/;
}
Later, I will try to use this config on the pre-production stand and if this work (or work after corrects) - I will write it here.
Thanks for help information:
https://blog.imaginea.com/modifying-query-parameters-nginx-in-reverse-proxy-mode/
And thanks for you all, too!
Edit
I tested this config and have 2 edits:
If you to use un-standart port - you need write "proxy_set_header Host $http_host;" in location section;
URL in attributes can be like "http://security-rest-api:9999/" and like "http%3A%2F%2Fsecurity-rest-api%3A9999%2F". You need to use both conditions for each type of attribute.
I corrected code with this edits

nginx - valid_referes dont work

I have the local server running on 3000 port and it sends some POST request to nginx server. Nginx should check referer, if it is not coming from 127.0.0.1:3000 (with all subdomains) then return 403 Restricted,otherwise if it is valid redirect to 9200/errors/browser endpoint.
Currently, it is always redirecting regardless if the referer is valid or not. I know that in nginx if is evil , so if-else approach doesnt work here.
server {
listen 127.0.0.1:9999;
server_name localhost;
location / {
valid_referers none blocked server_names ~someaddress;
if ($invalid_referer) {
return 403;
}
# redirect to this endpoint if referer is valid
return 307 http://localhost:9200/errors/browser;
}
}
I should add
if ($invalid_referer != "1") {
return 403;
}
as it is the empty string according to the documentation
$invalid_referer
Empty string, if the “Referer” request header field value is considered valid, otherwise “1”.

How to disable nginx access log by response header

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;
}

nginx: variable expansion inside split_clients not working?

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

Resources