M lib/dhall/ast.rb => lib/dhall/ast.rb +33 -1
@@ 261,6 261,11 @@ module Dhall
with(elements: elements.each_with_index.map(&block))
end
+ def each(&block)
+ elements.each(&block)
+ self
+ end
+
def reduce(z)
elements.reverse.reduce(z) { |acc, x| yield x, acc }
end
@@ 303,6 308,10 @@ module Dhall
type.nil? ? self : with(type: type)
end
+ def each
+ self
+ end
+
def reduce(z)
z
end
@@ 678,6 687,10 @@ module Dhall
end
end
+ def to_s
+ value
+ end
+
def as_json
[18, value]
end
@@ 720,6 733,11 @@ module Dhall
fragment Either(nil, ::String)
end)
+ HeaderType = RecordType.new(record: {
+ "header" => Variable["Text"],
+ "value" => Variable["Text"]
+ })
+
def initialize(headers, authority, *path, query, fragment)
super(
headers: headers,
@@ 730,6 748,16 @@ module Dhall
)
end
+ def with(hash)
+ self.class.new(
+ hash.fetch(:headers),
+ authority,
+ *path,
+ query,
+ fragment
+ )
+ end
+
def self.from_uri(uri)
(uri.scheme == "https" ? Https : Http).new(
nil,
@@ 740,12 768,16 @@ module Dhall
)
end
+ def headers
+ super || EmptyList.new(type: HeaderType)
+ end
+
def uri
URI("#{scheme}://#{authority}/#{path.join("/")}?#{query}")
end
def as_json
- [headers.as_json, authority, *path, query, fragment]
+ [@headers.as_json, authority, *path, query, fragment]
end
end
M lib/dhall/resolve.rb => lib/dhall/resolve.rb +24 -4
@@ 21,7 21,17 @@ module Dhall
ReadHttpSources = lambda do |sources|
sources.map do |source|
Promise.resolve(nil).then do
- r = Net::HTTP.get_response(source.uri)
+ uri = source.uri
+ req = Net::HTTP::Get.new(uri)
+ source.headers.each do |header|
+ req[header.fetch("header").to_s] = header.fetch("value").to_s
+ end
+ r = Net::HTTP.start(
+ uri.hostname,
+ uri.port,
+ use_ssl: uri.scheme == "https"
+ ) { |http| http.request(req) }
+
raise ImportFailedException, source if r.code != "200"
r.body
end
@@ 128,11 138,21 @@ module Dhall
end
def resolve_http(http_source)
- @http_resolutions.register(http_source)
+ ExpressionResolver.for(http_source.headers)
+ .resolve(self).then do |headers|
+ @http_resolutions.register(
+ http_source.with(headers: headers.normalize)
+ )
+ end
end
def resolve_https(https_source)
- @https_resolutions.register(https_source)
+ ExpressionResolver.for(https_source.headers)
+ .resolve(self).then do |headers|
+ @https_resolutions.register(
+ https_source.with(headers: headers.normalize)
+ )
+ end
end
def finish!
@@ 265,7 285,7 @@ module Dhall
register_for Object
def resolve(*)
- @expr
+ Promise.resolve(@expr)
end
end
end
M test/test_resolve.rb => test/test_resolve.rb +17 -1
@@ 24,7 24,9 @@ class TestResolve < Minitest::Test
"self" => "hRgY9gADZHNlbGY",
"text" => "aGFp",
"moretext" => "hRgY9gEDZHRleHQ",
- "2text" => "hAMGhRgY9gEDZHRleHSFGBj2AANobW9yZXRleHQ"
+ "2text" => "hAMGhRgY9gEDZHRleHSFGBj2AANobW9yZXRleHQ",
+ "using" => "iRgY9gAAhRgY9gADZ2hlYWRlcnNkZS50ZGF09vY",
+ "headers" => "gwT2ggiiZmhlYWRlcoISYnRoZXZhbHVlghJidHY"
}.fetch(source.pathname.to_s)))
end
end
@@ 173,6 175,20 @@ class TestResolve < Minitest::Test
assert_equal Dhall::Variable["_"], expr.resolve(@resolver).sync
end
+ def test_headers
+ stub_request(:get, "http://e.td/t")
+ .with(headers: { "Th" => "tv" })
+ .to_return(status: 200, body: "\x00")
+
+ expr = Dhall::Import.new(
+ nil,
+ Dhall::Import::Expression,
+ Dhall::Import::RelativePath.new("using")
+ )
+
+ assert_equal Dhall::Variable["_"], expr.resolve(@resolver).sync
+ end
+
def test_ipfs
stub_request(:get, "http://localhost:8000/ipfs/TESTCID")
.to_return(status: 200, body: "\x00")