Module: URI

Defined in:
lib/opal_patches.rb

Defined Under Namespace

Classes: Error, Generic, InvalidURIError, Parser

Constant Summary collapse

DEFAULT_PARSER =
Module.new do
  UNSAFE = Regexp.compile('[^\-_.!~*\'()a-zA-Z0-9;/?:@&=+$,\[\]]').freeze

  def self.regexp
    { UNSAFE: UNSAFE }
  end

  def self.escape(s, unsafe = UNSAFE)
    CGI.escape(s.to_s)
  end

  def self.unescape(s)
    CGI.unescape(s.to_s)
  end
end
RFC2396_PARSER =
DEFAULT_PARSER

Class Method Summary collapse

Class Method Details

.decode_www_form_component(str, _enc = nil) ⇒ Object

CRuby’s URI.decode_www_form_component / encode_www_form_component are used by Rack::Utils#unescape / Rack::Utils#escape. Opal’s ‘uri` stdlib omits them. Back them with CGI so that Rack’s query-string parser works for any request with a body / query (Sinatra’s ‘request.body.read` path eventually walks through this code).

IMPORTANT (Opal): CGI.unescape maps to JS decodeURI, which does NOT decode ‘%2F` (`/`). RFC 3986 decodeURI reserves those escapes; Rack form bodies need decodeURIComponent semantics (same as CGI.unescapeURIComponent). Without this, HTML like `</h1>` survives as literal `<%2Fh1>` in params.



258
259
260
261
262
263
# File 'lib/opal_patches.rb', line 258

def self.decode_www_form_component(str, _enc = nil)
  s = str.to_s.tr('+', ' ')
  CGI.unescapeURIComponent(s)
rescue ::Exception
  str.to_s
end

.encode_www_form_component(str, _enc = nil) ⇒ Object



266
267
268
# File 'lib/opal_patches.rb', line 266

def self.encode_www_form_component(str, _enc = nil)
  CGI.escape(str.to_s)
end

.HTTP_class_for(scheme) ⇒ Object

Net::HTTP.get(URI(‘https://…’)) is the canonical entry point in CRuby Ruby code. CRuby resolves ‘URI(’…‘)` via Kernel#URI, which is defined in `uri/common.rb` as `URI.parse(arg)`. Opal’s stdlib omits that; install it here so vendored gems (and our Net::HTTP shim) can use the idiomatic short form.



349
350
351
# File 'lib/opal_patches.rb', line 349

def self.HTTP_class_for(scheme)
  HTTP if scheme == 'http'
end

.parse(str) ⇒ Object



311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/opal_patches.rb', line 311

def self.parse(str)
  s = str.to_s
  return Generic.new(host: nil, scheme: nil, port: nil, path: '', query: nil, fragment: nil) if s.empty?

  js_url = `
    (function() {
      try { return new URL(#{s}); }
      catch (e) {
        try { return new URL(#{s}, "http://__homura.invalid/"); }
        catch (e2) { return null; }
      }
    })()
  `
  raise ::URI::InvalidURIError, "bad URI(is not URI?): #{s}" if `#{js_url} == null`

  host     = `#{js_url}.host` || ''
  host     = nil if host == '' || host.include?('__homura.invalid')
  scheme   = `#{js_url}.protocol` || ''
  scheme   = scheme.sub(/:$/, '')
  scheme   = nil if scheme == ''
  port_raw = `#{js_url}.port` || ''
  port     = port_raw == '' ? nil : port_raw.to_i
  path     = `#{js_url}.pathname` || ''
  query    = `#{js_url}.search` || ''
  query    = query.sub(/^\?/, '')
  query    = nil if query == ''
  frag     = `#{js_url}.hash` || ''
  frag     = frag.sub(/^#/, '')
  frag     = nil if frag == ''

  Generic.new(host: host, scheme: scheme, port: port, path: path, query: query, fragment: frag)
end