Permalink
Browse files

Forward prox functionality added through a patch by Colm Dougan

  • Loading branch information...
1 parent 6055704 commit 82a449be8e5d04ce3df4f8efd9c2cc5f8cb4d4db @klacke committed Dec 2, 2009
Showing with 82 additions and 46 deletions.
  1. +16 −11 include/yaws.hrl
  2. +8 −0 man/yaws.conf.5
  3. +4 −1 src/yaws.erl
  4. +9 −0 src/yaws_config.erl
  5. +45 −34 src/yaws_server.erl
View
@@ -118,6 +118,8 @@
-define(SC_DAV, 128).
-define(SC_FCGI_TRACE_PROTOCOL, 512).
-define(SC_FCGI_LOG_APP_ERROR, 1024).
+-define(SC_FORWARD_PROXY, 2048).
+
-define(SC_DEF, ?SC_ACCESS_LOG bor ?SC_ADD_PORT).
@@ -141,6 +143,8 @@
(((SC)#sconf.flags band ?SC_FCGI_TRACE_PROTOCOL) /= 0)).
-define(sc_fcgi_log_app_error(SC),
(((SC)#sconf.flags band ?SC_FCGI_LOG_APP_ERROR) /= 0)).
+-define(sc_forward_proxy(SC),
+ (((SC)#sconf.flags band ?SC_FORWARD_PROXY) /= 0)).
-define(sc_set_access_log(SC, Bool),
@@ -162,9 +166,13 @@
-define(sc_set_dav(SC, Bool),
SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_DAV, Bool)}).
-define(sc_set_fcgi_trace_protocol(SC, Bool),
- SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_FCGI_TRACE_PROTOCOL, Bool)}).
+ SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_FCGI_TRACE_PROTOCOL,
+ Bool)}).
-define(sc_set_fcgi_log_app_error(SC, Bool),
- SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_FCGI_LOG_APP_ERROR, Bool)}).
+ SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_FCGI_LOG_APP_ERROR,
+ Bool)}).
+-define(sc_set_forward_proxy(SC, Bool),
+ SC#sconf{flags = yaws:flag(SC#sconf.flags, ?SC_FORWARD_PROXY, Bool)}).
@@ -197,22 +205,19 @@
errormod_404 = yaws_outmod, %% the default 404 error module
errormod_crash = yaws_outmod, %% use the same module for crashes
arg_rewrite_mod = yaws,
- opaque = [], %% useful in embedded mode
- start_mod, %% user provided module to be started
+ opaque = [], %% useful in embedded mode
+ start_mod, %% user provided module to be started
allowed_scripts = [yaws,php,cgi,fcgi],
tilde_allowed_scripts = [],
revproxy = [],
soptions = [],
extra_cgi_vars = [],
- stats, %% raw traffic statistics
- fcgi_app_server_host, %% FastCGI application server host name or IP address
+ stats, %% raw traffic statistics
+ fcgi_app_server_host, %% FastCGI application server host
+ %% name or IP address
- fcgi_app_server_port, %% FastCGI application server port number
+ fcgi_app_server_port %% FastCGI application server port number
- %% [{Extension:string(), Mod:atom()]
- %% work in progress .....
- extension_mods = [{"ys", yaws_ext_handler_yaws}]
-
}).
%% we cannot compare sconfs directly due to the ets
View
@@ -439,6 +439,14 @@ It is possible to have multiple reverse proxies inside the same server.
WARNING, this feature is yet not in production quality.
.TP
+\fBfwdproxy = true|false \fR
+Make yaws a forward proxy. By enabling this option you can use yaws
+as a proxy for outgoing web traffic, typically by configuring the proxy
+settings in a web-browser to explicitly target yaws as its proxy server.
+
+WARNING, this feature is yet not in production quality.
+
+.TP
\fBservername = Name\fR
If we're virthosting everal servers and want to force a server
to match specific Host: headers we can do this with the "servername"
View
@@ -321,7 +321,10 @@ set_sc_flags([{dav, Bool}|T], Flags) ->
set_sc_flags(T, flag(Flags, ?SC_DAV, Bool));
set_sc_flags([{fcgi_trace_protocol, Bool}|T], Flags) ->
set_sc_flags(T, flag(Flags, ?SC_FCGI_TRACE_PROTOCOL, Bool));
-set_sc_flags([_|T], Flags) ->
+set_sc_flags([{forward_proxy, Bool}|T], Flags) ->
+ set_sc_flags(T, flag(Flags, ?SC_FORWARD_PROXY, Bool));
+set_sc_flags([_Unknown|T], Flags) ->
+ error_logger:format("Unknown and unhandled flag ~p~n", [_Unknown]),
set_sc_flags(T, Flags);
set_sc_flags([], Flags) ->
Flags.
View
@@ -993,6 +993,15 @@ fload(FD, server, GC, C, Cs, Lno, Chars) ->
{error, "Can't revproxy to an URL with a path "}
end;
+ ["fwdproxy", '=', Bool] ->
+ case is_bool(Bool) of
+ {true, Val} ->
+ C2 = ?sc_set_forward_proxy(C, Val),
+ fload(FD, server, GC, C2, Cs, Lno+1, Next);
+ false ->
+ {error, ?F("Expect true|false at line ~w", [Lno])}
+ end;
+
['<', "extra_cgi_vars", "dir", '=', Dir, '>'] ->
fload(FD, extra_cgi_vars, GC, C, Cs, Lno+1, Next, {Dir, []});
View
@@ -1523,7 +1523,7 @@ handle_request(CliSock, ARG, N) ->
end,
- IsRev = is_revproxy(DecPath, SC#sconf.revproxy),
+ IsRev = is_revproxy(ARG, DecPath, SC),
IsRedirect = is_redirect_map(DecPath,
SC#sconf.redirect_map),
@@ -1704,14 +1704,28 @@ handle_auth(ARG, {User, Password, OrigString},
end.
-is_revproxy(_,[]) ->
+is_revproxy(ARG, Path, SC = #sconf{revproxy = RevConf}) ->
+ IsFwd = ?sc_forward_proxy(SC),
+ %% Note: these are mututally exclusive.
+ case {IsFwd, RevConf} of
+ {false, []} ->
+ false;
+ {false, _} ->
+ is_revproxy1(Path, RevConf);
+ {true, _} ->
+ {true, {"/", fwdproxy_url(ARG)}};
+ {_, _} ->
+ false
+ end.
+
+is_revproxy1(_,[]) ->
false;
-is_revproxy(Path, [{Prefix, URL} | Tail]) ->
+is_revproxy1(Path, [{Prefix, URL} | Tail]) ->
case yaws:is_prefix(Prefix, Path) of
{true,_} ->
{true, {Prefix,URL}};
false ->
- is_revproxy(Path, Tail)
+ is_revproxy1(Path, Tail)
end.
is_redirect_map(_, []) ->
@@ -2050,29 +2064,7 @@ handle_ut(CliSock, ARG, UT = #urltype{type = php}, N) ->
end,
fun(A)->finish_up_dyn_file(A, CliSock)
end
- );
-
-handle_ut(CliSock, ARG, UT = #urltype{type = {extmod, {_Ext,_Mod}}}, N) ->
- Req = ARG#arg.req,
- H = ARG#arg.headers,
-
- ?Debug("UT = ~s~n", [?format_record(UT, urltype)]),
- Allowed = ['GET', 'POST', 'HEAD', 'OPTIONS'],
- if
- Req#http_request.method == 'GET';
- Req#http_request.method == 'POST';
- Req#http_request.method == 'HEAD' ->
- yaws:outh_set_dyn_headers(Req, H, UT),
- do_extmod(CliSock, ARG, UT, N);
- Req#http_request.method == 'OPTIONS' ->
- deliver_options(CliSock, Req, Allowed);
- true ->
- deliver_405(CliSock, Req, Allowed)
- end.
-
-do_extmod(_CliSock, _ARG, _UT, _N) ->
- done.
-
+ ).
done_or_continue() ->
case yaws:outh_get_doclose() of
@@ -4168,13 +4160,8 @@ deflate_q(_, _, _) ->
suffix_type(SC, L) ->
R=suffix_type(L),
case R of
- {regular, Ext, Mime} ->
- case lists:keysearch(Ext, 1, SC#sconf.extension_mods) of
- {value, ExtMod} ->
- {{extmod, ExtMod}, Mime};
- false ->
- {regular, Mime}
- end;
+ {regular, _Ext, Mime} ->
+ {regular, Mime};
{X, _Ext, Mime} ->
case member(X, SC#sconf.allowed_scripts) of
true -> {X, Mime};
@@ -4433,3 +4420,27 @@ dec_con(GS) ->
code_change(_OldVsn, Data, _Extra) ->
{ok, Data}.
+
+
+fwdproxy_url(ARG) ->
+ Headers = ARG#arg.headers,
+ {abs_path, Path} = (ARG#arg.req)#http_request.path,
+
+ {Host, Port} =
+ case yaws:split_at(Headers#headers.host, $:) of
+ {Host0, Port0} ->
+ case string:to_integer(Port0) of
+ {Port1, []} ->
+ {Host0, Port1};
+ _ ->
+ {Headers#headers.host, undefined}
+ end;
+ _Other ->
+ {Headers#headers.host, undefined}
+ end,
+
+ #url{scheme = http,
+ host = Host,
+ port = Port,
+ path = Path}.
+

0 comments on commit 82a449b

Please sign in to comment.