Module: Cloudflare::HTTP
- Defined in:
- lib/cloudflare_workers/http.rb
Constant Summary collapse
- DEFAULT_HEADERS =
{}.freeze
Class Method Summary collapse
-
.fetch(url, method: 'GET', headers: nil, body: nil) ⇒ Object
Issue an HTTP request via globalThis.fetch.
-
.js_headers_to_hash(js_headers) ⇒ Object
Internal: convert JS Headers / iterable to Ruby Hash with lowercased string keys.
-
.ruby_headers_to_js(hash) ⇒ Object
Convert a Ruby Hash<String, String> into a plain JS object usable as the ‘headers` init for fetch().
Class Method Details
.fetch(url, method: 'GET', headers: nil, body: nil) ⇒ Object
Issue an HTTP request via globalThis.fetch.
res = Cloudflare::HTTP.fetch('https://api.example.com/users',
method: 'POST',
headers: { 'content-type' => 'application/json' },
body: { name: 'kazu' }.to_json).__await__
res.status # => 200
res.json # => { 'id' => 1, 'name' => 'kazu' }
The whole response body is awaited and returned as a String. Use ‘Cloudflare::HTTPResponse#body` to access raw text.
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 |
# File 'lib/cloudflare_workers/http.rb', line 70 def self.fetch(url, method: 'GET', headers: nil, body: nil) hdrs = headers || DEFAULT_HEADERS method_str = method.to_s.upcase js_headers = ruby_headers_to_js(hdrs) js_body = body.nil? ? nil : body.to_s url_str = url.to_s response_klass = Cloudflare::HTTPResponse err_klass = Cloudflare::HTTPError headers_to_hash = method(:js_headers_to_hash) _ = headers_to_hash # silence opal lint # NOTE: the multi-line backtick below returns a Promise BECAUSE it # is assigned to `js_promise` (and `js_promise.__await__` awaits # it). Opal treats a multi-line x-string as a statement, not an # expression — safe when assigned, but a bare multi-line backtick # at end-of-method silently drops the Promise. Do NOT refactor # this into `def fetch ... end` with the backtick as the last # expression. See the single-line IIFE pattern used in # lib/cloudflare_workers/{cache,queue,durable_object}.rb#put for # the alternative that survives either position. (Phase 11B audit.) js_promise = ` (async function() { var init = { method: #{method_str}, headers: #{js_headers}, redirect: 'follow' }; if (#{js_body} !== nil && #{js_body} != null) { init.body = #{js_body}; } var resp; try { resp = await globalThis.fetch(#{url_str}, init); } catch (e) { #{Kernel}.$$raise(#{err_klass}.$new(e.message || String(e), Opal.hash({ url: #{url_str}, method: #{method_str} }))); } var text = ''; try { text = await resp.text(); } catch (e) { text = ''; } var hash_keys = []; var hash_vals = []; if (resp.headers && typeof resp.headers.forEach === 'function') { resp.headers.forEach(function(value, key) { hash_keys.push(String(key).toLowerCase()); hash_vals.push(String(value)); }); } return { status: resp.status|0, text: text, hkeys: hash_keys, hvals: hash_vals }; })() ` js_result = js_promise.__await__ hkeys = `#{js_result}.hkeys` hvals = `#{js_result}.hvals` h = {} i = 0 len = `#{hkeys}.length` while i < len h[`#{hkeys}[#{i}]`] = `#{hvals}[#{i}]` i += 1 end response_klass.new( status: `#{js_result}.status`, headers: h, body: `#{js_result}.text`, url: url_str ) end |
.js_headers_to_hash(js_headers) ⇒ Object
Internal: convert JS Headers / iterable to Ruby Hash with lowercased string keys. Currently inlined in fetch() but exposed for completeness.
152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/cloudflare_workers/http.rb', line 152 def self.js_headers_to_hash(js_headers) h = {} ` if (#{js_headers} && typeof #{js_headers}.forEach === 'function') { #{js_headers}.forEach(function(value, key) { #{h}.$$smap[String(key).toLowerCase()] = String(value); }); } ` h end |
.ruby_headers_to_js(hash) ⇒ Object
Convert a Ruby Hash<String, String> into a plain JS object usable as the ‘headers` init for fetch().
139 140 141 142 143 144 145 146 147 |
# File 'lib/cloudflare_workers/http.rb', line 139 def self.ruby_headers_to_js(hash) js_obj = `{}` hash.each do |k, v| ks = k.to_s vs = v.to_s `#{js_obj}[#{ks}] = #{vs}` end js_obj end |