roger_w3cvalidator 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MDRjZTczMWJiZTczZjI1MzkxYjZlYmFiZjU0NTJiMzgyNWY3OGM0MQ==
5
+ data.tar.gz: !binary |-
6
+ Mjg5NmVhYWE2ZmQ3NzU4ZDQ4OTJlY2QxODgwYzllZmQ2OTcyZDkyMQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YzgzZWIyOTY2YjA3YTA3N2E1ZGFmYzlhNzNlMDYwYWYyNGY3MGU2YThjZjRl
10
+ YTU5ZDYxMGNmMjI1OWNkMDUwNjI3MWYxM2NmOTRhZjU5Njk3YmQ4MjAyOGNk
11
+ Y2ZjMDAzNTY1ZWViODk4Mzc5NTZjODUxNmI4MmRjODEzNDFjZjE=
12
+ data.tar.gz: !binary |-
13
+ NWE4NTgzYjhkZmY5NWY5OTE4MjQ5ZWFiNGVjNjkzZjAyM2QzMzVjNjRhOTE2
14
+ MzIwYTlkYjdhMGQyM2ZkOTM5NTk1ZDRiNGMxZDFkYmQ1MGE0MDBhODUxYzMw
15
+ NmM4ZmIyZjFiNzAwMzZhNzQwYzFiMzI3YjFjY2M5ZWVmYzQ3ZWY=
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ # Changelog
2
+
3
+ ## Version 1.0.0
4
+ * First version extracted from Roger
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 DigitPaint
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # Roger W3CValidator
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/roger_w3cvalidator.png)](http://badge.fury.io/rb/roger_w3cvalidator)
4
+
5
+ W3CValidator consists of two parts:
6
+
7
+ * Middleware (`RogerW3cvalidator::Middleware`) to validate each HTML request (quite slow)
8
+ * Test to use on your mockup
9
+
10
+ ## Changes and versions
11
+
12
+ Have a look at the [CHANGELOG](CHANGELOG.md) to see what's new.
13
+
14
+ ## Contributors
15
+
16
+ [View contributors](https://github.com/digitpaint/roger_w3cvalidator/graphs/contributors)
17
+
18
+ ## License
19
+
20
+ MIT License, see [LICENSE](LICENSE) for more info.
@@ -0,0 +1,5 @@
1
+ module RogerW3cvalidator; end
2
+
3
+ # Load modules
4
+ require File.dirname(__FILE__) + "/roger_w3cvalidator/test"
5
+ require File.dirname(__FILE__) + "/roger_w3cvalidator/middleware"
@@ -0,0 +1,25 @@
1
+ require 'rack/request'
2
+ require 'rack/response'
3
+ require File.dirname(__FILE__) + "/w3c_validator"
4
+
5
+ module RogerW3cvalidator
6
+ class Middleware
7
+ def initialize(app)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ resp = @app.call(env)
13
+ if resp[1]["Content-Type"].to_s.include?("html")
14
+ str = ""
15
+ resp[2].each{|c| str << c}
16
+ validator = W3CValidator.new(str)
17
+ validator.validate!
18
+ if !validator.valid
19
+ env["rack.errors"].puts "Validation failed on #{env["PATH_INFO"]}: (errors: #{validator.errors}, warnings: #{validator.warnings})"
20
+ end
21
+ end
22
+ resp
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,42 @@
1
+ require 'roger/test'
2
+ require File.dirname(__FILE__) + "/w3c_validator"
3
+
4
+ module RogerW3cvalidator
5
+ class Test
6
+
7
+ def initialize(options={})
8
+ @options = {
9
+ :match => ["html/**/*.html"],
10
+ :skip => []
11
+ }
12
+ @options.update(options) if options
13
+ end
14
+
15
+ def call(test, options={})
16
+ options = {}.update(@options).update(options)
17
+
18
+ test.log(self, "Validating all files matching #{options[:match].inspect}")
19
+
20
+ success = true
21
+ test.get_files(options[:match], options[:skip]).each do |file_path|
22
+ validator = W3CValidator.new(File.read(file_path))
23
+ validator.validate!
24
+ if !validator.valid
25
+ test.log(self, "#{file_path} is invalid (errors: #{validator.errors}, warnings: #{validator.warnings})") do
26
+ validator.response["messages"].each do |message|
27
+ test.debug(self, message["message"])
28
+ end
29
+ end
30
+ success = false
31
+ else
32
+ test.debug(self, "#{file_path} is valid")
33
+ end
34
+ end
35
+
36
+ success
37
+ end
38
+
39
+ end
40
+ end
41
+
42
+ Roger::Test.register :w3cvalidator, RogerW3cvalidator::Test
@@ -0,0 +1,129 @@
1
+ require 'cgi'
2
+ require 'net/http'
3
+ require 'uri'
4
+ require 'yaml'
5
+
6
+ module RogerW3cvalidator
7
+ class W3CValidator
8
+
9
+ ValidationUri = "http://validator.w3.org/check"
10
+
11
+ class RequestError < StandardError; end
12
+
13
+ attr_reader :valid,:response,:errors,:warnings,:status
14
+
15
+ class << self
16
+ def validation_uri
17
+ @uri ||= URI.parse(ValidationUri)
18
+ end
19
+ end
20
+
21
+ def initialize(html)
22
+ @html = html
23
+ end
24
+
25
+ def validate!
26
+ @status = @warnings = @errors = @response = @valid = nil
27
+ options = {"output" => "json"}
28
+ query,headers = build_post_query(options)
29
+ response = self.request(:post, self.class.validation_uri.path,query,headers)
30
+ @status,@warnings,@errors = response["x-w3c-validator-status"],response["x-w3c-validator-warnings"].to_i,response["x-w3c-validator-errors"].to_i
31
+
32
+ if @status == "Valid" && @warnings == 0 && @errors == 0
33
+ return @valid = true
34
+ else
35
+ begin
36
+ @response = YAML.load(response.body)
37
+ rescue
38
+ end
39
+ return (@valid = (@errors == 0))
40
+ end
41
+
42
+ end
43
+
44
+ protected
45
+
46
+ def build_post_query(options)
47
+ boundary = "validate-this-content-please"
48
+ headers = {"Content-type" => "multipart/form-data, boundary=" + boundary + " "}
49
+
50
+ parts = []
51
+ options.each do |k,v|
52
+ parts << post_param(k,v)
53
+ end
54
+ parts << file_param("uploaded_file","index.html",@html,"text/html")
55
+
56
+ q = parts.map{|p| "--#{boundary}\r\n#{p}"}.join("") + "--#{boundary}--"
57
+ [q,headers]
58
+ end
59
+
60
+ def post_param(k,v)
61
+ "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"\r\n\r\n#{v}\r\n"
62
+ end
63
+
64
+ def file_param(k,filename,content,mime_type)
65
+ out = []
66
+ out << "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"; filename=\"#{filename}\""
67
+ out << "Content-Transfer-Encoding: binary"
68
+ out << "Content-Type: #{mime_type}"
69
+ out.join("\r\n") + "\r\n\r\n" + content + "\r\n"
70
+ end
71
+
72
+ # Makes request to remote service.
73
+ def request(method, path, *arguments)
74
+ perform_request(method, path, arguments, 3)
75
+ end
76
+
77
+ def perform_request(method, path, arguments, tries=3)
78
+ result = nil
79
+ result = http.send(method, path, *arguments)
80
+ handle_response(result)
81
+ rescue RequestError => e
82
+ if tries > 0
83
+ perform_request(method, path, arguments, tries-1)
84
+ else
85
+ raise
86
+ end
87
+ rescue Timeout::Error => e
88
+ raise
89
+ end
90
+
91
+ # Handles response and error codes from remote service.
92
+ def handle_response(response)
93
+ case response.code.to_i
94
+ when 301,302
95
+ raise "Redirect"
96
+ when 200...400
97
+ response
98
+ when 400
99
+ raise "Bad Request"
100
+ when 401
101
+ raise "Unauthorized Access"
102
+ when 403
103
+ raise "Forbidden Access"
104
+ when 404
105
+ raise "Rescoure not found"
106
+ when 405
107
+ raise "Method not allowed"
108
+ when 409
109
+ raise RequestError.new("Rescource conflict")
110
+ when 422
111
+ raise RequestError.new("Resource invalid")
112
+ when 401...500
113
+ raise "Client error"
114
+ when 500...600
115
+ raise RequestError.new("Server error")
116
+ else
117
+ raise "Unknown response: #{response.code.to_i}"
118
+ end
119
+ end
120
+
121
+ def http
122
+ site = self.class.validation_uri
123
+ http = Net::HTTP.new(site.host, site.port)
124
+ # http.use_ssl = site.is_a?(URI::HTTPS)
125
+ # http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl
126
+ http
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "roger_w3cvalidator"
5
+ s.version = "0.1.0"
6
+
7
+ s.authors = ["Flurin Egger"]
8
+ s.email = ["info@digitpaint.nl", "flurin@digitpaint.nl"]
9
+ s.homepage = "http://github.com/digitpaint/roger_w3cvalidator"
10
+ s.summary = "Middleware and Tester to validate your HTML within Roger"
11
+ s.licenses = ["MIT"]
12
+
13
+ s.date = Time.now.strftime("%Y-%m-%d")
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
21
+
22
+ s.add_dependency("rack", [">= 1.0.0"])
23
+ s.add_dependency("roger", [">= 0.11.0"])
24
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: roger_w3cvalidator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Flurin Egger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: roger
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.11.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 0.11.0
41
+ description:
42
+ email:
43
+ - info@digitpaint.nl
44
+ - flurin@digitpaint.nl
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - CHANGELOG.md
50
+ - LICENSE
51
+ - README.md
52
+ - lib/roger_w3cvalidator.rb
53
+ - lib/roger_w3cvalidator/middleware.rb
54
+ - lib/roger_w3cvalidator/test.rb
55
+ - lib/roger_w3cvalidator/w3c_validator.rb
56
+ - roger_w3cvalidator.gemspec
57
+ homepage: http://github.com/digitpaint/roger_w3cvalidator
58
+ licenses:
59
+ - MIT
60
+ metadata: {}
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubyforge_project:
77
+ rubygems_version: 2.1.5
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: Middleware and Tester to validate your HTML within Roger
81
+ test_files: []