RackMotion 0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e25151d74f5c7f014686ffc00f30f9cea8f4c643
4
+ data.tar.gz: a9899dde82b707925d9127c85c3fe3d76b51f7eb
5
+ SHA512:
6
+ metadata.gz: 6f7445f78ca154d1b7e3335aadcac83e89411df6d463827e603acb67fce62fbd7b436065e3ca49a4e46972a8f2d20af5b836f08685fac32dafb1e7ea532a9df9
7
+ data.tar.gz: e41097ff6c25e8c29538ec36b11bd45efdd5724727974e27061daba058092b2fc23c09b81c0a3966fedb8a110cf765d8079dccba757213c4f14e9ecb5c48b56b
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ <p align="center">
2
+ <img src="https://raw.github.com/drewbug/RackMotion/assets/rackmotion-logo.png" alt="RackMotion" title="RackMotion">
3
+ </p>
4
+
5
+ RackMotion provides a Rack-like interface for middleware that can intercept and alter HTTP requests and responses in RubyMotion. It's built on top of NSURLProtocol, which makes it, to borrow a line from [Mattt Thompson](http://www.nshipster.com/nsurlprotocol/), an Apple-sanctioned man-in-the-middle attack.
6
+
7
+ For example, here's how easy it is to enable [cross-origin resource sharing](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) for most Javascript XMLHttpRequests:
8
+
9
+ class EnableCORS
10
+ def initialize(app)
11
+ @app = app
12
+ end
13
+
14
+ def call(request)
15
+ status, headers, data = @app.call(request)
16
+
17
+ if request.allHTTPHeaderFields['Origin']
18
+ headers['Access-Control-Allow-Origin'] = request.allHTTPHeaderFields['Origin']
19
+ end
20
+
21
+ return status, headers, data
22
+ end
23
+ end
24
+
25
+ And then, in your AppDelegate:
26
+
27
+ RackMotion.use EnableCORS
28
+
29
+ ## Installation
30
+
31
+ Add this line to your application's Gemfile:
32
+
33
+ gem 'RackMotion'
34
+
35
+ And then execute:
36
+
37
+ $ bundle
38
+
39
+ Or install it yourself as:
40
+
41
+ $ gem install RackMotion
data/lib/RackMotion.rb ADDED
@@ -0,0 +1,8 @@
1
+ unless defined?(Motion::Project::Config)
2
+ raise "This file must be required within a RubyMotion project Rakefile."
3
+ end
4
+
5
+ lib_dir_path = File.dirname(File.expand_path(__FILE__))
6
+ Motion::Project::App.setup do |app|
7
+ app.files.unshift(Dir.glob(File.join(lib_dir_path, "project/**/*.rb")))
8
+ end
@@ -0,0 +1,80 @@
1
+ module RackMotion
2
+ def self.use(middleware)
3
+ NSURLProtocol.registerClass URLProtocol if URLProtocol.middlewares.empty?
4
+ URLProtocol.middlewares << middleware
5
+ end
6
+
7
+ class URLProtocol < NSURLProtocol
8
+ @@middlewares = []
9
+
10
+ def self.middlewares
11
+ @@middlewares
12
+ end
13
+
14
+ def self.canInitWithRequest(request)
15
+ return false unless request.URL
16
+ return false unless request.URL.scheme.start_with?("http")
17
+ !NSURLProtocol.propertyForKey('RackMotion', inRequest: request)
18
+ end
19
+
20
+ def self.canonicalRequestForRequest(request)
21
+ return request
22
+ end
23
+
24
+ def startLoading
25
+ @thread = NSThread.alloc.initWithTarget(lambda do
26
+ chain = @@middlewares.inject(self) do |instance, klass|
27
+ klass.new(instance)
28
+ end
29
+
30
+ status, headers, data = chain.call self.request.mutableCopy
31
+
32
+ response = NSHTTPURLResponse.alloc.initWithURL @connection.originalRequest.URL, statusCode: status, HTTPVersion: 'HTTP/1.1', headerFields: headers
33
+
34
+ self.client.URLProtocol(self, didReceiveResponse: response, cacheStoragePolicy: NSURLCacheStorageNotAllowed)
35
+ self.client.URLProtocol(self, didLoadData: data)
36
+ self.client.URLProtocolDidFinishLoading(self)
37
+ end, selector: 'call', object: nil)
38
+
39
+ @thread.start
40
+ end
41
+
42
+ def stopLoading
43
+ @connection.cancel if @connection
44
+ @thread.cancel if @thread
45
+ end
46
+
47
+ def call(new_request)
48
+ NSURLProtocol.setProperty(true, forKey: 'RackMotion', inRequest: new_request)
49
+
50
+ connection_delegate = ConnectionDelegate.new
51
+
52
+ @connection = NSURLConnection.alloc.initWithRequest(new_request, delegate: connection_delegate, startImmediately: true)
53
+ NSRunLoop.currentRunLoop.run
54
+
55
+ connection_delegate.semaphore.wait
56
+ return connection_delegate.response.statusCode, connection_delegate.response.allHeaderFields.mutableCopy, connection_delegate.data
57
+ end
58
+ end
59
+
60
+ class ConnectionDelegate
61
+ attr_reader :semaphore, :data, :response
62
+
63
+ def initialize
64
+ @semaphore = Dispatch::Semaphore.new(0)
65
+ @data = NSMutableData.new
66
+ end
67
+
68
+ def connection(connection, didReceiveData: data)
69
+ @data.appendData(data)
70
+ end
71
+
72
+ def connection(connection, didReceiveResponse: response)
73
+ @response = response
74
+ end
75
+
76
+ def connectionDidFinishLoading(connection)
77
+ @semaphore.signal
78
+ end
79
+ end
80
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: RackMotion
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Drew Carey Buglione
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: RackMotion provides a Rack-like interface for middleware that can intercept
28
+ and alter HTTP requests and responses in RubyMotion. It's built on top of NSURLProtocol,
29
+ which makes it, to borrow a line from Mattt Thompson, an Apple-sanctioned man-in-the-middle
30
+ attack.
31
+ email:
32
+ - me@drewb.ug
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - README.md
38
+ - lib/project/RackMotion.rb
39
+ - lib/RackMotion.rb
40
+ homepage: ''
41
+ licenses:
42
+ - ''
43
+ metadata: {}
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubyforge_project:
60
+ rubygems_version: 2.0.6
61
+ signing_key:
62
+ specification_version: 4
63
+ summary: Intercept and alter HTTP requests and responses in RubyMotion
64
+ test_files: []