waitress-core 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -4
  3. data/LICENSE +21 -21
  4. data/Rakefile +13 -13
  5. data/bin/waitress +22 -22
  6. data/ext/Thanks.md +1 -1
  7. data/ext/waitress_http11/ext_help.h +15 -15
  8. data/ext/waitress_http11/extconf.rb +6 -6
  9. data/ext/waitress_http11/http11.c +532 -532
  10. data/ext/waitress_http11/http11_parser.c +1216 -1216
  11. data/ext/waitress_http11/http11_parser.h +49 -49
  12. data/ext/waitress_http11/http11_parser.java.rl +171 -171
  13. data/ext/waitress_http11/http11_parser.rl +165 -165
  14. data/ext/waitress_http11/http11_parser_common.rl +55 -55
  15. data/ext/waitress_http11/http11_wrb_parser.h +91 -91
  16. data/lib/waitress/chef.rb +113 -113
  17. data/lib/waitress/configure.rb +121 -121
  18. data/lib/waitress/evalbind.rb +9 -9
  19. data/lib/waitress/handlers/dirhandler.rb +39 -39
  20. data/lib/waitress/handlers/handler.rb +57 -57
  21. data/lib/waitress/handlers/handler404.rb +25 -25
  22. data/lib/waitress/handlers/libhandler.rb +58 -58
  23. data/lib/waitress/kernel.rb +182 -182
  24. data/lib/waitress/parse/query.rb +60 -60
  25. data/lib/waitress/request.rb +45 -45
  26. data/lib/waitress/resources/default_config.rb +52 -52
  27. data/lib/waitress/resources/http/404.html +18 -18
  28. data/lib/waitress/resources/http/css/hack.css +37 -37
  29. data/lib/waitress/resources/http/css/waitress.css +57 -57
  30. data/lib/waitress/resources/http/fonts/svg/latin/hack-bold-latin-webfont.svg +240 -240
  31. data/lib/waitress/resources/http/fonts/svg/latin/hack-bolditalic-latin-webfont.svg +240 -240
  32. data/lib/waitress/resources/http/fonts/svg/latin/hack-italic-latin-webfont.svg +240 -240
  33. data/lib/waitress/resources/http/fonts/svg/latin/hack-regular-latin-webfont.svg +240 -240
  34. data/lib/waitress/resources/http/index.html +15 -15
  35. data/lib/waitress/response.rb +105 -105
  36. data/lib/waitress/server.rb +161 -158
  37. data/lib/waitress/util.rb +707 -707
  38. data/lib/waitress/version.rb +3 -3
  39. data/lib/waitress/vhost.rb +217 -217
  40. data/lib/waitress.rb +106 -106
  41. data/lib/waitress_http11.so +0 -0
  42. data/waitress-core.gemspec +29 -29
  43. metadata +3 -3
  44. data/lib/waitress_http11.bundle +0 -0
@@ -1,60 +1,60 @@
1
- module Waitress
2
- # A lot of this class uses methods from Rack::QueryParser in order to Parse
3
- # a given QueryString into a Hash of key/value pairs
4
- class QueryParser
5
- require 'uri'
6
-
7
- DEFAULT_SEP = /[&;] */n
8
-
9
- # Unescape a HTTP URL to regular text. e.g. %20 becomes a space (" ")
10
- def self.unescape str, enc=Encoding::UTF_8
11
- URI.decode_www_form_component(str, enc)
12
- end
13
-
14
- # Parse the given QueryString into a hash of key/value pairs
15
- def self.parse qs
16
- return {} if qs.nil? || qs.empty?
17
- results = {}
18
- (qs || '').split(DEFAULT_SEP).each do |p|
19
- k, v = p.split('='.freeze, 2).map! { |s| unescape(s) }
20
-
21
- normalize results, k, v
22
- end
23
- results
24
- end
25
-
26
- def self.normalize hash, name, v
27
- name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
28
- k = $1 || ''
29
- after = $' || ''
30
-
31
- return if k.empty?
32
-
33
- if after == ""
34
- hash[k] = v
35
- elsif after == "["
36
- hash[name] = v
37
- elsif after == "[]"
38
- hash[k] ||= []
39
- raise TypeError, "expected Array (got #{hash[k].class.name}) for param `#{k}'" unless hash[k].is_a?(Array)
40
- hash[k] << v
41
- elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
42
- child_key = $1
43
- hash[k] ||= []
44
- raise TypeError, "expected Array (got #{hash[k].class.name}) for param `#{k}'" unless hash[k].is_a?(Array)
45
- if hash[k].last.is_a?(Hash) && !hash[k].last.key?(child_key)
46
- normalize(hash[k].last, child_key, v)
47
- else
48
- hash[k] << normalize({}, child_key, v)
49
- end
50
- else
51
- hash[k] ||= {}
52
- raise TypeError, "expected Hash (got #{hash[k].class.name}) for param `#{k}'" unless hash[k].is_a?(Hash)
53
- hash[k] = normalize(hash[k], after, v)
54
- end
55
-
56
- hash
57
- end
58
-
59
- end
60
- end
1
+ module Waitress
2
+ # A lot of this class uses methods from Rack::QueryParser in order to Parse
3
+ # a given QueryString into a Hash of key/value pairs
4
+ class QueryParser
5
+ require 'uri'
6
+
7
+ DEFAULT_SEP = /[&;] */n
8
+
9
+ # Unescape a HTTP URL to regular text. e.g. %20 becomes a space (" ")
10
+ def self.unescape str, enc=Encoding::UTF_8
11
+ URI.decode_www_form_component(str, enc)
12
+ end
13
+
14
+ # Parse the given QueryString into a hash of key/value pairs
15
+ def self.parse qs
16
+ return {} if qs.nil? || qs.empty?
17
+ results = {}
18
+ (qs || '').split(DEFAULT_SEP).each do |p|
19
+ k, v = p.split('='.freeze, 2).map! { |s| unescape(s) }
20
+
21
+ normalize results, k, v
22
+ end
23
+ results
24
+ end
25
+
26
+ def self.normalize hash, name, v
27
+ name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
28
+ k = $1 || ''
29
+ after = $' || ''
30
+
31
+ return if k.empty?
32
+
33
+ if after == ""
34
+ hash[k] = v
35
+ elsif after == "["
36
+ hash[name] = v
37
+ elsif after == "[]"
38
+ hash[k] ||= []
39
+ raise TypeError, "expected Array (got #{hash[k].class.name}) for param `#{k}'" unless hash[k].is_a?(Array)
40
+ hash[k] << v
41
+ elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
42
+ child_key = $1
43
+ hash[k] ||= []
44
+ raise TypeError, "expected Array (got #{hash[k].class.name}) for param `#{k}'" unless hash[k].is_a?(Array)
45
+ if hash[k].last.is_a?(Hash) && !hash[k].last.key?(child_key)
46
+ normalize(hash[k].last, child_key, v)
47
+ else
48
+ hash[k] << normalize({}, child_key, v)
49
+ end
50
+ else
51
+ hash[k] ||= {}
52
+ raise TypeError, "expected Hash (got #{hash[k].class.name}) for param `#{k}'" unless hash[k].is_a?(Hash)
53
+ hash[k] = normalize(hash[k], after, v)
54
+ end
55
+
56
+ hash
57
+ end
58
+
59
+ end
60
+ end
@@ -1,45 +1,45 @@
1
- module Waitress
2
- # The request class is used to represent a HTTP request by a client. This includes
3
- # all the headers sent to the server by the client, request URI and those properties
4
- # parsed by Mongrel, including the Path and QueryString. GET and POST queries are to
5
- # be parsed on-request by the handler or .wrb file as to not waste CPU resources.
6
- class Request
7
-
8
- attr_accessor :method
9
- attr_accessor :path
10
- attr_accessor :uri
11
- attr_accessor :querystring
12
- attr_accessor :http_version
13
- attr_accessor :body
14
- attr_accessor :headers
15
-
16
- def initialize method, path, uri, query, http_version, body, headers
17
- @method = method
18
- @path = Waitress::QueryParser.unescape(path)
19
- @uri = Waitress::QueryParser.unescape(uri)
20
- @querystring = query
21
- @http_version = http_version
22
- @body = body
23
- @headers = headers
24
- @marks = {}
25
- end
26
-
27
- # The GET query for the request in the form of a hash. This is parsed on-request
28
- def get_query
29
- @get ||= Waitress::QueryParser.parse(@querystring)
30
- @get
31
- end
32
-
33
- # The POST query for the request in the form of a hash. This is parsed on-request
34
- def post_query
35
- @post ||= Waitress::QueryParser.parse(@body)
36
- @post
37
- end
38
-
39
- def to_s
40
- m = lambda { |a,x| x.nil? ? "" : "#{a}=#{x.inspect}" }
41
- "#<#{self.class} method=#{@method} path=#{@path} #{m.call("query", @query)}>"
42
- end
43
-
44
- end
45
- end
1
+ module Waitress
2
+ # The request class is used to represent a HTTP request by a client. This includes
3
+ # all the headers sent to the server by the client, request URI and those properties
4
+ # parsed by Mongrel, including the Path and QueryString. GET and POST queries are to
5
+ # be parsed on-request by the handler or .wrb file as to not waste CPU resources.
6
+ class Request
7
+
8
+ attr_accessor :method
9
+ attr_accessor :path
10
+ attr_accessor :uri
11
+ attr_accessor :querystring
12
+ attr_accessor :http_version
13
+ attr_accessor :body
14
+ attr_accessor :headers
15
+
16
+ def initialize method, path, uri, query, http_version, body, headers
17
+ @method = method
18
+ @path = Waitress::QueryParser.unescape(path)
19
+ @uri = Waitress::QueryParser.unescape(uri)
20
+ @querystring = query
21
+ @http_version = http_version
22
+ @body = body
23
+ @headers = headers
24
+ @marks = {}
25
+ end
26
+
27
+ # The GET query for the request in the form of a hash. This is parsed on-request
28
+ def get_query
29
+ @get ||= Waitress::QueryParser.parse(@querystring)
30
+ @get
31
+ end
32
+
33
+ # The POST query for the request in the form of a hash. This is parsed on-request
34
+ def post_query
35
+ @post ||= Waitress::QueryParser.parse(@body)
36
+ @post
37
+ end
38
+
39
+ def to_s
40
+ m = lambda { |a,x| x.nil? ? "" : "#{a}=#{x.inspect}" }
41
+ "#<#{self.class} method=#{@method} path=#{@path} #{m.call("query", @query)}>"
42
+ end
43
+
44
+ end
45
+ end
@@ -1,52 +1,52 @@
1
- # This is the configuration for your waitress server, accepting connections on port '2910'
2
- Waitress.configure!(2910) do |w|
3
-
4
- # You can run regular Ruby Code in here, too!
5
- @home = "~/.waitress/www/"
6
- def fl file
7
- File.join(@home, file)
8
- end
9
-
10
- # This is your main Virtual Host, accepting connections to 'example.mysite.com'
11
- w.host(/example.mysite.com/) do |host|
12
- # This is where your public documents and pages are stored
13
- host.root fl("example/http")
14
-
15
- # This is where your non-public includes are stored
16
- host.includes fl("example/rb")
17
-
18
- # This will show up when a 404 error occurs
19
- # host.set_404 fl("example/http/404.html")
20
-
21
- # Want to rewrite a URL? No problem.
22
- host.rewrite /some_url/, "some_other_url"
23
- host.rewrite /capture_group_(\d)/, "capture/group\\1"
24
-
25
- # Bind_Lib will allow you to automatically import lib tags into .wrb files
26
- # Before they are sent to the client.
27
- host.bind_lib /jquery.*/, :js, "jquery"
28
- host.bind_lib /boostrap.*/, :css, "boots"
29
-
30
- # Use combos to chain together libraries into a collection
31
- host.combo "all-lib", "jquery", "boots"
32
-
33
- # Change this to change where you store your libraries
34
- host.libdir fl("libs")
35
-
36
- # Change this to choose what URI the libraries are linked
37
- # to (yoursite.com/libraries/library_name)
38
- host.liburi "libraries"
39
- end
40
-
41
- # This is your other Virtual Host, accepting connections to any domain.
42
- # The '0' represents the priority, with the default being 50. Higher priority
43
- # Hosts will be chosen if the request matches multiple Hosts.
44
- w.host(/.*/, 0) do |host|
45
- # This is where your public documents and pages are stored
46
- host.root fl("main/http")
47
-
48
- # This is where your non-public includes are stored
49
- host.includes fl("main/rb")
50
- end
51
-
52
- end
1
+ # This is the configuration for your waitress server, accepting connections on port '2910'
2
+ Waitress.configure!(2910) do |w|
3
+
4
+ # You can run regular Ruby Code in here, too!
5
+ @home = File.dirname(__FILE__)
6
+ def fl file
7
+ File.join(@home, file)
8
+ end
9
+
10
+ # This is your main Virtual Host, accepting connections to 'example.mysite.com'
11
+ w.host(/example.mysite.com/) do |host|
12
+ # This is where your public documents and pages are stored
13
+ host.root fl("example/http")
14
+
15
+ # This is where your non-public includes are stored
16
+ host.includes fl("example/rb")
17
+
18
+ # This will show up when a 404 error occurs
19
+ # host.set_404 fl("example/http/404.html")
20
+
21
+ # Want to rewrite a URL? No problem.
22
+ host.rewrite /some_url/, "some_other_url"
23
+ host.rewrite /capture_group_(\d)/, "capture/group\\1"
24
+
25
+ # Bind_Lib will allow you to automatically import lib tags into .wrb files
26
+ # Before they are sent to the client.
27
+ host.bind_lib /jquery.*/, :js, "jquery"
28
+ host.bind_lib /boostrap.*/, :css, "boots"
29
+
30
+ # Use combos to chain together libraries into a collection
31
+ host.combo "all-lib", "jquery", "boots"
32
+
33
+ # Change this to change where you store your libraries
34
+ host.libdir fl("libs")
35
+
36
+ # Change this to choose what URI the libraries are linked
37
+ # to (yoursite.com/libraries/library_name)
38
+ host.liburi "libraries"
39
+ end
40
+
41
+ # This is your other Virtual Host, accepting connections to any domain.
42
+ # The '0' represents the priority, with the default being 50. Higher priority
43
+ # Hosts will be chosen if the request matches multiple Hosts.
44
+ w.host(/.*/, 0) do |host|
45
+ # This is where your public documents and pages are stored
46
+ host.root fl("main/http")
47
+
48
+ # This is where your non-public includes are stored
49
+ host.includes fl("main/rb")
50
+ end
51
+
52
+ end
@@ -1,18 +1,18 @@
1
- <html>
2
- <head>
3
- <title> 404 - Page Not Found </title>
4
- <link rel="stylesheet" href="/css/hack.css">
5
- <link rel="stylesheet" href="/css/waitress.css">
6
- </head>
7
- <body>
8
- <div id="maincontainer">
9
- <div class="textcontainer">
10
- <h1> 404 </h1>
11
- <h2> You ordered something that wasn't on the menu </h2>
12
- </div>
13
- <div class="imgcontainer">
14
- <img src="/img/404.png">
15
- </div>
16
- </div>
17
- </body>
18
- </html>
1
+ <html>
2
+ <head>
3
+ <title> 404 - Page Not Found </title>
4
+ <link rel="stylesheet" href="/css/hack.css">
5
+ <link rel="stylesheet" href="/css/waitress.css">
6
+ </head>
7
+ <body>
8
+ <div id="maincontainer">
9
+ <div class="textcontainer">
10
+ <h1> 404 </h1>
11
+ <h2> You ordered something that wasn't on the menu </h2>
12
+ </div>
13
+ <div class="imgcontainer">
14
+ <img src="/img/404.png">
15
+ </div>
16
+ </div>
17
+ </body>
18
+ </html>
@@ -1,37 +1,37 @@
1
- /*!
2
- * Hack v2.013 - https://sourcefoundry.org/hack/
3
- * Licenses - Fonts: Hack Open Font License + Bitstream Vera license, CSS: MIT License
4
- */
5
- /* FONT PATHS
6
- * -------------------------- */
7
- @font-face {
8
- font-family: 'Hack';
9
- src: url('../fonts/eot/latin/hack-regular-latin-webfont.eot?v=2.013');
10
- src: url('../fonts/eot/latin/hack-regular-latin-webfont.eot?#iefix&v=2.013') format('embedded-opentype'), url('../fonts/woff2/latin/hack-regular-latin-webfont.woff2?v=2.013') format('woff2'), url('../fonts/woff/latin/hack-regular-latin-webfont.woff?v=2.013') format('woff'), url('../fonts/web-ttf/latin/hack-regular-latin-webfont.ttf?v=2.013') format('truetype'), url('../fonts/svg/latin/hack-regular-latin-webfont.svg?v=2.013#hackregular') format('svg');
11
- font-weight: 400;
12
- font-style: normal;
13
- }
14
-
15
- @font-face {
16
- font-family: 'Hack';
17
- src: url('../fonts/eot/latin/hack-bold-latin-webfont.eot?v=2.013');
18
- src: url('../fonts/eot/latin/hack-bold-latin-webfont.eot?#iefix&v=2.013') format('embedded-opentype'), url('../fonts/woff2/latin/hack-bold-latin-webfont.woff2?v=2.013') format('woff2'), url('../fonts/woff/latin/hack-bold-latin-webfont.woff?v=2.013') format('woff'), url('../fonts/web-ttf/latin/hack-bold-latin-webfont.ttf?v=2.013') format('truetype'), url('../fonts/svg/latin/hack-bold-latin-webfont.svg?v=2.013#hackbold') format('svg');
19
- font-weight: 700;
20
- font-style: normal;
21
- }
22
-
23
- @font-face {
24
- font-family: 'Hack';
25
- src: url('../fonts/eot/latin/hack-italic-latin-webfont.eot?v=2.013');
26
- src: url('../fonts/eot/latin/hack-italic-latin-webfont.eot?#iefix&v=2.013') format('embedded-opentype'), url('../fonts/woff2/latin/hack-italic-latin-webfont.woff2?v=2.013') format('woff2'), url('../fonts/woff/latin/hack-italic-latin-webfont.woff?v=2.013') format('woff'), url('../fonts/web-ttf/latin/hack-italic-latin-webfont.ttf?v=2.013') format('truetype'), url('../fonts/svg/latin/hack-italic-latin-webfont.svg?v=2.013#hackitalic') format('svg');
27
- font-weight: 400;
28
- font-style: italic;
29
- }
30
-
31
- @font-face {
32
- font-family: 'Hack';
33
- src: url('../fonts/eot/latin/hack-bolditalic-latin-webfont.eot?v=2.013');
34
- src: url('../fonts/eot/latin/hack-bolditalic-latin-webfont.eot?#iefix&v=2.013') format('embedded-opentype'), url('../fonts/woff2/latin/hack-bolditalic-latin-webfont.woff2?v=2.013') format('woff2'), url('../fonts/woff/latin/hack-bolditalic-latin-webfont.woff?v=2.013') format('woff'), url('../fonts/web-ttf/latin/hack-bolditalic-latin-webfont.ttf?v=2.013') format('truetype'), url('../fonts/svg/latin/hack-bolditalic-latin-webfont.svg?v=2.013#hackbolditalic') format('svg');
35
- font-weight: 700;
36
- font-style: italic;
37
- }
1
+ /*!
2
+ * Hack v2.013 - https://sourcefoundry.org/hack/
3
+ * Licenses - Fonts: Hack Open Font License + Bitstream Vera license, CSS: MIT License
4
+ */
5
+ /* FONT PATHS
6
+ * -------------------------- */
7
+ @font-face {
8
+ font-family: 'Hack';
9
+ src: url('../fonts/eot/latin/hack-regular-latin-webfont.eot?v=2.013');
10
+ src: url('../fonts/eot/latin/hack-regular-latin-webfont.eot?#iefix&v=2.013') format('embedded-opentype'), url('../fonts/woff2/latin/hack-regular-latin-webfont.woff2?v=2.013') format('woff2'), url('../fonts/woff/latin/hack-regular-latin-webfont.woff?v=2.013') format('woff'), url('../fonts/web-ttf/latin/hack-regular-latin-webfont.ttf?v=2.013') format('truetype'), url('../fonts/svg/latin/hack-regular-latin-webfont.svg?v=2.013#hackregular') format('svg');
11
+ font-weight: 400;
12
+ font-style: normal;
13
+ }
14
+
15
+ @font-face {
16
+ font-family: 'Hack';
17
+ src: url('../fonts/eot/latin/hack-bold-latin-webfont.eot?v=2.013');
18
+ src: url('../fonts/eot/latin/hack-bold-latin-webfont.eot?#iefix&v=2.013') format('embedded-opentype'), url('../fonts/woff2/latin/hack-bold-latin-webfont.woff2?v=2.013') format('woff2'), url('../fonts/woff/latin/hack-bold-latin-webfont.woff?v=2.013') format('woff'), url('../fonts/web-ttf/latin/hack-bold-latin-webfont.ttf?v=2.013') format('truetype'), url('../fonts/svg/latin/hack-bold-latin-webfont.svg?v=2.013#hackbold') format('svg');
19
+ font-weight: 700;
20
+ font-style: normal;
21
+ }
22
+
23
+ @font-face {
24
+ font-family: 'Hack';
25
+ src: url('../fonts/eot/latin/hack-italic-latin-webfont.eot?v=2.013');
26
+ src: url('../fonts/eot/latin/hack-italic-latin-webfont.eot?#iefix&v=2.013') format('embedded-opentype'), url('../fonts/woff2/latin/hack-italic-latin-webfont.woff2?v=2.013') format('woff2'), url('../fonts/woff/latin/hack-italic-latin-webfont.woff?v=2.013') format('woff'), url('../fonts/web-ttf/latin/hack-italic-latin-webfont.ttf?v=2.013') format('truetype'), url('../fonts/svg/latin/hack-italic-latin-webfont.svg?v=2.013#hackitalic') format('svg');
27
+ font-weight: 400;
28
+ font-style: italic;
29
+ }
30
+
31
+ @font-face {
32
+ font-family: 'Hack';
33
+ src: url('../fonts/eot/latin/hack-bolditalic-latin-webfont.eot?v=2.013');
34
+ src: url('../fonts/eot/latin/hack-bolditalic-latin-webfont.eot?#iefix&v=2.013') format('embedded-opentype'), url('../fonts/woff2/latin/hack-bolditalic-latin-webfont.woff2?v=2.013') format('woff2'), url('../fonts/woff/latin/hack-bolditalic-latin-webfont.woff?v=2.013') format('woff'), url('../fonts/web-ttf/latin/hack-bolditalic-latin-webfont.ttf?v=2.013') format('truetype'), url('../fonts/svg/latin/hack-bolditalic-latin-webfont.svg?v=2.013#hackbolditalic') format('svg');
35
+ font-weight: 700;
36
+ font-style: italic;
37
+ }
@@ -1,57 +1,57 @@
1
- body {
2
- background-color: rgb(15, 15, 15);
3
- font-family: 'Hack', proxima-nova, helvetica;
4
- color: #ddd;
5
- }
6
-
7
- #maincontainer {
8
- width: 60%;
9
- min-width: 950px;
10
- height: 250px;
11
- position: absolute;
12
- top:0;
13
- bottom: 0;
14
- left: 0;
15
- right: 0;
16
-
17
- text-align: right;
18
- margin: auto;
19
-
20
- display: flex;
21
- }
22
-
23
- .textcontainer {
24
- width: 65%;
25
- padding-right: 5%;
26
- }
27
-
28
- .titlecontainer {
29
- text-align: center;
30
- display: block;
31
- }
32
-
33
- .imgcontainer {
34
- width: 30%;
35
- padding-left: 5%;
36
- text-align: left;
37
- border-left: 3px solid #ddd;
38
- opacity: 0.25;
39
- }
40
-
41
- img {
42
- height: 250px;
43
- }
44
-
45
- h1, h2 {
46
- margin: 0;
47
- font-weight: normal;
48
- }
49
-
50
- h1 {
51
- font-size: 120px;
52
- margin-bottom: -15px;
53
- }
54
-
55
- h2 {
56
- font-size: 40px;
57
- }
1
+ body {
2
+ background-color: rgb(15, 15, 15);
3
+ font-family: 'Hack', proxima-nova, helvetica;
4
+ color: #ddd;
5
+ }
6
+
7
+ #maincontainer {
8
+ width: 60%;
9
+ min-width: 950px;
10
+ height: 250px;
11
+ position: absolute;
12
+ top:0;
13
+ bottom: 0;
14
+ left: 0;
15
+ right: 0;
16
+
17
+ text-align: right;
18
+ margin: auto;
19
+
20
+ display: flex;
21
+ }
22
+
23
+ .textcontainer {
24
+ width: 65%;
25
+ padding-right: 5%;
26
+ }
27
+
28
+ .titlecontainer {
29
+ text-align: center;
30
+ display: block;
31
+ }
32
+
33
+ .imgcontainer {
34
+ width: 30%;
35
+ padding-left: 5%;
36
+ text-align: left;
37
+ border-left: 3px solid #ddd;
38
+ opacity: 0.25;
39
+ }
40
+
41
+ img {
42
+ height: 250px;
43
+ }
44
+
45
+ h1, h2 {
46
+ margin: 0;
47
+ font-weight: normal;
48
+ }
49
+
50
+ h1 {
51
+ font-size: 120px;
52
+ margin-bottom: -15px;
53
+ }
54
+
55
+ h2 {
56
+ font-size: 40px;
57
+ }