Request headers are not converted to lowercase while proxy pass to Tomcat from Nginx - nginx

Seems, by default Tomcat request headers are always in lowercase. But when we redirect the request to Tomcat from Nginx using proxy_pass/AJP, the request headers contain upper-case too.
For example, In
Tomcat: user-agent = xxx
Nginx to Tomcat: User-Agent = xxx
please help me to understand, why it wasn't converted to lowercase even though we were redirecting those to tomcat?
I'm passing the request to tomcat from Nginx like below,
ajp_pass tomcat;
or
proxy_pass tomcat;
I'm expecting to get all request headers in lowercase only.

Related

Rewrite the referer header when using ngrok

I want to create an ngrok tunnel to a router admin web interface that requires the Referer header to be set to the router's base URL, any request without the Referer set to (in my case) http://192.168.1.1/ will fail with a HTTP 403.
I've been trying to use the --request-header-add option:
ngrok http --request-header-add 'referer: http://192.168.1.1/' 192.168.1.1:80
but it complains about wrong format, since the value contains a colon in the http:// part:
ERROR: Added request header should be in key:value format, got referer: http://192.168.1.1/
ERROR:
ERROR: ERR_NGROK_370
Is there really no way to rewrite / add a referer header?
I had same issue with router (opnsense) and I fixed it be removing the referer header all together (as I did not find a way to set it using ngrok)
e.g.:
ngrok http --host-header=rewrite --request-header-remove 'referer' 192.168.1.1:80
One way I have made it work was passing a value as a string.
ngrok http --request-header-add "referer: ${URL}" 192.168.1.1:80
By making it double quotes instead of single ones and making the URL a variable.
Hope that helps you.

Change proxy's response header through Nginx

I have an instance of Nginx Plus deployed as a reverse proxy. The proxy app returns a "set-cookie" header in the response which I'd like to modify (the domain associated with the to-be cookie):
Change
set-cookie:key=value;Path=/;HttpOnly;Domain=my.domain.net
to
set-cookie:key=value;Path=/;HttpOnly;Domain=new.domain.com
Needless to say I can't modify the application to use something like an outbound rewrite rule.
The Nginx http proxy module has two directives which manipulate the “Set-Cookie” header in the response from the upstream server.
proxy_cookie_path can change the path attribute of the “Set-Cookie” header.
proxy_cookie_domain can change the domain attribute of the “Set-Cookie” header.

Can I redirect a request with code 302 to another port without using the HOST variable?

In the HTTP protocol, there are multiple status codes that can be used to redirect a request to another URL, such as 301 Moved Permanently or 302 Found. To my knowledge, the target URL can either contain a host (http://example.com/example.html) or let the host implicitly be the current host (/example.html).
When using the first form, one can redirect to a non-standard port (http://example.com:8080/example.html). How can this be done when not specifying the host?
Currently, I parse the HOST request header and build the new URL. But AFAIK, that header is not strictly required to be sent, so I want to avoid it.
You can't specify just the port in a redirect. And yes, the "Host" header field is strictly required in HTTP/1.1.

How does a webserver know what website you want to access?

Apache has something called VirtualHosts.
You can configure it in that way that when you go to example.com get a different site than example2.com even if you use the same IP's.
A HTTP Request looks something like this:
GET /index.html HTTP/1.0
[some more]
How does the server know you are trying to access www.example.com or www.example2.com?
In addition to the GET line, the browser sends a number of headers. One of these headers is the Host header, which specifies which host the request is targeted at.
A simple example request could be:
GET /index.html HTTP/1.0
Host: example.com
This indicates that the browser wants whatever is at http://example.com/index.html, and not what is at http://example2.com/index.html.
Further information:
The Host header in the HTTP specification
IIS also has this and I believe refers to it as host header redirection.
The http packet header contains the destination hostname which the server uses to determine which website to serve up. Some more reading: http://www.it-notebook.org/iis/article/understanding_host_headers.htm

Do web browsers always send a trailing slash after a domain name?

Is there consistency and/or a standard on how browsers send a url to a host related to trailing slashes?
Meaning, if I type in http://example.com in the address bar of a web browser, is the browser suppose to add a trailing slash (http://example.com/) or not?
The HTTP request sent from the browser to the server does not include the domain name, only the "path" portion (starting from the first slash after the domain name). Since the path cannot be empty, a / is sent in that case.
A sample GET request for the root of a web site might be:
GET / HTTP/1.0
The / above cannot be omitted.
As RFC 2616 tells:
3.2.2 http URL
The "http" scheme is used to locate
network resources via the HTTP
protocol. This section defines the
scheme-specific syntax and
semantics for http URLs.
http_URL = "http:" "//" host [ ":"
port ] [ abs_path [ "?" query ]]
If the port is empty or not given,
port 80 is assumed. The semantics
are that the identified resource is
located at the server listening for
TCP connections on that port of that
host, and the Request-URI for the
resource is abs_path (section 5.1.2).
The use of IP addresses in URLs
SHOULD be avoided whenever possible
(see RFC 1900 [24]). If the
abs_path is not present in the URL, it
MUST be given as "/" when used as a
Request-URI for a resource (section
5.1.2). If a proxy receives a host name which is not a fully qualified
domain name, it MAY add its domain
to the host name it received. If a
proxy receives a fully qualified
domain name, the proxy MUST NOT change
the host name.
Read more: http://www.faqs.org/rfcs/rfc2616.html#ixzz0kGbpjYWa
5.1.2 Request-URI
...
For example, a client wishing to retrieve the
resource above directly from the
origin server would create a TCP
connection to port 80 of the host
"www.w3.org" and send the lines:
GET /pub/WWW/TheProject.html HTTP/1.1
Host: www.w3.org
followed by the remainder of the
Request. Note that the absolute path
cannot be empty; if none is present in
the original URI, it MUST be given
as "/" (the server root).
Read more: http://www.faqs.org/rfcs/rfc2616.html#ixzz0kGcaRbqU
Note that it's a very different matter when the URL has a path element:
http://example.com/dir
is a different URL than
http://example.com/dir/
and could in fact contain different content, and have a different search engine ranking.
As far as the protocol is concerned, http://example.com/something and http://example.com/something/ are quite different. Some servers might redirect you from one to the other if it is implemented in such a way.
As for the pure domain names, it always sends a request ending with a slash.
(The domain name itself is not included in the path section of an HTTP request, just as Greg Hewgill and the others wrote. It is, however, included in the headers.)
You can check it with a tool like Fiddler or WireShark.

Resources