mirror of
https://github.com/c-cube/ezcurl.git
synced 2026-03-07 21:47:55 -05:00
Compare commits
2 commits
aa5474167f
...
def9411b72
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
def9411b72 | ||
|
|
ab39f4cbdc |
9 changed files with 82 additions and 66 deletions
23
CHANGELOG.md
23
CHANGELOG.md
|
|
@ -1,27 +1,38 @@
|
|||
## 0.2.4
|
||||
|
||||
# 0.3
|
||||
|
||||
- Provide seek function when uploading from string
|
||||
- make `CURLOPT_NOSIGNAL=false` the default; simplify
|
||||
- Expose underlying no signal in a global setting
|
||||
- implement `http_stream`
|
||||
- feat: add `Ezcurl.Cookies` module, get/set/transfer them
|
||||
|
||||
- breaking: wrap Curl.t in record
|
||||
|
||||
# 0.2.4
|
||||
|
||||
- fix: global initialization logic is now hidden behind a mutex
|
||||
* depend on `thread`
|
||||
|
||||
## 0.2.3
|
||||
# 0.2.3
|
||||
|
||||
- fix: workaround servers which do not understand "Expect" header
|
||||
- fix: correctly set size of payload for POST
|
||||
- make sure to setup 'PUT" correctly
|
||||
- allow POST with non-form data
|
||||
|
||||
## 0.2.2
|
||||
# 0.2.2
|
||||
|
||||
- fix: do not reset client if passed as argument
|
||||
|
||||
## 0.2.1
|
||||
# 0.2.1
|
||||
|
||||
- fix setting of headers
|
||||
|
||||
## 0.2
|
||||
# 0.2
|
||||
|
||||
- add default user agent
|
||||
|
||||
## 0.1
|
||||
# 0.1
|
||||
|
||||
- initial release
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
(name ezcurl)
|
||||
|
||||
(version 0.2.4)
|
||||
(version 0.3)
|
||||
|
||||
(generate_opam_files true)
|
||||
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
(ocurl
|
||||
(>= 0.8))
|
||||
(odoc :with-doc)
|
||||
(tiny_httpd (and (>= 0.19) :with-test))
|
||||
(ocaml
|
||||
(>= 4.03))))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# This file is generated by dune, edit dune-project instead
|
||||
opam-version: "2.0"
|
||||
version: "0.2.4"
|
||||
version: "0.3"
|
||||
synopsis: "Friendly wrapper around OCurl, Lwt version"
|
||||
maintainer: ["simon.cruanes.2007@m4x.org"]
|
||||
authors: ["Simon Cruanes"]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# This file is generated by dune, edit dune-project instead
|
||||
opam-version: "2.0"
|
||||
version: "0.2.4"
|
||||
version: "0.3"
|
||||
synopsis: "Friendly wrapper around OCurl"
|
||||
maintainer: ["simon.cruanes.2007@m4x.org"]
|
||||
authors: ["Simon Cruanes"]
|
||||
|
|
@ -13,6 +13,7 @@ depends: [
|
|||
"dune" {>= "3.0"}
|
||||
"ocurl" {>= "0.8"}
|
||||
"odoc" {with-doc}
|
||||
"tiny_httpd" {>= "0.19" & with-test}
|
||||
"ocaml" {>= "4.03"}
|
||||
]
|
||||
build: [
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ module type S = sig
|
|||
@param headers headers of the query *)
|
||||
|
||||
(** Push-stream of bytes
|
||||
@since NEXT_RELEASE *)
|
||||
@since 0.3 *)
|
||||
class type input_stream = object
|
||||
method on_close : unit -> unit
|
||||
method on_input : bytes -> int -> int -> unit
|
||||
|
|
@ -280,7 +280,7 @@ module type S = sig
|
|||
unit ->
|
||||
(unit response, Curl.curlCode * string) result io
|
||||
(** HTTP call via cURL, with a streaming response body.
|
||||
@since NEXT_RELEASE *)
|
||||
@since 0.3 *)
|
||||
|
||||
val get :
|
||||
?tries:int ->
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ end
|
|||
|
||||
type t = private { curl: Curl.t } [@@unboxed]
|
||||
(** A client, i.e. a cURL instance. The wrapping record has been present since
|
||||
NEXT_RELEASE *)
|
||||
0.3 *)
|
||||
|
||||
val make :
|
||||
?set_opts:(Curl.t -> unit) ->
|
||||
|
|
@ -29,10 +29,10 @@ val make :
|
|||
@param set_opts called before returning the client, to set options
|
||||
@param cookiejar_file
|
||||
if provided, tell curl to use the given file path to store/load cookies
|
||||
(since NEXT_RELEASE)
|
||||
(since 0.3)
|
||||
@param enable_session_cookies
|
||||
if provided, enable cookie handling in curl so it store/load cookies
|
||||
(since NEXT_RELEASE) *)
|
||||
(since 0.3) *)
|
||||
|
||||
val delete : t -> unit
|
||||
(** Delete the client. It cannot be used anymore. *)
|
||||
|
|
@ -43,21 +43,21 @@ val with_client : ?set_opts:(Curl.t -> unit) -> (t -> 'a) -> 'a
|
|||
val set_no_signal : bool -> unit
|
||||
(** Set no_signal default value for each new client instance. Default is [true].
|
||||
See [CURLOPT_NOSIGNAL].
|
||||
@since NEXT_RELEASE *)
|
||||
@since 0.3 *)
|
||||
|
||||
(** Cookie handling.
|
||||
|
||||
@since NEXT_RELEASE *)
|
||||
@since 0.3 *)
|
||||
module Cookies : sig
|
||||
val flush_cookiejar : t -> unit
|
||||
(** If [cookiejar_file] was provided in {!make}, this flushes the current set
|
||||
of cookies to the provided file.
|
||||
@since NEXT_RELEASE *)
|
||||
@since 0.3 *)
|
||||
|
||||
val reload_cookiejar : t -> unit
|
||||
(** If [cookiejar_file] was provided in {!make}, this reloads cookies from the
|
||||
provided file.
|
||||
@since NEXT_RELEASE *)
|
||||
@since 0.3 *)
|
||||
|
||||
val get_cookies : t -> string list
|
||||
(** Get cookie list (in netscape format) *)
|
||||
|
|
@ -164,7 +164,7 @@ module type S = sig
|
|||
@param headers headers of the query *)
|
||||
|
||||
(** Push-based stream of bytes
|
||||
@since NEXT_RELEASE *)
|
||||
@since 0.3 *)
|
||||
class type input_stream = object
|
||||
method on_close : unit -> unit
|
||||
method on_input : bytes -> int -> int -> unit
|
||||
|
|
@ -185,7 +185,7 @@ module type S = sig
|
|||
(** HTTP call via cURL, with a streaming response body. The body is given to
|
||||
[write_into] by chunks, then [write_into#on_close ()] is called and the
|
||||
response is returned.
|
||||
@since NEXT_RELEASE *)
|
||||
@since 0.3 *)
|
||||
|
||||
val get :
|
||||
?tries:int ->
|
||||
|
|
|
|||
|
|
@ -1,39 +1,8 @@
|
|||
get: OK
|
||||
body=```
|
||||
version = 0.27.0
|
||||
profile=conventional
|
||||
margin=80
|
||||
if-then-else=k-r
|
||||
parens-ite=true
|
||||
parens-tuple=multi-line-only
|
||||
sequence-style=terminator
|
||||
type-decl=sparse
|
||||
break-cases=toplevel
|
||||
cases-exp-indent=2
|
||||
field-space=tight-decl
|
||||
leading-nested-match-parens=true
|
||||
module-item-spacing=compact
|
||||
quiet=true
|
||||
ocaml-version=4.08.0
|
||||
|
||||
code=200,body=```
|
||||
hello jeanjacques
|
||||
```
|
||||
streaming get: OK
|
||||
body=```
|
||||
version = 0.27.0
|
||||
profile=conventional
|
||||
margin=80
|
||||
if-then-else=k-r
|
||||
parens-ite=true
|
||||
parens-tuple=multi-line-only
|
||||
sequence-style=terminator
|
||||
type-decl=sparse
|
||||
break-cases=toplevel
|
||||
cases-exp-indent=2
|
||||
field-space=tight-decl
|
||||
leading-nested-match-parens=true
|
||||
module-item-spacing=compact
|
||||
quiet=true
|
||||
ocaml-version=4.08.0
|
||||
|
||||
code=200, body=```
|
||||
hello reineclaude
|
||||
```
|
||||
same buf? true
|
||||
|
|
|
|||
|
|
@ -1,17 +1,44 @@
|
|||
let body = ref ""
|
||||
module H = Tiny_httpd
|
||||
|
||||
let url =
|
||||
"https://raw.githubusercontent.com/c-cube/ezcurl/refs/heads/main/.ocamlformat"
|
||||
(** Start server, return its port and a thread *)
|
||||
let start_server () : int * Thread.t =
|
||||
let port = ref (-1) in
|
||||
let cond = Condition.create () in
|
||||
let mutex = Mutex.create () in
|
||||
|
||||
let () =
|
||||
let server = H.create ~masksigpipe:true ~addr:"127.0.0.1" ~port:0 () in
|
||||
H.add_route_handler server
|
||||
H.Route.(exact "test" @/ string @/ return)
|
||||
(fun str _req ->
|
||||
H.Response.make_string ~code:200 @@ Ok (Printf.sprintf "hello %s" str));
|
||||
let th =
|
||||
Thread.create
|
||||
(H.run_exn ~after_init:(fun () ->
|
||||
port := H.port server;
|
||||
Condition.broadcast cond))
|
||||
server
|
||||
in
|
||||
|
||||
(* wait for server to start *)
|
||||
while !port < 0 do
|
||||
Mutex.lock mutex;
|
||||
Condition.wait cond mutex;
|
||||
Mutex.unlock mutex
|
||||
done;
|
||||
!port, th
|
||||
|
||||
let test1 ~port () =
|
||||
let name = "jeanjacques" in
|
||||
let url = Printf.sprintf "http://127.0.0.1:%d/test/%s" port name in
|
||||
match Ezcurl.get ~url () with
|
||||
| Error (code, msg) ->
|
||||
Format.eprintf "curl error: code `%s` (%s)@." (Curl.strerror code) msg
|
||||
| Ok res ->
|
||||
body := res.body;
|
||||
Format.printf "get: OK@.body=```@.%s@.```@." !body
|
||||
Format.printf "get: OK@.code=%d,body=```@.%s@.```@." res.code res.body
|
||||
|
||||
let () =
|
||||
let test2 ~port () =
|
||||
let name = "reineclaude" in
|
||||
let url = Printf.sprintf "http://127.0.0.1:%d/test/%s" port name in
|
||||
let buf = Buffer.create 32 in
|
||||
match
|
||||
Ezcurl.http_stream ~meth:GET ~url
|
||||
|
|
@ -24,7 +51,13 @@ let () =
|
|||
with
|
||||
| Error (code, msg) ->
|
||||
Format.eprintf "curl error: code `%s` (%s)@." (Curl.strerror code) msg
|
||||
| Ok _res ->
|
||||
| Ok res ->
|
||||
let new_body = Buffer.contents buf in
|
||||
Format.printf "streaming get: OK@.body=```@.%s@.```@." new_body;
|
||||
Format.printf "same buf? %b@." (new_body = !body)
|
||||
Format.printf "streaming get: OK@.code=%d, body=```@.%s@.```@." res.code
|
||||
new_body
|
||||
|
||||
let () =
|
||||
let port, _th = start_server () in
|
||||
test1 ~port ();
|
||||
test2 ~port ();
|
||||
exit 0
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
(test
|
||||
(name basic_test)
|
||||
(libraries ezcurl))
|
||||
(package ezcurl)
|
||||
(libraries ezcurl tiny_httpd threads.posix))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue