Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
nghttp2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
nghttp2
Commits
2fd095d0
Commit
2fd095d0
authored
Jun 03, 2016
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nghttpx: Share the code to configure backends
parent
09150a79
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
201 additions
and
183 deletions
+201
-183
src/shrpx.cc
src/shrpx.cc
+2
-183
src/shrpx_config.cc
src/shrpx_config.cc
+189
-0
src/shrpx_config.h
src/shrpx_config.h
+10
-0
No files found.
src/shrpx.cc
View file @
2fd095d0
...
@@ -146,52 +146,6 @@ struct SignalServer {
...
@@ -146,52 +146,6 @@ struct SignalServer {
pid_t
worker_process_pid
;
pid_t
worker_process_pid
;
};
};
namespace
{
int
resolve_hostname
(
Address
*
addr
,
const
char
*
hostname
,
uint16_t
port
,
int
family
)
{
int
rv
;
auto
service
=
util
::
utos
(
port
);
addrinfo
hints
{};
hints
.
ai_family
=
family
;
hints
.
ai_socktype
=
SOCK_STREAM
;
#ifdef AI_ADDRCONFIG
hints
.
ai_flags
|=
AI_ADDRCONFIG
;
#endif // AI_ADDRCONFIG
addrinfo
*
res
;
rv
=
getaddrinfo
(
hostname
,
service
.
c_str
(),
&
hints
,
&
res
);
if
(
rv
!=
0
)
{
LOG
(
FATAL
)
<<
"Unable to resolve address for "
<<
hostname
<<
": "
<<
gai_strerror
(
rv
);
return
-
1
;
}
auto
res_d
=
defer
(
freeaddrinfo
,
res
);
char
host
[
NI_MAXHOST
];
rv
=
getnameinfo
(
res
->
ai_addr
,
res
->
ai_addrlen
,
host
,
sizeof
(
host
),
nullptr
,
0
,
NI_NUMERICHOST
);
if
(
rv
!=
0
)
{
LOG
(
FATAL
)
<<
"Address resolution for "
<<
hostname
<<
" failed: "
<<
gai_strerror
(
rv
);
return
-
1
;
}
if
(
LOG_ENABLED
(
INFO
))
{
LOG
(
INFO
)
<<
"Address resolution for "
<<
hostname
<<
" succeeded: "
<<
host
;
}
memcpy
(
&
addr
->
su
,
res
->
ai_addr
,
res
->
ai_addrlen
);
addr
->
len
=
res
->
ai_addrlen
;
return
0
;
}
}
// namespace
namespace
{
namespace
{
int
chown_to_running_user
(
const
char
*
path
)
{
int
chown_to_running_user
(
const
char
*
path
)
{
return
chown
(
path
,
get_config
()
->
uid
,
get_config
()
->
gid
);
return
chown
(
path
,
get_config
()
->
uid
,
get_config
()
->
gid
);
...
@@ -1075,11 +1029,6 @@ constexpr auto DEFAULT_ACCESSLOG_FORMAT = StringRef::from_lit(
...
@@ -1075,11 +1029,6 @@ constexpr auto DEFAULT_ACCESSLOG_FORMAT = StringRef::from_lit(
R"("$http_referer" "$http_user_agent")"
);
R"("$http_referer" "$http_user_agent")"
);
}
// namespace
}
// namespace
namespace
{
constexpr
char
DEFAULT_DOWNSTREAM_HOST
[]
=
"127.0.0.1"
;
constexpr
int16_t
DEFAULT_DOWNSTREAM_PORT
=
80
;
}
// namespace;
namespace
{
namespace
{
void
fill_default_config
()
{
void
fill_default_config
()
{
*
mod_config
()
=
{};
*
mod_config
()
=
{};
...
@@ -2151,7 +2100,6 @@ void process_options(int argc, char **argv,
...
@@ -2151,7 +2100,6 @@ void process_options(int argc, char **argv,
auto
&
listenerconf
=
mod_config
()
->
conn
.
listener
;
auto
&
listenerconf
=
mod_config
()
->
conn
.
listener
;
auto
&
upstreamconf
=
mod_config
()
->
conn
.
upstream
;
auto
&
upstreamconf
=
mod_config
()
->
conn
.
upstream
;
auto
&
downstreamconf
=
mod_config
()
->
conn
.
downstream
;
if
(
listenerconf
.
addrs
.
empty
())
{
if
(
listenerconf
.
addrs
.
empty
())
{
UpstreamAddr
addr
{};
UpstreamAddr
addr
{};
...
@@ -2185,140 +2133,11 @@ void process_options(int argc, char **argv,
...
@@ -2185,140 +2133,11 @@ void process_options(int argc, char **argv,
}
}
}
}
auto
&
addr_groups
=
downstreamconf
.
addr_groups
;
if
(
configure_downstream_group
(
mod_config
(),
get_config
()
->
http2_proxy
,
false
,
tlsconf
)
!=
0
)
{
if
(
addr_groups
.
empty
())
{
DownstreamAddrConfig
addr
{};
addr
.
host
=
ImmutableString
::
from_lit
(
DEFAULT_DOWNSTREAM_HOST
);
addr
.
port
=
DEFAULT_DOWNSTREAM_PORT
;
addr
.
proto
=
PROTO_HTTP1
;
DownstreamAddrGroupConfig
g
(
StringRef
::
from_lit
(
"/"
));
g
.
addrs
.
push_back
(
std
::
move
(
addr
));
mod_config
()
->
router
.
add_route
(
StringRef
{
g
.
pattern
},
addr_groups
.
size
());
addr_groups
.
push_back
(
std
::
move
(
g
));
}
else
if
(
get_config
()
->
http2_proxy
)
{
// We don't support host mapping in these cases. Move all
// non-catch-all patterns to catch-all pattern.
DownstreamAddrGroupConfig
catch_all
(
StringRef
::
from_lit
(
"/"
));
for
(
auto
&
g
:
addr_groups
)
{
std
::
move
(
std
::
begin
(
g
.
addrs
),
std
::
end
(
g
.
addrs
),
std
::
back_inserter
(
catch_all
.
addrs
));
}
std
::
vector
<
DownstreamAddrGroupConfig
>
().
swap
(
addr_groups
);
std
::
vector
<
WildcardPattern
>
().
swap
(
mod_config
()
->
wildcard_patterns
);
// maybe not necessary?
mod_config
()
->
router
=
Router
();
mod_config
()
->
router
.
add_route
(
StringRef
{
catch_all
.
pattern
},
addr_groups
.
size
());
addr_groups
.
push_back
(
std
::
move
(
catch_all
));
}
else
{
auto
&
wildcard_patterns
=
mod_config
()
->
wildcard_patterns
;
std
::
sort
(
std
::
begin
(
wildcard_patterns
),
std
::
end
(
wildcard_patterns
),
[](
const
WildcardPattern
&
lhs
,
const
WildcardPattern
&
rhs
)
{
return
std
::
lexicographical_compare
(
rhs
.
host
.
rbegin
(),
rhs
.
host
.
rend
(),
lhs
.
host
.
rbegin
(),
lhs
.
host
.
rend
());
});
if
(
LOG_ENABLED
(
INFO
))
{
LOG
(
INFO
)
<<
"Reverse sorted wildcard hosts (compared from tail to head, "
"and sorted in reverse order):"
;
for
(
auto
&
wp
:
mod_config
()
->
wildcard_patterns
)
{
LOG
(
INFO
)
<<
wp
.
host
;
}
}
}
// backward compatibility: override all SNI fields with the option
// value --backend-tls-sni-field
if
(
!
tlsconf
.
backend_sni_name
.
empty
())
{
auto
&
sni
=
tlsconf
.
backend_sni_name
;
for
(
auto
&
addr_group
:
addr_groups
)
{
for
(
auto
&
addr
:
addr_group
.
addrs
)
{
addr
.
sni
=
sni
;
}
}
}
if
(
LOG_ENABLED
(
INFO
))
{
LOG
(
INFO
)
<<
"Resolving backend address"
;
}
ssize_t
catch_all_group
=
-
1
;
for
(
size_t
i
=
0
;
i
<
addr_groups
.
size
();
++
i
)
{
auto
&
g
=
addr_groups
[
i
];
if
(
g
.
pattern
==
StringRef
::
from_lit
(
"/"
))
{
catch_all_group
=
i
;
}
if
(
LOG_ENABLED
(
INFO
))
{
LOG
(
INFO
)
<<
"Host-path pattern: group "
<<
i
<<
": '"
<<
g
.
pattern
<<
"'"
;
for
(
auto
&
addr
:
g
.
addrs
)
{
LOG
(
INFO
)
<<
"group "
<<
i
<<
" -> "
<<
addr
.
host
.
c_str
()
<<
(
addr
.
host_unix
?
""
:
":"
+
util
::
utos
(
addr
.
port
))
<<
", proto="
<<
strproto
(
addr
.
proto
)
<<
(
addr
.
tls
?
", tls"
:
""
);
}
}
}
if
(
catch_all_group
==
-
1
)
{
LOG
(
FATAL
)
<<
"backend: No catch-all backend address is configured"
;
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
downstreamconf
.
addr_group_catch_all
=
catch_all_group
;
if
(
LOG_ENABLED
(
INFO
))
{
LOG
(
INFO
)
<<
"Catch-all pattern is group "
<<
catch_all_group
;
}
for
(
auto
&
g
:
addr_groups
)
{
for
(
auto
&
addr
:
g
.
addrs
)
{
if
(
addr
.
host_unix
)
{
// for AF_UNIX socket, we use "localhost" as host for backend
// hostport. This is used as Host header field to backend and
// not going to be passed to any syscalls.
addr
.
hostport
=
"localhost"
;
auto
path
=
addr
.
host
.
c_str
();
auto
pathlen
=
addr
.
host
.
size
();
if
(
pathlen
+
1
>
sizeof
(
addr
.
addr
.
su
.
un
.
sun_path
))
{
LOG
(
FATAL
)
<<
"UNIX domain socket path "
<<
path
<<
" is too long > "
<<
sizeof
(
addr
.
addr
.
su
.
un
.
sun_path
);
exit
(
EXIT_FAILURE
);
}
if
(
LOG_ENABLED
(
INFO
))
{
LOG
(
INFO
)
<<
"Use UNIX domain socket path "
<<
path
<<
" for backend connection"
;
}
addr
.
addr
.
su
.
un
.
sun_family
=
AF_UNIX
;
// copy path including terminal NULL
std
::
copy_n
(
path
,
pathlen
+
1
,
addr
.
addr
.
su
.
un
.
sun_path
);
addr
.
addr
.
len
=
sizeof
(
addr
.
addr
.
su
.
un
);
continue
;
}
addr
.
hostport
=
ImmutableString
(
util
::
make_http_hostport
(
StringRef
(
addr
.
host
),
addr
.
port
));
auto
hostport
=
util
::
make_hostport
(
StringRef
{
addr
.
host
},
addr
.
port
);
if
(
resolve_hostname
(
&
addr
.
addr
,
addr
.
host
.
c_str
(),
addr
.
port
,
downstreamconf
.
family
)
==
-
1
)
{
LOG
(
FATAL
)
<<
"Resolving backend address failed: "
<<
hostport
;
exit
(
EXIT_FAILURE
);
}
LOG
(
NOTICE
)
<<
"Resolved backend address: "
<<
hostport
<<
" -> "
<<
util
::
to_numeric_addr
(
&
addr
.
addr
);
}
}
auto
&
proxy
=
mod_config
()
->
downstream_http_proxy
;
auto
&
proxy
=
mod_config
()
->
downstream_http_proxy
;
if
(
!
proxy
.
host
.
empty
())
{
if
(
!
proxy
.
host
.
empty
())
{
auto
hostport
=
util
::
make_hostport
(
StringRef
{
proxy
.
host
},
proxy
.
port
);
auto
hostport
=
util
::
make_hostport
(
StringRef
{
proxy
.
host
},
proxy
.
port
);
...
...
src/shrpx_config.cc
View file @
2fd095d0
...
@@ -2904,4 +2904,193 @@ StringRef strproto(shrpx_proto proto) {
...
@@ -2904,4 +2904,193 @@ StringRef strproto(shrpx_proto proto) {
assert
(
0
);
assert
(
0
);
}
}
// Configures the following member in |config|: router,
// conn.downstream.addr_groups, wildcard_patterns,
int
configure_downstream_group
(
Config
*
config
,
bool
http2_proxy
,
bool
numeric_addr_only
,
const
TLSConfig
&
tlsconf
)
{
auto
&
downstreamconf
=
config
->
conn
.
downstream
;
auto
&
addr_groups
=
downstreamconf
.
addr_groups
;
if
(
addr_groups
.
empty
())
{
DownstreamAddrConfig
addr
{};
addr
.
host
=
ImmutableString
::
from_lit
(
DEFAULT_DOWNSTREAM_HOST
);
addr
.
port
=
DEFAULT_DOWNSTREAM_PORT
;
addr
.
proto
=
PROTO_HTTP1
;
DownstreamAddrGroupConfig
g
(
StringRef
::
from_lit
(
"/"
));
g
.
addrs
.
push_back
(
std
::
move
(
addr
));
config
->
router
.
add_route
(
StringRef
{
g
.
pattern
},
addr_groups
.
size
());
addr_groups
.
push_back
(
std
::
move
(
g
));
}
else
if
(
http2_proxy
)
{
// We don't support host mapping in these cases. Move all
// non-catch-all patterns to catch-all pattern.
DownstreamAddrGroupConfig
catch_all
(
StringRef
::
from_lit
(
"/"
));
for
(
auto
&
g
:
addr_groups
)
{
std
::
move
(
std
::
begin
(
g
.
addrs
),
std
::
end
(
g
.
addrs
),
std
::
back_inserter
(
catch_all
.
addrs
));
}
std
::
vector
<
DownstreamAddrGroupConfig
>
().
swap
(
addr_groups
);
std
::
vector
<
WildcardPattern
>
().
swap
(
config
->
wildcard_patterns
);
// maybe not necessary?
config
->
router
=
Router
();
config
->
router
.
add_route
(
StringRef
{
catch_all
.
pattern
},
addr_groups
.
size
());
addr_groups
.
push_back
(
std
::
move
(
catch_all
));
}
else
{
auto
&
wildcard_patterns
=
config
->
wildcard_patterns
;
std
::
sort
(
std
::
begin
(
wildcard_patterns
),
std
::
end
(
wildcard_patterns
),
[](
const
WildcardPattern
&
lhs
,
const
WildcardPattern
&
rhs
)
{
return
std
::
lexicographical_compare
(
rhs
.
host
.
rbegin
(),
rhs
.
host
.
rend
(),
lhs
.
host
.
rbegin
(),
lhs
.
host
.
rend
());
});
if
(
LOG_ENABLED
(
INFO
))
{
LOG
(
INFO
)
<<
"Reverse sorted wildcard hosts (compared from tail to head, "
"and sorted in reverse order):"
;
for
(
auto
&
wp
:
config
->
wildcard_patterns
)
{
LOG
(
INFO
)
<<
wp
.
host
;
}
}
}
// backward compatibility: override all SNI fields with the option
// value --backend-tls-sni-field
if
(
!
tlsconf
.
backend_sni_name
.
empty
())
{
auto
&
sni
=
tlsconf
.
backend_sni_name
;
for
(
auto
&
addr_group
:
addr_groups
)
{
for
(
auto
&
addr
:
addr_group
.
addrs
)
{
addr
.
sni
=
sni
;
}
}
}
if
(
LOG_ENABLED
(
INFO
))
{
LOG
(
INFO
)
<<
"Resolving backend address"
;
}
ssize_t
catch_all_group
=
-
1
;
for
(
size_t
i
=
0
;
i
<
addr_groups
.
size
();
++
i
)
{
auto
&
g
=
addr_groups
[
i
];
if
(
g
.
pattern
==
StringRef
::
from_lit
(
"/"
))
{
catch_all_group
=
i
;
}
if
(
LOG_ENABLED
(
INFO
))
{
LOG
(
INFO
)
<<
"Host-path pattern: group "
<<
i
<<
": '"
<<
g
.
pattern
<<
"'"
;
for
(
auto
&
addr
:
g
.
addrs
)
{
LOG
(
INFO
)
<<
"group "
<<
i
<<
" -> "
<<
addr
.
host
.
c_str
()
<<
(
addr
.
host_unix
?
""
:
":"
+
util
::
utos
(
addr
.
port
))
<<
", proto="
<<
strproto
(
addr
.
proto
)
<<
(
addr
.
tls
?
", tls"
:
""
);
}
}
}
if
(
catch_all_group
==
-
1
)
{
LOG
(
FATAL
)
<<
"backend: No catch-all backend address is configured"
;
return
-
1
;
}
downstreamconf
.
addr_group_catch_all
=
catch_all_group
;
if
(
LOG_ENABLED
(
INFO
))
{
LOG
(
INFO
)
<<
"Catch-all pattern is group "
<<
catch_all_group
;
}
auto
resolve_flags
=
numeric_addr_only
?
AI_NUMERICHOST
:
0
;
for
(
auto
&
g
:
addr_groups
)
{
for
(
auto
&
addr
:
g
.
addrs
)
{
if
(
addr
.
host_unix
)
{
// for AF_UNIX socket, we use "localhost" as host for backend
// hostport. This is used as Host header field to backend and
// not going to be passed to any syscalls.
addr
.
hostport
=
"localhost"
;
auto
path
=
addr
.
host
.
c_str
();
auto
pathlen
=
addr
.
host
.
size
();
if
(
pathlen
+
1
>
sizeof
(
addr
.
addr
.
su
.
un
.
sun_path
))
{
LOG
(
FATAL
)
<<
"UNIX domain socket path "
<<
path
<<
" is too long > "
<<
sizeof
(
addr
.
addr
.
su
.
un
.
sun_path
);
return
-
1
;
}
if
(
LOG_ENABLED
(
INFO
))
{
LOG
(
INFO
)
<<
"Use UNIX domain socket path "
<<
path
<<
" for backend connection"
;
}
addr
.
addr
.
su
.
un
.
sun_family
=
AF_UNIX
;
// copy path including terminal NULL
std
::
copy_n
(
path
,
pathlen
+
1
,
addr
.
addr
.
su
.
un
.
sun_path
);
addr
.
addr
.
len
=
sizeof
(
addr
.
addr
.
su
.
un
);
continue
;
}
addr
.
hostport
=
ImmutableString
(
util
::
make_http_hostport
(
StringRef
(
addr
.
host
),
addr
.
port
));
auto
hostport
=
util
::
make_hostport
(
StringRef
{
addr
.
host
},
addr
.
port
);
if
(
resolve_hostname
(
&
addr
.
addr
,
addr
.
host
.
c_str
(),
addr
.
port
,
downstreamconf
.
family
,
resolve_flags
)
==
-
1
)
{
LOG
(
FATAL
)
<<
"Resolving backend address failed: "
<<
hostport
;
return
-
1
;
}
LOG
(
NOTICE
)
<<
"Resolved backend address: "
<<
hostport
<<
" -> "
<<
util
::
to_numeric_addr
(
&
addr
.
addr
);
}
}
return
0
;
}
int
resolve_hostname
(
Address
*
addr
,
const
char
*
hostname
,
uint16_t
port
,
int
family
,
int
additional_flags
)
{
int
rv
;
auto
service
=
util
::
utos
(
port
);
addrinfo
hints
{};
hints
.
ai_family
=
family
;
hints
.
ai_socktype
=
SOCK_STREAM
;
hints
.
ai_flags
|=
additional_flags
;
#ifdef AI_ADDRCONFIG
hints
.
ai_flags
|=
AI_ADDRCONFIG
;
#endif // AI_ADDRCONFIG
addrinfo
*
res
;
rv
=
getaddrinfo
(
hostname
,
service
.
c_str
(),
&
hints
,
&
res
);
if
(
rv
!=
0
)
{
LOG
(
FATAL
)
<<
"Unable to resolve address for "
<<
hostname
<<
": "
<<
gai_strerror
(
rv
);
return
-
1
;
}
auto
res_d
=
defer
(
freeaddrinfo
,
res
);
char
host
[
NI_MAXHOST
];
rv
=
getnameinfo
(
res
->
ai_addr
,
res
->
ai_addrlen
,
host
,
sizeof
(
host
),
nullptr
,
0
,
NI_NUMERICHOST
);
if
(
rv
!=
0
)
{
LOG
(
FATAL
)
<<
"Address resolution for "
<<
hostname
<<
" failed: "
<<
gai_strerror
(
rv
);
return
-
1
;
}
if
(
LOG_ENABLED
(
INFO
))
{
LOG
(
INFO
)
<<
"Address resolution for "
<<
hostname
<<
" succeeded: "
<<
host
;
}
memcpy
(
&
addr
->
su
,
res
->
ai_addr
,
res
->
ai_addrlen
);
addr
->
len
=
res
->
ai_addrlen
;
return
0
;
}
}
// namespace shrpx
}
// namespace shrpx
src/shrpx_config.h
View file @
2fd095d0
...
@@ -283,6 +283,9 @@ constexpr auto SHRPX_OPT_BACKEND_HTTP2_SETTINGS_TIMEOUT =
...
@@ -283,6 +283,9 @@ constexpr auto SHRPX_OPT_BACKEND_HTTP2_SETTINGS_TIMEOUT =
constexpr
size_t
SHRPX_OBFUSCATED_NODE_LENGTH
=
8
;
constexpr
size_t
SHRPX_OBFUSCATED_NODE_LENGTH
=
8
;
constexpr
char
DEFAULT_DOWNSTREAM_HOST
[]
=
"127.0.0.1"
;
constexpr
int16_t
DEFAULT_DOWNSTREAM_PORT
=
80
;
enum
shrpx_proto
{
PROTO_NONE
,
PROTO_HTTP1
,
PROTO_HTTP2
,
PROTO_MEMCACHED
};
enum
shrpx_proto
{
PROTO_NONE
,
PROTO_HTTP1
,
PROTO_HTTP2
,
PROTO_MEMCACHED
};
enum
shrpx_forwarded_param
{
enum
shrpx_forwarded_param
{
...
@@ -713,6 +716,13 @@ read_tls_ticket_key_file(const std::vector<std::string> &files,
...
@@ -713,6 +716,13 @@ read_tls_ticket_key_file(const std::vector<std::string> &files,
// Returns string representation of |proto|.
// Returns string representation of |proto|.
StringRef
strproto
(
shrpx_proto
proto
);
StringRef
strproto
(
shrpx_proto
proto
);
int
configure_downstream_group
(
Config
*
config
,
bool
http2_proxy
,
bool
numeric_addr_only
,
const
TLSConfig
&
tlsconf
);
int
resolve_hostname
(
Address
*
addr
,
const
char
*
hostname
,
uint16_t
port
,
int
family
,
int
additional_flags
=
0
);
}
// namespace shrpx
}
// namespace shrpx
#endif // SHRPX_CONFIG_H
#endif // SHRPX_CONFIG_H
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment