0

谁能确认 Cohttp_mirage.Client 是否支持 TLS (https)?我所做的挖掘似乎表明 Conduit_mirage确实支持客户端 tls,但是在 Cohttp_mirage 中,而服务器是仿函数,它采用可以是 tcp 或 tls 的流(从 mirage-www dispatch_tls.ml 文件中收集到)。

如果它确实支持 TLS,是否有任何示例说明如何设置(对于 Mirage)?我在网上或海市蜃楼中找不到任何东西。我正在为单个 Web 服务编写客户端,所以我猜它只需要一个证书。

如果答案是“不,它不支持 TLS”,是否有任何工作正在进行?也许我可以尝试深入了解自己。我已经编程了 15 年,但我对 OCaml 还是很陌生。

4

2 回答 2

1

我不明白你的问题,因为你说 mirage-http确实支持 TLS - 那么你卡在哪里了?我想您需要将启用 TLS 的管道传递给connect_uri.

在服务器端,该项目的网站 ( https://mirage.io/ ) 是一个支持 TLS 的 unikernel。

示例项目(虽然所有服务器,但客户端也应该工作):

于 2016-02-11T10:18:52.230 回答
1

如前所述,问题是将启用 TLS 的管道传递给最终的 Cohttp 客户端。这是我的海市蜃楼“config.ml”文件。

open Mirage

let net =
  try match Sys.getenv "NET" with
    | "direct" -> `Direct
    | "socket" -> `Socket
    | _        -> `Direct
  with Not_found -> `Socket

let dhcp =
  try match Sys.getenv "DHCP" with
    | "" -> false
    | _  -> true
  with Not_found -> false

let stack console =
  match net, dhcp with
  | `Direct, true  -> direct_stackv4_with_dhcp console tap0
  | `Direct, false -> direct_stackv4_with_default_ipv4 console tap0
  | `Socket, _     -> socket_stackv4 console [Ipaddr.V4.any]

let main =
  foreign "MyDispatch.Main" (console @-> http @-> resolver @-> conduit @-> job)

let () =
  let sv4 = stack default_console in
  let res_dns = resolver_dns sv4 in
  let conduit = conduit_direct ~tls:true sv4 in
  let http_srv = http_server conduit ind
  register "ident" [
    main $ default_console $ http_srv $ res_dns $ conduit
  ]

请注意,我还需要 DNS 才能使 http 客户端正常工作。关键部分是~tls:true

let conduit = conduit_direct ~tls:true sv4 in ...

在调度文件(MyDispatch.ml,为了避免名称冲突,我有:

open Lwt
open Cohttp
open Printf
open V1_LWT

module Main (C:CONSOLE) (S:Cohttp_lwt.Server) (RES: Resolver_lwt.S) (CON: Conduit_mirage.S) = struct
    module SH = ServiceHandlers.Make (Cohttp_mirage.Client)
    module Wm = SH.Wm

    let routes ctx = [
        ("/v1/ident/initiate", fun () -> new SH.initiate_session ctx );
    ]

    let callback ctx (ch,conn) request body =
        Wm.dispatch' (routes ctx) ~body ~request
    >|= begin function
        | None        -> (`Not_found, Header.init (), `String "Not found", [])
        | Some result -> result
    end
    >>= fun (status, headers, body, path) ->
        let path =
            match Sys.getenv "DEBUG_PATH" with
        | _ -> Printf.sprintf " - %s" (String.concat ", " path)
        | exception Not_found   -> ""
        in
      Printf.eprintf "%d - %s %s%s"
        (Code.code_of_status status)
        (Code.string_of_method (Request.meth request))
        (Uri.path (Request.uri request))
        path;
      S.respond ~headers ~body ~status ()

    let start c http (res_dns) (ctx:CON.t) =
        let ctx = Cohttp_mirage.Client.ctx res_dns ctx in
        let callback = callback ctx in
        let conn_closed (_,conn_id) =
            let cid = Cohttp.Connection.to_string conn_id in
            C.log c (Printf.sprintf "conn %s closed" cid)
            in
    http (`TCP 8080) (S.make ~conn_closed ~callback ())
end

这里的关键部分是将 DNS 解析器添加到(启用了 TLS 的)上下文并将其传递给回调,因此它最终可以被客户端使用。ServiceHandlers使用 Webmachine 并且是一个带有Cohttp_lwt.Client模块的仿函数(Cohttp_lwt_mirage.Client在本例中为 )。最终,客户端使用启用了 TLS/DNS 的上下文进行调用(handle_response是特定于应用程序的代码。):

Client.post ~ctx:ctx_with_tls_dns ~headers ~body uri >>= handle_response

“当您知道如何(tm)时,这很容易”。请注意,到目前为止,我只使用 Mirage/unix 运行它,而不是 Mirage/xen。

于 2016-02-15T18:02:54.027 回答