crystal-community / cossack Goto Github PK
View Code? Open in Web Editor NEWSimple and flexible HTTP client for Crystal with middleware and test support.
License: GNU Lesser General Public License v3.0
Simple and flexible HTTP client for Crystal with middleware and test support.
License: GNU Lesser General Public License v3.0
Hi! Is there a way to specify Cossack Middleware to inject to every Cossack client?
Use cases:
spec_helper.cr
When dealing with intranet resources - it is very annoying for OS administrators to push internal CA certificates as "trusted" to all clients. Our administrators not too lazy, but they cant do this properly too.
It will be nice if cossack will provide some parameter like ssl_params, which can be used to turn-off server SSL certificate validation.
Thank you!
crystal version: Crystal 0.17.4 (2016-05-26)
shards.yml:
dependencies:
cossack:
github: greyblake/crystal-cossack
cr file:
require "cossack"
cossack = Cossack.new
How do you think about parallel requests feature?
faraday:
https://github.com/lostisland/faraday/wiki/Parallel-requests
curb:
https://github.com/taf2/curb#multi-interface-basic-http-get
Hi -
I'm having a bit of trouble using the simple get example listed.
response = Cossack.get("http://doomy.tumblr.com/api/read/json")
returns a status of 301.
However, this works correctly.
cossack = Cossack::Client.new do |client|
# follow up to 10 redirections (by default 5)
client.use Cossack::RedirectionMiddleware, limit: 10
end
return cossack.get("http://doomy.tumblr.com/api/read/json")
Is this intended? I would like to use the simple Cossack.get
static method as I don't need to configure anything, however it gives me a 301 instead of following the redirect.
Running make test
with the latest upgrade to the crystal language (v0.19.0) results in a syntax error. It appears to original from the breaking change to remove the x as Y
syntax, noted in the release notes.
Error message:
crystal spec $(find ./spec/unit/ -name '*_spec.cr')
Error in line 1: while requiring "././spec/unit//client_spec.cr"
in ./spec/unit/client_spec.cr:1: while requiring "../spec_helper"
require "../spec_helper"
^
in ./spec/spec_helper.cr:4: while requiring "../src/cossack"
require "../src/cossack"
^
in ./src/cossack.cr:4: while requiring "./cossack/**"
require "./cossack/**"
^
in ./src/cossack/client.cr:47: macro didn't expand to a valid program, it expanded to:
================================================================================
--------------------------------------------------------------------------------
1.
2. def get(url : String, params : Params? = nil) : Response
3. get(url, params) { }
4. end
5.
6. def get(url : String, params : Params? = nil) : Response
7. uri = complete_uri!(URI.parse(url))
8.
9. if params
10. query = HTTP::Params.build do |form|
11. (params as Params).each { |name, val| form.add(name, val) }
12. end
13. if uri.query
14. uri.query = [uri.query, query].join("&")
15. else
16. uri.query = query
17. end
18. end
19.
20. request = Request.new("GET", uri, @headers.dup, options: @request_options.dup)
21. yield(request)
22. call(request)
23. end
24.
25. def delete(url : String, params : Params? = nil) : Response
26. delete(url, params) { }
27. end
28.
29. def delete(url : String, params : Params? = nil) : Response
30. uri = complete_uri!(URI.parse(url))
31.
32. if params
33. query = HTTP::Params.build do |form|
34. (params as Params).each { |name, val| form.add(name, val) }
35. end
36. if uri.query
37. uri.query = [uri.query, query].join("&")
38. else
39. uri.query = query
40. end
41. end
42.
43. request = Request.new("DELETE", uri, @headers.dup, options: @request_options.dup)
44. yield(request)
45. call(request)
46. end
47.
48. def head(url : String, params : Params? = nil) : Response
49. head(url, params) { }
50. end
51.
52. def head(url : String, params : Params? = nil) : Response
53. uri = complete_uri!(URI.parse(url))
54.
55. if params
56. query = HTTP::Params.build do |form|
57. (params as Params).each { |name, val| form.add(name, val) }
58. end
59. if uri.query
60. uri.query = [uri.query, query].join("&")
61. else
62. uri.query = query
63. end
64. end
65.
66. request = Request.new("HEAD", uri, @headers.dup, options: @request_options.dup)
67. yield(request)
68. call(request)
69. end
70.
71. def options(url : String, params : Params? = nil) : Response
72. options(url, params) { }
73. end
74.
75. def options(url : String, params : Params? = nil) : Response
76. uri = complete_uri!(URI.parse(url))
77.
78. if params
79. query = HTTP::Params.build do |form|
80. (params as Params).each { |name, val| form.add(name, val) }
81. end
82. if uri.query
83. uri.query = [uri.query, query].join("&")
84. else
85. uri.query = query
86. end
87. end
88.
89. request = Request.new("OPTIONS", uri, @headers.dup, options: @request_options.dup)
90. yield(request)
91. call(request)
92. end
93.
--------------------------------------------------------------------------------
Syntax error in expanded macro: macro_4395676992:11: unterminated parenthesized expression
(params as Params).each { |name, val| form.add(name, val) }
^
================================================================================
{% for method in %w(get delete head options) %}
^
Run:
#<Cossack::Request:0x55bb428007c0 @method="GET", @uri=#<URI:0x55bb42801360 @scheme="http", @host="172.16.123.129", @port=nil, @path="", @query=nil, @user=nil, @password=nil, @fragment=nil, @opaque=nil>, @headers=HTTP::Headers{"User-Agent" => "Cossack v0.1.4"}, @body=nil, @options=#<Cossack::RequestOptions:0x55bb42807d60 @connect_timeout=30.0, @read_timeout=30.0>>
Redirect:
#<Cossack::Request:0x55bb42800240 @method="GET", @uri=#<URI:0x55bb42801000 @scheme="http", @host="172.16.123.129http", @port=nil, @path="/172.16.123.129", @query=nil, @user=nil, @password=nil, @fragment=nil, @opaque=nil>, @headers=HTTP::Headers{"User-Agent" => "Cossack v0.1.4"}, @body=nil, @options=#<Cossack::RequestOptions:0x55bb42807d60 @connect_timeout=30.0, @read_timeout=30.0>>
I had to overload
class HTTPConnection < Connection
def call(request : Request) : Response
And add prints there to track it down
The Crystal standard library doesn't contain support for proxy servers. It seems like this would be a great thing for cossack to support. Any plans to add it?
Here's the discussion in the crystal-lang repo with a reference implementation:
Thanks!
Nick
I'm attempting to record & replay HTTP interactions using Hi8 and Cossack. Hi8 ends up recording the request with the scheme and host "doubled". E.g., "https://api.fixer.io/latest"
becomes "https://api.fixer.iohttps://api.fixer.io/latest"
. See Hi8 issue #2 for details.
I've traced it all the way back to Cossack's HTTPConnection#call
where in http_connection.cr:5 it first creates the HTTP::Client
by passing in the request.uri
, then in http_connection.cr:9 it once again passes the full request.uri.to_s
to HTTP::Client#exec(method : String, path, headers, body)
which expects only the path component.
class HTTPConnection < Connection
def call(request : Request) : Response
client = HTTP::Client.new(request.uri)
client.connect_timeout = request.options.connect_timeout
client.read_timeout = request.options.read_timeout
http_response = client.exec(request.method, request.uri.to_s, request.headers, request.body)
Cossack should only pass in the trailing URI path and query components into the HTTP::Client#exec()
call.
When HI8 code calls @request.resource.to_s
(episode.cr:47), it should only get the path component of the URI.
Because Cossack passes in the full URI, when HI8 calls @request.resource.to_s
it returns the full URI. HI8 then appends that to the request header (which already contains the scheme and host components), which leads to the "doubling" of the URI base URL.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.