Redirection not working with nethttpd
Paolo Donadeo <[email protected]> Tue, 11 Aug 2009 15:46:36 +0200
| Newsgroups | gmane.comp.lang.ocaml.lib.net.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi everybody, I think I need your help. I just wrote a minimal program
that highlights a problem with redirect and nethttpd. The script is so
simple that I think I simply missed something, or incorrectly
configured the netplex server.
The CGI script handles only 3 URLS: "/", the home page with a login
form, that has "/post_url" as action; "/post_url", that handles the
POST and redirect to "/redir" and, finally, "/redir" which displays
"OK". Everything else is "not found".
After the form POST I read this log line:
[Tue Aug 11 15:28:01 2009] [test server] [err] [-] [-] Nethttpd:
Uncaught exception: Failure("Caught Redirect_response, but it is too
late for redirections")
The script can be compiled with:
$ ocamlbuild test.d.byte (or test.native)
and run with
$ ./test.d.byte -conf netplex.conf -fg
All the files needed for compilation are attached. I'm running a 32
bit Ubuntu box, with Objective Caml 3.11.0 and Ocamlnet 2.2.9.
Can you help me?
--
Paolo
~
~
:wq
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
Ocamlnet-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ocamlnet-devel
myocamlbuild.ml
(text/x-ocaml, 1.7 KB)
open Ocamlbuild_plugin
open Command (* no longer needed for OCaml >= 3.10.2 *)
(* these functions are not really officially exported *)
let run_and_read = Ocamlbuild_pack.My_unix.run_and_read
let blank_sep_strings = Ocamlbuild_pack.Lexers.blank_sep_strings
(* this lists all supported packages *)
let find_packages () =
blank_sep_strings &
Lexing.from_string &
run_and_read "ocamlfind list | cut -d' ' -f1"
(* ocamlfind command *)
let ocamlfind x = S[A"ocamlfind"; x]
let _ = dispatch begin function
| Before_options ->
(* override default commands by ocamlfind ones *)
Options.ocamlc := ocamlfind & A"ocamlc";
Options.ocamlopt := ocamlfind & A"ocamlopt";
Options.ocamldep := ocamlfind & A"ocamldep";
Options.ocamldoc := ocamlfind & A"ocamlfind";
| After_rules ->
(* When one link an OCaml library/binary/package, one should use -linkpkg *)
flag ["ocaml"; "link"] & A"-linkpkg";
flag ["ocaml"; "thread_option"] & A"-thread";
flag ["infer_interface"; "use_camlp4"] & S[A"-I"; A"+camlp4"];
(* For each ocamlfind package one inject the -package option when
* compiling, computing dependencies, generating documentation and
* linking. *)
List.iter
(
fun pkg ->
flag ["ocaml"; "compile"; "pkg_"^pkg] & S[A"-package"; A pkg];
flag ["ocaml"; "ocamldep"; "pkg_"^pkg] & S[A"-package"; A pkg];
flag ["ocaml"; "doc"; "pkg_"^pkg] & S[A"-package"; A pkg];
flag ["ocaml"; "link"; "pkg_"^pkg] & S[A"-package"; A pkg];
flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S[A"-package"; A pkg];
) (find_packages ());
| _ -> ()
end
netplex.conf
(application/octet-stream, 829 B)
netplex {
controller {
max_level = "debug";
logging {
type = "file";
file = "/home/paolo/Documenti/Home_page/blog.git/src/test_MVC/test/test.log";
}
};
service {
name = "test server";
protocol {
name = "http";
address {
type = "internet";
bind = "127.0.0.1:8000";
};
};
processor {
type = "nethttpd";
host {
pref_name = "localhost";
pref_port = 8000;
names = "*:0";
uri {
path = "/";
service {
type = "dynamic";
handler = "test_handler";
}
};
};
};
workload_manager {
type = "dynamic";
max_jobs_per_thread = 1;
min_free_jobs_capacity = 1;
max_free_jobs_capacity = 1;
max_threads = 20;
};
}
}
_tags
(application/octet-stream, 133 B) - not displayed
test.log
(text/x-log, 158 B)
[Tue Aug 11 15:28:01 2009] [test server] [err] [-] [-] Nethttpd: Uncaught exception: Failure("Caught Redirect_response, but it is too late for redirections")
test.ml
(text/x-ocaml, 2.9 KB)
let rec request_dispatcher (cgi : Netcgi.cgi_activation) =
let script_name = cgi#environment#cgi_script_name in
match script_name with
| "/" -> begin (* The "home" page *)
(* A simple login form *)
let content = "<html>
<head><title>Home page</head>
<body>
<p>Login</p>
<p>
<form action=\"/post_url\" method=\"post\">
<input type=\"text\" name=\"login\" id=\"login\">
<br />
<input type=\"password\" name=\"pwd\" id=\"pwd\">
<br />
<input type=\"submit\" name=\"submit\" id=\"submit\" value=\"Log In\"/>
</form>
</p>
</body>
</html>" in
let content_length = String.length content in
cgi#set_header
~status:`Ok
~cache:`No_cache
~content_length ();
cgi#out_channel#output_string content;
cgi#out_channel#commit_work ();
end
| "/post_url" -> begin (* handles the POST and redirect to /redir *)
let e = cgi#environment in
e#set_output_header_fields [];
e#set_status `Found;
e#set_output_header_field "Location" "/redir";
cgi#out_channel#commit_work ();
end
| "/redir" -> begin (* the "logged in" page *)
let content = "OK!" in
let content_length = String.length content in
cgi#set_header
~status:`Ok
~cache:`No_cache
~content_type:"text/plain"
~content_length ();
cgi#out_channel#output_string content;
cgi#out_channel#commit_work ();
end
| _ -> begin
let content = "Sorry, not found!" in
let content_length = String.length content in
cgi#set_header
~status:`Not_found
~cache:`No_cache
~content_type:"text/plain"
~content_length ();
cgi#out_channel#output_string content;
cgi#out_channel#commit_work ();
end
;;
let request_dispatcher' (cgi : Netcgi1_compat.Netcgi_types.cgi_activation) =
let cgi' = Netcgi1_compat.Netcgi_types.of_compat_activation cgi in
request_dispatcher cgi';
;;
let netplex_dynamic_handler =
{
Nethttpd_services.dyn_handler = (fun _ -> request_dispatcher');
dyn_activation = Nethttpd_services.std_activation `Std_activation_buffered;
dyn_uri = None;
dyn_translator = (fun _ -> "");
dyn_accept_all_conditionals = false;
};;
let nethttpd_factory () =
Nethttpd_plex.nethttpd_factory
~handlers:[("test_handler", netplex_dynamic_handler)] ()
;;
let main() =
let (opt_list, cmdline_cfg) = Netplex_main.args () in
Arg.parse
opt_list
(fun s -> raise (Arg.Bad ("Don't know what to do with: " ^ s)))
"usage: netplex [options]";
Netplex_main.startup
(Netplex_mp.mp ())
Netplex_log.logger_factories
Netplex_workload.workload_manager_factories
[ nethttpd_factory () ]
cmdline_cfg
;;
Sys.set_signal Sys.sigpipe Sys.Signal_ignore;;
main();;