data_uri 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -5,19 +5,65 @@
5
5
  Data URIs allow resources to be embedding inside a URI. The URI::Data class
6
6
  provides support for parsing these URIs using the normal URI.parse method.
7
7
 
8
+ I wrote it to support embedding binary data inside JSON messages in a
9
+ relatively reasonable way. If you find some other use for it, please drop me
10
+ a line.
11
+
8
12
  == Usage
9
13
 
10
14
  require 'data_uri'
11
15
 
12
16
  uri = URI.parse('data:image/gif;base64,...')
13
- uri.content_type # 'image/gif
17
+ uri.content_type # image/gif
14
18
  uri.data # Base64 decoded data
15
19
 
20
+ Data URIs can play nicely with open-uri:
21
+
22
+ require 'data_uri/openuri'
23
+
24
+ open(uri) do |io|
25
+ io.content_type # image/gif
26
+ io.read # decoded data
27
+ end
28
+
29
+ There is no support for creating data URI strings, but it would be trivial to
30
+ add if anyone's interested.
31
+
32
+ == Features & Limitations
33
+
34
+ It accepts URIs with charset MIME parameters:
35
+
36
+ data:text/html;charset=utf-8,...
37
+
38
+ and if the String object has a force_encoding method, as in ruby-1.9.x, it
39
+ will call it with the value of the charset parameter on the decoded data.
40
+ Other MIME parameters are parsed and stored, but are not exposed.
41
+
42
+ The base64 pseudo-parameter must appear immediately prior to the data, as per
43
+ the RFC. Google Chrome apparently misbehaves in this regard, so if this
44
+ causes grief to anyone, yell and I'll relax the constraint. If base64 coding
45
+ is not specified, the data are URI decoded.
46
+
47
+ Some non-authoritative documentation about data URIs state that whitespace
48
+ is allowed and ignored within them. The RFC seems to contradict this
49
+ interpretation, but support seems to be widespread in the browser world.
50
+ URI::Data cannot parse URIs containing whitespace. If
51
+ this causes grief to anyone, yell and I'll either add a class method to
52
+ URI::Data for explicit relaxed parsing, and/or figure out how to convince
53
+ URI::Generic to be more open minded about the kinds of URIs it allows.
54
+
55
+ Even when using the open-uri support file, Kernel.open will not accept string
56
+ data URIs, only URI::Data objects. Open-uri is opinionated about the
57
+ formats of the URIs it will try to open, and it's ambiguous to me at least if
58
+ data URIs can necessarily be distinguished from filesystem paths on all
59
+ platforms. Again, if this causes undue pain and suffering, we can commit
60
+ minor violence to open-uri to convince it to see reason.
61
+
16
62
  == License:
17
63
 
18
64
  (The MIT License)
19
65
 
20
- Copyright (c) 2010
66
+ Copyright (c) 2010 Donald Ball <donald.ball@gmail.com>
21
67
 
22
68
  Permission is hereby granted, free of charge, to any person obtaining
23
69
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -2,9 +2,3 @@ desc "Build a gem file"
2
2
  task :build do
3
3
  system "gem build data_uri.gemspec"
4
4
  end
5
-
6
- task :default => :test
7
-
8
- task :test do
9
- system "ruby -Ilib test/test_*.rb"
10
- end
@@ -0,0 +1,22 @@
1
+ module URI
2
+
3
+ class Data
4
+
5
+ def open
6
+ io = StringIO.new(data)
7
+ OpenURI::Meta.init(io)
8
+ io.meta_add_field('content-type', content_type)
9
+ if block_given?
10
+ begin
11
+ yield io
12
+ ensure
13
+ io.close
14
+ end
15
+ else
16
+ io
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,40 @@
1
+ module URI
2
+
3
+ class Data < Generic
4
+
5
+ COMPONENT = [:scheme, :opaque].freeze
6
+ MIME_TYPE_RE = %r{^([-\w.+]+/[-\w.+]*)}.freeze
7
+ MIME_PARAM_RE = /^;([-\w.+]+)=([^;,]+)/.freeze
8
+
9
+ attr_reader :content_type, :data
10
+
11
+ def initialize(*args)
12
+ super(*args)
13
+ @data = @opaque
14
+ if md = MIME_TYPE_RE.match(@data)
15
+ @content_type = md[1]
16
+ @data = @data[@content_type.length .. -1]
17
+ end
18
+ @content_type ||= 'text/plain'
19
+ @mime_params = {}
20
+ while md = MIME_PARAM_RE.match(@data)
21
+ @mime_params[md[1]] = md[2]
22
+ @data = @data[md[0].length .. -1]
23
+ end
24
+ if base64 = /^;base64/.match(@data)
25
+ @data = @data[7 .. -1]
26
+ end
27
+ unless /^,/.match(@data)
28
+ raise 'Invalid data URI'
29
+ end
30
+ @data = @data[1 .. -1]
31
+ @data = base64 ? Base64.decode64(@data) : URI.decode(@data)
32
+ if @data.respond_to?(:force_encoding) && charset = @mime_params['charset']
33
+ @data.force_encoding(charset)
34
+ end
35
+ end
36
+ end
37
+
38
+ @@schemes['DATA'] = Data
39
+
40
+ end
data/lib/data_uri.rb CHANGED
@@ -1,24 +1,5 @@
1
1
  require 'uri'
2
2
  require 'base64'
3
+ require 'stringio'
3
4
 
4
- module URI
5
-
6
- class Data < Generic
7
-
8
- COMPONENT = [:scheme, :opaque].freeze
9
- OPAQUE_REGEXP = /^([^;]+);base64,(.+)$/.freeze
10
-
11
- attr_reader :content_type, :data
12
-
13
- def initialize(*args)
14
- super(*args)
15
- if OPAQUE_REGEXP.match(@opaque)
16
- @content_type = $1
17
- @data = Base64.decode64($2)
18
- end
19
- end
20
- end
21
-
22
- @@schemes['DATA'] = Data
23
-
24
- end
5
+ require 'data_uri/uri'
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: data_uri
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 27
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 0
8
- - 1
9
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
10
11
  platform: ruby
11
12
  authors:
12
13
  - Donald Ball
@@ -29,6 +30,8 @@ extra_rdoc_files:
29
30
  files:
30
31
  - README.rdoc
31
32
  - Rakefile
33
+ - lib/data_uri/open_uri.rb
34
+ - lib/data_uri/uri.rb
32
35
  - lib/data_uri.rb
33
36
  has_rdoc: true
34
37
  homepage: http://github.com/dball/data_uri
@@ -44,6 +47,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
44
47
  requirements:
45
48
  - - ">="
46
49
  - !ruby/object:Gem::Version
50
+ hash: 3
47
51
  segments:
48
52
  - 0
49
53
  version: "0"
@@ -52,6 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
56
  requirements:
53
57
  - - ">="
54
58
  - !ruby/object:Gem::Version
59
+ hash: 3
55
60
  segments:
56
61
  - 0
57
62
  version: "0"