Skip to content

Commit

Permalink
Accept an IPv6 between "[...]" as an fcgi server hostname
Browse files Browse the repository at this point in the history
Here are some examples:
    php_handler = <fcgi, [::1]:9000>
    fcgi_app_server = [::1]:9000

The square brackets syntax is already used in URLs (http://[::1]:8080/)
and allows to mix an IPv6 address and a port number.

While here, fix a bug in revproxy URL parsing where IPv6 between
brackets were considered as a syntax error.
  • Loading branch information
dumbbell committed Apr 15, 2014
1 parent 52e7b4c commit 2e662ff
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 12 deletions.
10 changes: 8 additions & 2 deletions doc/yaws.tex
Expand Up @@ -2648,8 +2648,9 @@ \section{Server Part}

\item \verb+fcgi_app_server = Host:Port+ ---
The hostname and TCP port number of a FastCGI application
server. The TCP port number is not optional. There is no default
value.
server. To specify an IPv6 address, put it inside square
brackets (ex: "[::1]:9000"). The TCP port number is not
optional. There is no default value.

\item \verb+fcgi_trace_protocol = true | false+ ---
Enable or disable tracing of FastCGI protocol messages as info log
Expand Down Expand Up @@ -3053,6 +3054,11 @@ \section{Server Part}
\Yaws{}, specify:
\begin{verbatim}
php_handler = <fcgi, 127.0.0.1:54321>
\end{verbatim}
If you need to specify an IPv6 address, use square
brackets:
\begin{verbatim}
php_handler = <fcgi, [::1]:54321>
\end{verbatim}
The PHP interpreter needs read access to the files it
is to serve. Thus, if you run it in a different
Expand Down
12 changes: 10 additions & 2 deletions man/yaws.conf.5
Expand Up @@ -500,8 +500,10 @@ Turns on/off statistics gathering for a virtual server. Default is \fIfalse\fR.

.TP
\fBfcgi_app_server = Host:Port\fR
The hostname and TCP port number of a FastCGI application server. The TCP port
number is not optional. There is no default value.
The hostname and TCP port number of a FastCGI application server.
To specify an IPv6 address, put it inside square brackets (ex:
"[::1]:9000"). The TCP port number is not optional. There is no default
value.

.TP
\fBfcgi_trace_protocol = true | false\fR
Expand Down Expand Up @@ -915,6 +917,12 @@ make use of this PHP server from Yaws, specify:
php_handler = <fcgi, 127.0.0.1:54321>
.fi

If you need to specify an IPv6 address, use square brackets:

.nf
php_handler = <fcgi, [::1]:54321>
.fi

The PHP interpreter needs read access to the files it is to serve. Thus, if you
run it in a different security context than Yaws itself, make sure it has access
to the .php files.
Expand Down
39 changes: 31 additions & 8 deletions src/yaws_config.erl
Expand Up @@ -639,16 +639,22 @@ yaws_dir() ->
yaws:get_app_dir().

string_to_host_and_port(String) ->
case string:tokens(String, ":") of
[Host, Port] ->
HostPortRE = "^(?:\\[([^\\]]+)\\]|([^:]+)):([0-9]+)$",
REOptions = [{capture, all_but_first, list}],
case re:run(String, HostPortRE, REOptions) of
{match, [IPv6, HostOrIPv4, Port]} ->
case string:to_integer(Port) of
{Integer, []} when Integer >= 0, Integer =< 65535 ->
{ok, Host, Integer};
case IPv6 of
"" -> {ok, HostOrIPv4, Integer};
_ -> {ok, IPv6, Integer}
end;
_Else ->
{error, ?F("~p is not a valid port number", [Port])}
end;
_Else ->
{error, ?F("bad host and port specifier, expected HOST:PORT", [])}
nomatch ->
{error, ?F("bad host and port specifier, expected HOST:PORT; "
"use [IP]:PORT for IPv6 address", [])}
end.

string_to_node_mod_fun(String) ->
Expand Down Expand Up @@ -1503,14 +1509,18 @@ fload(FD, server, GC, C, Cs, Lno, Chars) ->
{error, ?F("Expect true|false at line ~w", [Lno])}
end;

["fcgi_app_server", '=', Val] ->
case string_to_host_and_port(Val) of
["fcgi_app_server", '=' | Val] ->
HostPortSpec = case Val of
[HPS] -> HPS;
['[', HSpec, ']', PSpec] -> "[" ++ HSpec ++ "]" ++ PSpec
end,
case string_to_host_and_port(HostPortSpec) of
{ok, Host, Port} ->
C2 = C#sconf{fcgi_app_server = {Host, Port}},
fload(FD, server, GC, C2, Cs, Lno+1, Next);
{error, Reason} ->
{error, ?F("Invalid fcgi_app_server ~p at line ~w: ~s",
[Val, Lno, Reason])}
[HostPortSpec, Lno, Reason])}
end;

["fcgi_trace_protocol", '=', Bool] ->
Expand Down Expand Up @@ -2405,6 +2415,12 @@ parse_revproxy([Prefix, Url, "intercept_mod", InterceptMod]) ->
Error ->
Error
end;
parse_revproxy([Prefix, Proto, '[', IPv6, ']', Rest, "intercept_mod", InterceptMod]) ->
Url = Proto ++ "[" ++ IPv6 ++ "]" ++ Rest,
parse_revproxy([Prefix, Url, "intercept_mod", InterceptMod]);
parse_revproxy([Prefix, Proto, '[', IPv6, ']', Rest]) ->
Url = Proto ++ "[" ++ IPv6 ++ "]" ++ Rest,
parse_revproxy([Prefix, Url]);
parse_revproxy(_Other) ->
{error, syntax}.

Expand Down Expand Up @@ -2466,6 +2482,13 @@ parse_phpmod(['<', "fcgi", ',', HostPortSpec, '>'], _) ->
{error, Reason} ->
{error, Reason}
end;
parse_phpmod(['<', "fcgi", ',', '[', HostSpec, ']', PortSpec, '>'], _) ->
case string_to_host_and_port("[" ++ HostSpec ++ "]" ++ PortSpec) of
{ok, Host, Port} ->
{ok, {fcgi, {Host, Port}}};
{error, Reason} ->
{error, Reason}
end;
parse_phpmod(['<', "extern", ',', NodeModFunSpec, '>'], _) ->
case string_to_node_mod_fun(NodeModFunSpec) of
{ok, Node, Mod, Fun} ->
Expand Down

0 comments on commit 2e662ff

Please sign in to comment.