In Nginx, what's the difference between variables $host and $http_host.
$host is a variable of the Core module.
$host
This variable is equal to line Host in the header of request or
name of the server processing the request if the Host header is not
available.
This variable may have a different value from $http_host in such
cases: 1) when the Host input header is absent or has an empty value,
$host equals to the value of server_name directive; 2)when the value
of Host contains port number, $host doesn't include that port number.
$host's value is always lowercase since 0.8.17.
$http_host is also a variable of the same module but you won't find it with that name because it is defined generically as $http_HEADER (ref).
$http_HEADER
The value of the HTTP request header HEADER when converted to lowercase and with 'dashes' converted to 'underscores', e.g. $http_user_agent, $http_referer...;
Summarizing:
$http_host equals always the HTTP_HOST request header.
$host equals $http_host, lowercase and without the port number (if present), except when HTTP_HOST is absent or is an empty value. In that case, $host equals the value of the server_name directive of the server which processed the request.
The accepted answer and its comments don't seem to be correct (anymore). The docs (http://nginx.org/en/docs/http/ngx_http_core_module.html#var_host) say that $host is
in this order of precedence: host name from the request line, or host name from the “Host” request header field, or the server name matching a request
So $http_host is always the value of the Host header field. They might differ if the host in the request line (if specified) differs from the Host header field. Or if the Host header is not set.
server_name matches only the Host header field (http://nginx.org/en/docs/http/request_processing.html), so that $host may differ from the matched server_name.
$http_host
$http_host always equals Host request header field
Host: example.org
$host
$host is in this order of precedence (from high to low):
Host name from the request line
GET http://example.org/test/ HTTP/1.1
Host request header field
The server_name (in Nginx config) matching a request, even if server_name is wildcard (Ex: server_name *.example.org;)
Host name from the request line
When open URL http://example.org/test/ ...
Most browser send the request like this
GET /test/ HTTP/1.1
Host: example.org
Most browser doesn't send the request like this (but this is valid request)
GET http://example.org/test/ HTTP/1.1
Validation
Nginx testing config
server {
listen 80;
server_name *.example.org;
location / {
default_type "text/plain";
return 200 "[host] = $host";
}
}
When all exist ...
$host = host name from the request line
curl http://127.0.0.1 -v \
--request-target http://request.example.org/test/ \
--path-as-is \
-H "Host: host.example.org"
This command will
Connect to 127.0.0.1
Send request path as GET http://request.example.org/test/ HTTP/1.1
Set Host header to Host: host.example.org
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET http://request.example.org/test/ HTTP/1.1
> Host: host.example.org
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.23.1
< Date: Fri, 21 Oct 2022 02:00:56 GMT
< Content-Type: text/plain
< Content-Length: 28
< Connection: keep-alive
<
* Connection #0 to host 127.0.0.1 left intact
[host] = request.example.org
When only Host header exist ...
$host = Host header
curl http://127.0.0.1/test/ -v \
-H "Host: host.example.org"
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET /test/ HTTP/1.1
> Host: host.example.org
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.23.1
< Date: Fri, 21 Oct 2022 02:01:37 GMT
< Content-Type: text/plain
< Content-Length: 25
< Connection: keep-alive
<
* Connection #0 to host 127.0.0.1 left intact
[host] = host.example.org
When none exist ...
$host = server_name (in Nginx config)
# HTTP 1.1 must have Host header, so use HTTP 1.0
curl http://127.0.0.1/test/ -v -H "Host:" -0
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET /test/ HTTP/1.0
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.23.1
< Date: Fri, 21 Oct 2022 02:02:20 GMT
< Content-Type: text/plain
< Content-Length: 22
< Connection: close
<
* Closing connection 0
[host] = *.example.org
Ref: ngx_http_core_module, Nginx $host validation
Related
I have a JSON file called people.json:
[
{
"name": "Adam"
},
{
"name": "Eve"
}
]
I'm trying to send this data using a POST request with curl, from the project's root directory:
curl --request POST \
--header 'Content-Type: application/json' 'Accept: application/json' \
--data-binary #src/test/java/com/spring/app/people.json \
http://127.0.0.1:8080/api/v1/person -v -s
I keep getting the "Bad Request" error:
* Closing connection -1
* Trying 127.0.0.1:8080...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> POST /api/v1/person HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.74.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 80
>
* upload completely sent off: 80 out of 80 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 400
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Sat, 12 Dec 2020 03:56:38 GMT
< Connection: close
<
* Closing connection 0
{"timestamp":"2020-12-12T03:56:38.822+00:00","status":400,"error":"Bad Request","message":"","path":"/api/v1/person"}%
I've already had a look at this post, but still get the same error.
I've also installed homebrew curl, but even using that doesn't resolve the error.
I would appreciate any help.
Environment:
CouchDB 2.2.0 running on VirtualBox, running up-to-date Debian image. Network type is bridged, all ports are open, no https.
Vue3.js app (not using any Vue functionality to access the DB)
Remote access JS package:
axios
fetch
Browser: Chrome latest
Relevant CouchDB local.ini settings
[couch_peruser]
enable = false
delete_dbs = false
[chttpd]
port = 5984
require_valid_user = false
proxy_use_secret = false
bind_address = 0.0.0.0
authentication_handlers = {chttpd_auth, cookie_authentication_handler}, {chttpd_auth, default_authentication_handler}
[httpd]
bind_address = 127.0.0.1
enable_cors = true
(default authentication handlers set in default.ini)
authentication_handlers = {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}
[couch_httpd_auth]
secret = (hash num)
require_valid_user = false
allow_persistent_cookies = true
[cors]
origins = *
headers = accept, authorization, content-type, X-Auth-CouchDB-UserName, origin, referer
credentials = true
methods = GET, PUT, POST, HEAD, DELETE
What Happens
If I do the query via curl, I get a cookie in the response.
Here's the curl call:
curl -v http://couchman.lcldev:5984/_session \
-H "Content-Type:application/json" \
-H "X-Auth-CouchDB-UserName:<uname>" \
-d '{"name":"<uname>","password":"<passwd>"}'
And here's the response:
< HTTP/1.1 200 OK
< Cache-Control: must-revalidate
< Content-Length: 47
< Content-Type: application/json
< Date: Wed, 10 Oct 2018 21:16:10 GMT
< Server: CouchDB/2.2.0 (Erlang OTP/19)
< Set-Cookie: (cookie info)
<
{"ok":true,"name":"<name>","roles":["<roles>"]}
Yay. I get a cookie.
But if I call it from within my app (with either fetch or axios), I only get these headers:
Response headers:
cache-control,must-revalidate
content-type,application/json
server,CouchDB/2.2.0 (Erlang OTP/19)
No Set-Cookie header.
So, what's up? What am I missing?
Answered in first comment - see thread for more info.
I created a small stack using with orion and the populated mongodb from the tour guide app.
I don't understand why the updates queries are not working :(
if I query the context:
curl -s -X GET -H "Accept: text/plain" -H "fiware-service: tourguide" 'http://localhost:1026/v2/entities/0115206c51f60b48b77e4c937835795c33bb953f/attrs/capacity/value'
I get correctly the value "50"
if I update the value, following the query examples:
curl -s -v -X PUT -H "Accept: text/plain" -H "fiware-service: tourguide" -H "Content-Type: text/plain" 'http://160.85.2.22:1026/v2/entities/0115206c51f60b48b77e4c937835795c33bb953f/attrs/capacity/value' -d 52
i get error "The requested entity has not been found. Check type and id"
* Trying 160.85.2.22...
* Connected to 160.85.2.22 (160.85.2.22) port 1026 (#0)
> PUT /v2/entities/0115206c51f60b48b77e4c937835795c33bb953f/attrs/capacity/value?type=Restaurant HTTP/1.1
> Host: 160.85.2.22:1026
> User-Agent: curl/7.47.0
> Accept: application/json
> fiware-service: tourguide
> Content-Type: text/plain
> Content-Length: 2
>
} [2 bytes data]
* upload completely sent off: 2 out of 2 bytes
< HTTP/1.1 404 Not Found
< Connection: Keep-Alive
< Content-Length: 95
< Content-Type: application/json
< Fiware-Correlator: 9d2f4164-48f3-11e6-af87-0242ac110004
< Date: Wed, 13 Jul 2016 12:16:23 GMT
<
{ [95 bytes data]
* Connection #0 to host 160.85.2.22 left intact
{
"description": "The requested entity has not been found. Check type and id",
"error": "NotFound"
}
As far as I understand, you are using the context data of the FIWARE Tour Guide Application. In that context data, Restaurant entities belong to different service paths. In particular, each Resturant belong to a service path corresponding to the value of its department attribute.
Thus, have a look to the department attribute of the 0115206c51f60b48b77e4c937835795c33bb953f entity (using the Fiware-Service header: "tourguide"). If the value of the attribute is for example "Franchise4" then you have to use the following service path header in your PUT request (pay attention to the initial /):
-H "fiware-servicepath: /Franchise4"
Why GET request on attribute value is working without service path header while PUT request on attribute value isn't? When the header is omitted, query requests default to /# (which means "any service path") while create/udpate requests default to / (which is the root service path, which doesn't match with /Franchise4).
I am trying to send an email via the Mandrill API, but it is throwing an error with the key(s) I provide. Below is the text.json file I am including in my curl request.
{
'key' : 'MyActualKey',
'message': {
'html': '<p>Example HTML content</p>',
'text': 'Example text content',
'subject': 'example subject',
'from_email': 'from#example.com',
'from_name': 'Test',
'to': [
{
'email': 'to#example.com',
'name': 'Eric Clapton',
'type': 'to'
}
],
'headers': {
'Reply-To': 'reply#example.com'
},
'merge': True,
'tags': [
'Mandrill Test'
]
},
'ip_pool': 'Main Pool'
}
Then I execute this curl command:
curl -X POST -H "Content-Type: application/json" --data #test.json https://mandrillapp.com/api/1.0/messages/send.json -v
Resulting in this output with the error shown on the last line:
* Adding handle: conn: 0x7fd922803a00
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7fd922803a00) send_pipe: 1, recv_pipe: 0
* About to connect() to mandrillapp.com port 443 (#0)
* Trying 54.221.22.61...
* Connected to mandrillapp.com (54.221.22.61) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
* Server certificate: mandrillapp.com
* Server certificate: Thawte SSL CA
* Server certificate: thawte Primary Root CA
* Server certificate: Thawte Premium Server CA
> POST /api/1.0/messages/send.json HTTP/1.1
> User-Agent: curl/7.30.0
> Host: mandrillapp.com
> Accept: */*
> Content-Type: application/json
> Content-Length: 501
>
* upload completely sent off: 501 out of 501 bytes
< HTTP/1.1 500 Internal Server Error
* Server nginx/1.6.0 is not blacklisted
< Server: nginx/1.6.0
< Date: Sat, 14 Jun 2014 23:46:44 GMT
< Content-Type: application/json; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Powered-By: PHP/5.3.10-1ubuntu3.11
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: POST, GET, OPTIONS
< Access-Control-Allow-Headers: Content-Type
< Access-Control-Allow-Credentials: false
<
* Connection #0 to host mandrillapp.com left intact
{"status":"error","code":-1,"name":"ValidationError","message":"You must specify a key value"}
Notice how the last line says 'specify a key value' - again, this is the exact key from the Mandrill control panel. I even generated a couple more and they all failed.
Try to change it into a valid json and see if that helps:
Change all single quotes into double quotes
Change the value of "merge" from "True" to lower case "true".
Have a situation where an outside user collaborates or shares a folder with a enterprise user. API call impersonating the enterprise user returns a 404 error. Please see the http exchange below using curl. Some sensitive information is masked. Appreciate any help.
curl -k -v -H "Authorization: Bearer XXXXXXXXXXXXXXXXXXXX" -H "As-User: 2146XXXXX" https://api.box.com/2.0/folders/1834XXXXXX
* About to connect() to api.box.com port 443 (#0)
* Trying 74.112.185.97... connected
> GET /2.0/folders/1834XXXXXX HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: api.box.com
> Accept: */*
> Authorization: Bearer XXXXXXXXXXXXXXXXXXXX
> As-User: 2146XXXXX
>
< HTTP/1.1 404 Not Found
< Server: nginx
< Date: Wed, 16 Apr 2014 00:34:58 GMT
< Content-Type: application/json
< Content-Length: 323
< Connection: keep-alive
< Cache-Control: no-cache, no-store
<
* Connection #0 to host api.box.com left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
{"type":"error","status":404,"code":"not_found","context_info":{"errors": [{"reason":"invalid_parameter","name":"item","message":"Invalid value 'd_1834XXXXXX'. 'item' with value 'd_1834XXXXXX' not found"}]},"help_url":"http:\/\/developers.box.com\/docs\/#errors","message":"Not Found","request_id":"1378003773534dd03193806"}