我可以用Ocamlnet CGI读取原始POST数据吗?

时间:2014-03-06 23:14:51

标签: cgi ocaml

我正在使用Ocamlnet编写一些Web服务。更具体地说,我将Netcgi_scgi与Apache 2结合使用。

看起来所有功能都是为了向我展示已经解析过的用户输入视图。

我有没有办法直接访问输入流,所以我可以自己解析原始POST数据?

另外,有没有办法阻止Netcgi代码自动尝试解析POST数据? (我发现,我正在这样做,它失败并抛出异常,如果它没有收到预期的键值格式,所以我的处理程序甚至都不会被调用。)

我希望能够支持JSON-RPC,它要求POST数据是一个没有与之关联的参数名称的JSON对象。 (好吧,规范不是协议特定的,所以没有拼写,但在我看来,这是最合理的解释。旧的(1.2)规范明确表明它是这样做的。)

2 个答案:

答案 0 :(得分:0)

简单的方法是(使用plex)允许application/json mime

Nethttpd_plex.nethttpd_factory
  ~config_cgi:Netcgi.({
  default_config with
  default_exn_handler = false;
  permitted_input_content_types = [
    "application/json";
  ] @ default_config.permitted_input_content_types})

然后,您将获得单个参数BODY中的请求内容(如果客户端正确发送Content-Type: application/json标头),那么您可以执行类似

的操作
let get_json_request (cgi : Netcgi.cgi_activation) =
  cgi # argument_value "BODY"
  |> Yojson.Basic.from_string

let generate_page (cgi : Netcgi.cgi_activation) =
  get_json_request cgi |> process_json_request

更难(但可能更好)的方法是为您的处理程序提供自己的dyn_activationdyn_handler或创建新服务(在ocamlnet源中查找default_dynamic_service)...但我刚走下那条路......

答案 1 :(得分:0)

使用cgi_argument

let with_arg arg f = Io.unwind ~protect:(fun arg -> arg#finalize ()) f arg

let get_arg cgi name =
  try  Some (with_arg (cgi#argument name) (fun arg -> arg#value))
  with Not_found -> None

let parse ?default ~validate ~parse cgi name =
  match default, get_arg cgi name with
  | None  , None    -> argf "Missing parameter \"%s\"" name
  | Some v, None    -> v
  | _     , Some p  ->
    try  parse (Pcre.extract ~rex:validate ~full_match:false p)
    with Not_found -> argf "Invalid parameter \"%s\"" name

<强>参考