package awso-sync
All checked builds pass sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
Synchronous (blocking) AWS client (400+ services, auto-generated from botocore)
Install
dune-project
Dependency
Authors
Maintainers
Sources
awso-0.9.1.tbz
sha256=e0e7510192b7e45871cff5c60e5162a77a9fa103b6924136fb1fea5db2092b26
sha512=51a18cf74c122b021bd84ef5728b7c5b2d5e767f03d5cd2387d886edc34a68cf54a3183e2d6c4939b4c8d3e0c0e406c869d019f2ee9a0903ae4cf7ca725572f0
doc/src/awso-sync/http.ml.html
Source file http.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161open! Import (* Synchronous HTTP backend using libcurl (via [ocurl]). Pure blocking I/O. The lwt and async backends drive cohttp manually because they need to weave their I/O into their respective scheduler; the sync backend has no scheduler to weave into, so we let libcurl do the wire-level work. We still build a Cohttp.Request.t to feed to Awso.Auth.sign_request (the signing function takes Cohttp's request type). We then extract the signed headers and hand everything to curl. *) let method_string (meth : Awso.Http.Meth.t) = match meth with | `GET -> "GET" | `POST -> "POST" | `PUT -> "PUT" | `DELETE -> "DELETE" | `HEAD -> "HEAD" | `PATCH -> "PATCH" | `OPTIONS -> "OPTIONS" | `CONNECT -> "CONNECT" | `TRACE -> "TRACE" | `Other s -> s ;; let body_makes_sense_for = function | `POST | `PUT | `PATCH | `Other _ -> true | `GET | `HEAD | `DELETE | `OPTIONS | `CONNECT | `TRACE -> false ;; (* Curl wants headers as a "Name: value" string list. *) let cohttp_headers_to_curl headers = Cohttp.Header.to_list headers |> List.map ~f:(fun (k, v) -> sprintf "%s: %s" k v) ;; (* libcurl reports the response status as the integer code; turn it into the Awso.Http.Status.t our runtime expects. *) let status_of_code code : Awso.Http.Status.t = match Cohttp.Code.status_of_code code with | #Awso.Http.Status.t as s -> (s :> Awso.Http.Status.t) | other -> `Code (Cohttp.Code.code_of_status other) ;; (* libcurl's headerfunction is called once per response header line, including the trailing CRLF on each line and the empty line at the end of the block. We parse just the "Name: value" lines. *) let parse_response_header_line line = match String.index_opt line ':' with | None -> None | Some i -> let name = String.sub line 0 i in let value = let rest = String.sub line (i + 1) (String.length line - i - 1) in String.trim rest in Some (name, value) ;; let perform_request ~uri ~meth ~headers ~req_body = let h = Curl.init () in let body_buf = Buffer.create 4096 in let resp_headers = ref [] in Fun.protect ~finally:(fun () -> Curl.cleanup h) (fun () -> Curl.set_url h (Uri.to_string uri); Curl.set_httpheader h (cohttp_headers_to_curl headers); Curl.set_followlocation h true; Curl.set_maxredirs h 50; (* TODO: handle S3-style "PermanentRedirect" responses, where the new endpoint is in the XML body rather than a Location header. The lwt backend (lib/runtime/lwt/http.ml: find_xml_redirect_endpoint) does this — we should port that logic here so cross-region S3 bucket access works against awso-sync too. *) Curl.set_useragent h "awso-sync/0.9"; Curl.set_writefunction h (fun chunk -> Buffer.add_string body_buf chunk; String.length chunk); Curl.set_headerfunction h (fun line -> (match parse_response_header_line line with | None -> () | Some kv -> resp_headers := kv :: !resp_headers); String.length line); Curl.set_customrequest h (method_string meth); if body_makes_sense_for meth then ( Curl.set_postfields h req_body; Curl.set_postfieldsize h (String.length req_body)); if Stdlib.( = ) meth `HEAD then Curl.set_nobody h true; Curl.perform h; let code = Curl.get_responsecode h in let status = status_of_code code in let body = Buffer.contents body_buf in let headers = Awso.Http.Headers.of_list (List.rev !resp_headers) in Awso.Http.Response.make ~headers ~body status) ;; module Io = struct let return x = x let bind x f = f x let map x f = f x let call ?endpoint_url ~cfg ~service meth request uri = let { Awso.Cfg.region ; aws_access_key_id ; aws_secret_access_key ; aws_session_token ; _ } = cfg in let region = match region with | Some r -> r | None -> failwith "config must set 'region'" in let endpoint = match endpoint_url with | Some endpoint_url -> Uri.of_string endpoint_url | None -> Awso.Botocore_endpoints.lookup_uri ~region service `HTTPS in let uri = Uri.with_uri ~scheme:(Uri.scheme endpoint) ~host:(Uri.host endpoint) uri in let host = match Uri.host endpoint with | Some h -> h | None -> failwith (sprintf "could not extract 'host' from url %s" (Uri.to_string endpoint)) in let cohttp_meth : Cohttp.Code.meth = (meth :> Cohttp.Code.meth) in let req_body = Awso.Http.Request.body request in let body_length = Int64.of_int (String.length req_body) in let payload_hash = Awso.Auth.payload_hash req_body in let headers = let init = request |> Awso.Http.Request.headers |> Awso.Http.Headers.to_list |> Cohttp.Header.of_list in Cohttp.Header.add init "host" host in let signed = Cohttp.Request.make_for_client ~headers ~chunked:false ~body_length cohttp_meth uri |> Awso.Auth.sign_request ~region ~service ?session_token:aws_session_token ?aws_access_key_id ?aws_secret_access_key ~payload_hash in let signed_headers = Cohttp.Request.headers signed in perform_request ~uri ~meth ~headers:signed_headers ~req_body ;; let resolve_cfg = function | Some cfg -> cfg | None -> Cfg.get_exn () ;; end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>