straight-server 0.2.3 → 1.0.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/Gemfile +21 -16
  4. data/Gemfile.lock +44 -30
  5. data/Gemfile.travis +15 -16
  6. data/README.md +66 -47
  7. data/VERSION +1 -1
  8. data/db/migrations/011_add_callback_data_to_orders.rb +1 -1
  9. data/db/migrations/012_add_address_provider.rb +11 -0
  10. data/db/migrations/013_add_address_derivation_scheme.rb +11 -0
  11. data/db/migrations/014_pubkey_null_address_provider_not_null.rb +8 -0
  12. data/db/migrations/015_add_amount_paid_to_orders.rb +11 -0
  13. data/db/migrations/016_add_new_params_to_orders.rb +13 -0
  14. data/db/migrations/017_add_test_mode_to_gateways.rb +11 -0
  15. data/db/migrations/018_add_test_keychain_id_to_gateways.rb +11 -0
  16. data/db/migrations/019_add_test_pubkey_to_gateways.rb +11 -0
  17. data/db/migrations/020_add_test_mode_to_orders.rb +11 -0
  18. data/db/schema.rb +11 -1
  19. data/lib/straight-server.rb +11 -9
  20. data/lib/straight-server/config.rb +28 -18
  21. data/lib/straight-server/gateway.rb +167 -87
  22. data/lib/straight-server/initializer.rb +13 -7
  23. data/lib/straight-server/order.rb +39 -17
  24. data/lib/straight-server/orders_controller.rb +71 -21
  25. data/lib/straight-server/random_string.rb +3 -13
  26. data/lib/straight-server/server.rb +3 -4
  27. data/lib/straight-server/signature_validator.rb +69 -0
  28. data/lib/straight-server/thread.rb +19 -4
  29. data/lib/straight-server/throttler.rb +7 -13
  30. data/lib/tasks/db.rake +1 -1
  31. data/spec/.straight/config.yml +8 -3
  32. data/spec/.straight/default_test_last_keychain_id +1 -0
  33. data/spec/factories.rb +2 -1
  34. data/spec/lib/gateway_spec.rb +222 -94
  35. data/spec/lib/initializer_spec.rb +1 -1
  36. data/spec/lib/order_spec.rb +26 -7
  37. data/spec/lib/orders_controller_spec.rb +65 -6
  38. data/spec/lib/signature_validator_spec.rb +72 -0
  39. data/spec/lib/thread_spec.rb +16 -0
  40. data/spec/lib/throttle_spec.rb +2 -2
  41. data/spec/spec_helper.rb +17 -22
  42. data/straight-server.gemspec +31 -12
  43. data/templates/config.yml +19 -10
  44. metadata +52 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3d3e00cdba620b59557e0f28a51cdc3a82a7b953
4
- data.tar.gz: 53372b11a9ddd0045bba84f4b42e9c2706ec9668
3
+ metadata.gz: 8c948e3fe9fa5c45507abf1d99c8d79d208a8c38
4
+ data.tar.gz: 6bb99e03b2ab6d086cab4dd9afec47de95a85a34
5
5
  SHA512:
6
- metadata.gz: 0ca180d944906bd732574b91794012e0661e09de8d47900906ccd06e9269746aaf2a39be3ceffd02ccb2e9e4f9a89e4b9d824ceee2293a9b4c69f9ffc8473f44
7
- data.tar.gz: 656718bdf4cc21510fa657efd33265545e7d4cc9a0b47f27e263dfd888e5d55c6216056f897b2af2555e414622731ffaa30313824b67d31b21b9556a54ee2bd6
6
+ metadata.gz: 6eeaaf80ea4161fa7857739fbb25939e4bd7d159a389acff8880a0b208daaa46a5f90fdbca3752d7e563cc896bc1eb9d5ffb54e169918b5dfad426898b38eaab
7
+ data.tar.gz: 6cf3c16258ffd4b3b762ce8b2ebe287cb6a6c0e5e959dcae12a8c9d32d40de3d9b5f5a3dccbbb80d9ee3c9c4a4c62c54ff83c514e3a1dd9cb0302e9071649db8
@@ -1,8 +1,8 @@
1
1
  gemfile: Gemfile.travis
2
2
  language: ruby
3
3
  rvm:
4
- - 2.1.0
4
+ - 2.2.1
5
5
  services:
6
6
  - redis-server
7
7
  notifications:
8
- slack: straight-payments:ovM1xPrG9BmKTHGkM0k42gkP
8
+ slack: mycelium-gear:ovM1xPrG9BmKTHGkM0k42gkP
data/Gemfile CHANGED
@@ -1,21 +1,26 @@
1
- source "http://rubygems.org"
1
+ source 'https://rubygems.org' do
2
+ gem 'straight', '1.0.0' #, path: '../straight-engine'
3
+ gem 'satoshi-unit', '>= 0.1.8'
4
+ gem 'goliath'
5
+ gem 'faye-websocket'
6
+ gem 'sequel'
7
+ gem 'logmaster', '0.1.5'
8
+ gem 'ruby-hmac'
9
+ gem 'httparty'
10
+ gem 'redis'
11
+ gem 'btcruby'
12
+ end
2
13
 
3
- gem "straight", "0.2.2"
4
- gem "satoshi-unit"
5
- gem "goliath"
6
- gem "faye-websocket"
7
- gem "sequel"
8
- gem "logmaster", '0.1.5'
9
- gem "ruby-hmac"
10
- gem "httparty"
11
- gem "money-tree", "0.9.0"
14
+ unless ENV['STRAIGHT_SERVER_IGNORE_ADDONS_GEMFILE'] # use this flag when building straight-server.gemspec
15
+ addons_gemfile = File.join(ENV['STRAIGHT_SERVER_CONFIG_DIR'] || File.join(ENV['HOME'], '.straight'), 'AddonsGemfile')
16
+ eval_gemfile addons_gemfile if File.exists?(addons_gemfile)
17
+ end
12
18
 
13
- # Add dependencies to develop your gem here.
14
- # Include everything needed to run rake, tests, features, etc.
15
19
  group :development do
16
- gem "bundler", "~> 1.0"
17
- gem "jeweler", "~> 2.0.1"
18
- gem "github_api", "0.11.3"
20
+ gem 'byebug'
21
+ gem 'bundler', '~> 1.0'
22
+ gem 'jeweler', '~> 2.0.1'
23
+ gem 'github_api', '0.11.3'
19
24
  end
20
25
 
21
26
  group :test do
@@ -24,5 +29,5 @@ group :test do
24
29
  gem 'factory_girl'
25
30
  gem 'sqlite3'
26
31
  gem 'hashie'
27
- gem 'redis'
32
+ gem 'webmock', require: false
28
33
  end
@@ -1,5 +1,5 @@
1
1
  GEM
2
- remote: http://rubygems.org/
2
+ remote: https://rubygems.org/
3
3
  specs:
4
4
  activesupport (4.2.1)
5
5
  i18n (~> 0.7)
@@ -10,7 +10,14 @@ GEM
10
10
  addressable (2.3.8)
11
11
  async-rack (0.5.1)
12
12
  rack (~> 1.1)
13
+ btcruby (1.0.6)
14
+ ffi (~> 1.9, >= 1.9.3)
13
15
  builder (3.2.2)
16
+ byebug (5.0.0)
17
+ columnize (= 0.9.0)
18
+ columnize (0.9.0)
19
+ crack (0.4.2)
20
+ safe_yaml (~> 1.0.0)
14
21
  descendants_tracker (0.0.4)
15
22
  thread_safe (~> 0.3, >= 0.3.1)
16
23
  diff-lcs (1.2.5)
@@ -24,11 +31,12 @@ GEM
24
31
  activesupport (>= 3.0.0)
25
32
  faraday (0.9.1)
26
33
  multipart-post (>= 1.2, < 3)
27
- faye-websocket (0.9.2)
34
+ faye-websocket (0.10.0)
28
35
  eventmachine (>= 0.12.0)
29
36
  websocket-driver (>= 0.5.1)
30
- ffi (1.9.8)
37
+ ffi (1.9.10)
31
38
  git (1.2.9.1)
39
+ git-version-bump (0.15.1)
32
40
  github_api (0.11.3)
33
41
  addressable (~> 2.3)
34
42
  descendants_tracker (~> 0.0.1)
@@ -64,18 +72,16 @@ GEM
64
72
  nokogiri (>= 1.5.10)
65
73
  rake
66
74
  rdoc
67
- json (1.8.2)
68
- jwt (1.4.1)
75
+ json (1.8.3)
76
+ jwt (1.5.0)
69
77
  log4r (1.1.10)
70
78
  logmaster (0.1.5)
71
79
  pony
72
80
  mail (2.6.3)
73
81
  mime-types (>= 1.16, < 3)
74
- mime-types (2.5)
82
+ mime-types (2.6.1)
75
83
  mini_portile (0.6.2)
76
- minitest (5.6.1)
77
- money-tree (0.9.0)
78
- ffi
84
+ minitest (5.7.0)
79
85
  multi_json (1.11.0)
80
86
  multi_xml (0.5.5)
81
87
  multipart-post (2.0.0)
@@ -89,10 +95,11 @@ GEM
89
95
  rack (~> 1.2)
90
96
  pony (1.11)
91
97
  mail (>= 2.0)
92
- rack (1.6.0)
98
+ rack (1.6.1)
93
99
  rack-accept-media-types (0.9)
94
- rack-contrib (1.2.0)
95
- rack (>= 0.9.1)
100
+ rack-contrib (1.3.0)
101
+ git-version-bump (~> 0.15)
102
+ rack (~> 1.4)
96
103
  rack-respond_to (0.9.8)
97
104
  rack-accept-media-types (>= 0.6)
98
105
  rake (10.4.2)
@@ -112,18 +119,23 @@ GEM
112
119
  rspec-support (~> 3.2.0)
113
120
  rspec-support (3.2.2)
114
121
  ruby-hmac (0.4.0)
115
- satoshi-unit (0.1.7)
116
- sequel (4.22.0)
122
+ safe_yaml (1.0.4)
123
+ satoshi-unit (0.1.8)
124
+ sequel (4.24.0)
117
125
  sqlite3 (1.3.10)
118
- straight (0.2.2)
119
- httparty
120
- money-tree
121
- satoshi-unit
126
+ straight (1.0.0)
127
+ btcruby (~> 1.0)
128
+ faraday
129
+ httparty (~> 0.13.5)
130
+ satoshi-unit (~> 0.1)
122
131
  thread_safe (0.3.5)
123
- timecop (0.7.3)
132
+ timecop (0.7.4)
124
133
  tzinfo (1.2.2)
125
134
  thread_safe (~> 0.1)
126
- websocket-driver (0.5.4)
135
+ webmock (1.21.0)
136
+ addressable (>= 2.3.6)
137
+ crack (>= 0.3.2)
138
+ websocket-driver (0.6.0)
127
139
  websocket-extensions (>= 0.1.0)
128
140
  websocket-extensions (0.1.2)
129
141
 
@@ -131,21 +143,23 @@ PLATFORMS
131
143
  ruby
132
144
 
133
145
  DEPENDENCIES
146
+ btcruby!
134
147
  bundler (~> 1.0)
148
+ byebug
135
149
  factory_girl
136
- faye-websocket
150
+ faye-websocket!
137
151
  github_api (= 0.11.3)
138
- goliath
152
+ goliath!
139
153
  hashie
140
- httparty
154
+ httparty!
141
155
  jeweler (~> 2.0.1)
142
- logmaster (= 0.1.5)
143
- money-tree (= 0.9.0)
144
- redis
156
+ logmaster (= 0.1.5)!
157
+ redis!
145
158
  rspec
146
- ruby-hmac
147
- satoshi-unit
148
- sequel
159
+ ruby-hmac!
160
+ satoshi-unit (>= 0.1.8)!
161
+ sequel!
149
162
  sqlite3
150
- straight (= 0.2.2)
163
+ straight (= 1.0.0)!
151
164
  timecop
165
+ webmock
@@ -1,21 +1,20 @@
1
- source "http://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
- gem "straight", git: "https://github.com/snitko/straight.git"
4
- gem "satoshi-unit"
5
- gem "goliath"
6
- gem "faye-websocket"
7
- gem "sequel"
8
- gem "logmaster", '0.1.5'
9
- gem "ruby-hmac"
10
- gem "httparty"
11
- gem "money-tree", "0.9.0"
3
+ gem 'straight', github: "snitko/straight"
4
+ gem 'satoshi-unit'
5
+ gem 'goliath'
6
+ gem 'faye-websocket'
7
+ gem 'sequel'
8
+ gem 'logmaster', '0.1.5'
9
+ gem 'ruby-hmac'
10
+ gem 'httparty'
11
+ gem 'redis'
12
12
 
13
- # Add dependencies to develop your gem here.
14
- # Include everything needed to run rake, tests, features, etc.
15
13
  group :development do
16
- gem "bundler", "~> 1.0"
17
- gem "jeweler", "~> 2.0.1"
18
- gem "github_api", "0.11.3"
14
+ gem 'byebug'
15
+ gem 'bundler', '~> 1.0'
16
+ gem 'jeweler', '~> 2.0.1'
17
+ gem 'github_api', '0.11.3'
19
18
  end
20
19
 
21
20
  group :test do
@@ -24,5 +23,5 @@ group :test do
24
23
  gem 'factory_girl'
25
24
  gem 'sqlite3'
26
25
  gem 'hashie'
27
- gem 'redis'
26
+ gem 'webmock', require: false
28
27
  end
data/README.md CHANGED
@@ -10,7 +10,7 @@ Straight server
10
10
 
11
11
  > Website: http://gear.mycelium.com
12
12
 
13
- [![Build Status](https://travis-ci.org/snitko/straight-server.svg)](https://travis-ci.org/snitko/straight-server)
13
+ [![Build Status](https://travis-ci.org/MyceliumGear/straight-server.svg)](https://travis-ci.org/MyceliumGear/straight-server)
14
14
 
15
15
  If you'd like to accept Bitcoin payments on your website automatically, but you're not
16
16
  fond of services like Coinbase or Bitpay, which hold your bitcoins for you and require a ton
@@ -35,7 +35,7 @@ Installation
35
35
  ------------
36
36
  I currently only tested it on Unix machines.
37
37
 
38
- 1. Install RVM and Ruby 2.1 (see [RVM guide](http://rvm.io/rvm/install))
38
+ 1. Install RVM, Ruby 2.1 (see [RVM guide](http://rvm.io/rvm/install)) and Redis.
39
39
 
40
40
  2. run `gem install straight-server`
41
41
 
@@ -70,7 +70,7 @@ in the `~/.straight/config.yml` file for the current gateway. This callback requ
70
70
 
71
71
  Here's an example of a callback url request that could be made by Straight server when order status changes:
72
72
 
73
- GET http://mystore.com/payment-callback?order_id=234&amount=1&status=2&address=1NZov2nm6gRCGW6r4q1qHtxXurrWNpPr1q&tid=tid1&callback_data=some+random+data&keychain_id=1&last_keychain_id=1
73
+ GET http://mystore.com/payment-callback?order_id=234&amount=1&amount_in_btc=0.00000001&amoint_paid_in_btc=0.00000001&status=2&address=1NZov2nm6gRCGW6r4q1qHtxXurrWNpPr1q&tid=tid1&callback_data=some+random+data&keychain_id=1&last_keychain_id=1
74
74
 
75
75
  As you may have noticed, there's a parameter called `callback_data`. It is a way for you to pass info back
76
76
  to your app. It will have the same value as the `callback_data` parameter you passed to the create order request:
@@ -96,7 +96,7 @@ where `:id` can either be order `id` (CAUTION: order `id` is NOT the same as `ke
96
96
  `payment_id` - both are returned in the json data when the order
97
97
  is created (see above). The request above may return something like:
98
98
 
99
- {"status":2,"amount":1,"address":"1NZov2nm6gRCGW6r4q1qHtxXurrWNpPr1q","tid":"f0f9205e41bf1b79cb7634912e86bb840cedf8b1d108bd2faae1651ca79a5838","id":1, "keychain_id": 1, "last_keychain_id": 1 }
99
+ {"status":2,"amount":1,"address":"1NZov2nm6gRCGW6r4q1qHtxXurrWNpPr1q","tid":"f0f9205e41bf1b79cb7634912e86bb840cedf8b1d108bd2faae1651ca79a5838","id":1,"amount_in_btc": 0.00000001,"amount_paid_in_btc": 0.00000001,"keychain_id": 1,"last_keychain_id": 1 }
100
100
 
101
101
  **Subscribing to the order using websockets**:
102
102
  You can also subscribe to the order status changes using websockets at:
@@ -112,6 +112,15 @@ its creation time in `#created_at` field. In turn, each order's gateway has a fi
112
112
  depending on what approach to storing gateways you use). After this time has passed, straight-server stops
113
113
  checking whether new transactions appear on the order's bitcoin address and also changes order's status to 5 (expired).
114
114
 
115
+ **Get last keychain id**
116
+ You can get last keychain id for gateway with the following request:
117
+
118
+ GET /gateway/1/last_keychain_id
119
+
120
+ The request above return something like:
121
+
122
+ {"gateway_id": 1, "last_keychain_id": "11"}
123
+
115
124
  Implications of restarting the server
116
125
  -------------------------------------
117
126
 
@@ -197,35 +206,36 @@ Go to your `~/.straight/config.yml` directory and set two options for each of yo
197
206
  secret: 'a long string of random chars'
198
207
  check_signature: true
199
208
 
200
- This will force gateways to check signatures when you try to create a new order. A signature is
201
- a HMAC SHA256 hash of the secret and a keychain_id. Because you need keychain_id, it means you have
202
- to actually provide it manually in the params. It can be any integer > 0, but it's better
203
- that it is a consecutive integer, so keep track of the last keychain_id that was used in your
204
- application. A possible request (assuming secret is the line mentioned above in the sample config) would look like this:
205
-
206
- POST /gateways/1/orders?amount=1&keychain_id=1&signature=aa14c26b2ae892a8719b0c2c57f162b967bfbfbdcc38d8883714a0680cf20467
209
+ This will force gateways to check signatures when you try to create a new order.
210
+ A signature is a `X-Signature` header with a string of about 88 chars:
207
211
 
208
- An example of obtaining such signature in Ruby:
212
+ Base64StrictEncode(
213
+ HMAC-SHA512(
214
+ REQUEST_METHOD + REQUEST_URI + SHA512(X-Nonce + REQUEST_BODY),
215
+ GATEWAY_SECRET
216
+ )
217
+ )
209
218
 
210
- require 'openssl'
211
-
212
- secret = 'a long string of random chars'
213
- OpenSSL::HMAC.digest('sha256', secret, "1").unpack("H*").first # "1" may be order_id here
219
+ Where
214
220
 
215
- Straight server will also sign the callback url request. However, since keychain_id may potentially
216
- be shared between 2 or more orders, the callback signature is based on internal `order_id` returned
217
- with the json after you create the said order. Here's an example of such a signature:
221
+ * `REQUEST_METHOD`: `GET`, `POST`, etc.
222
+ * `REQUEST_URI`: `/full/path/with?arguments&and#fragment`
223
+ * `REQUEST_BODY`: final string with JSON or blank string
224
+ * `X-Nonce`: header with an integer which must be incremented with each request (protects from replay attack), for example `(Time.now.to_f * 1000).to_i`
225
+ * `SHA512`: [binary SHA-2, 512 bits](https://en.wikipedia.org/wiki/SHA-2)
226
+ * `HMAC-SHA512`: [binary HMAC with SHA512](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code)
227
+ * `GATEWAY_SECRET`: key for HMAC
228
+ * `Base64StrictEncode`: [Base64 encoding according to RFC 4648](https://en.wikipedia.org/wiki/Base64#RFC_4648)
218
229
 
219
- order.id #=> 234
220
- secret = 'a long string of random chars'
221
- h = OpenSSL::HMAC.digest('sha256', secret, 234).unpack("H*").first
230
+ For Ruby users signing is already implemented in `straight-server-kit` gem.
222
231
 
223
- and then send the request to the callback url with that signature:
232
+ Straight server will also sign the callback url request. However, it will use blank X-Nonce.
224
233
 
225
- GET http://mystore.com/payment-callback?order_id=234&amount=1&status=2&address=1NZov2nm6gRCGW6r4q1qHtxXurrWNpPr1q&tid=tid1&callback_data=some+random+data?signature=aa14c26b2ae892a8719b0c2c57f162b967bfbfbdcc38d8883714a0680cf20467&keychain_id=1&last_keychain_id=1
234
+ GET http://mystore.com/payment-callback?order_id=1&amount=10&amount_in_btc=0.0000001&amount_paid_in_btc=0.&status=1&address=address_1&tid=tid1&keychain_id=1&last_keychain_id=1&callback_data=so%3Fme+ran%26dom+data
235
+ X-Signature: S2P8A16+RPaegTzJnb0Eg91csb1SExjdnvadABmQvfoIry4POBp6WbA6UOSqXojzRevyC8Ya/5QrQTnNxIb4og==
226
236
 
227
- It is now up to your application to calculate that signature, compare it and
228
- make sure that only one such request is allowed (that is, if signature was used, it cannot be used again).
237
+ It is now up to your application to calculate that signature and compare it.
238
+ If it doesn't match, do not trust data, instead log it for further investigation and return 200 in order to prevent retries.
229
239
 
230
240
  What is keychain_id and why do we need it?
231
241
  ------------------------------------------
@@ -245,13 +255,6 @@ If you have 20 orders in a row and try to create another one, straight-server wi
245
255
  automatically reuse the `keychain_id` (and consequently, the address too) of the 20-th order. It will
246
256
  also set the 21-st order's `reused` field to the value of `1`.
247
257
 
248
- CAUTION: while you don't need to provide `keychain_id` when creating orders with gateways that
249
- do not require signatures, you still must do it with gateways that do require signatures.
250
- In this case, it is very important to make sure that you don't accidentally provide `keychain_id`
251
- that is too far away from the last used one. For example, if the gateway's `last_keychain_id` is `10`,
252
- do not use `35` for the next order, use `11`. `last_gateway_id` is always returned with other info
253
- when you create or check order status.
254
-
255
258
  Querying the blockchain
256
259
  -----------------------
257
260
  Straight currently uses third-party services, such as Blokchain.info and Helloblock.io to track
@@ -267,30 +270,40 @@ to query the blockchain.
267
270
  Counting orders
268
271
  ---------------
269
272
  For easy statistics and reports, it is desirable to know how many orders of each particular status each gateway has.
270
- For that reason optional order counters are implemented. To enable order counters, you must first install manually *redis-server*
271
- and then *redis* rubygem.
272
-
273
- Then edit your config file and make sure the following options are set:
273
+ For that reason optional order counters are implemented. To enable order counters, make sure the following options are set:
274
274
 
275
- environment: development # name your environment here
276
275
  count_orders: true # enable order counting feature
277
276
 
278
- redis:
279
- host: localhost
280
- port: 6379
281
- db: null # change to 1, 2, 3 etc. or leave as is
282
- password: null # if no password is needed, leave as is
283
-
284
277
  After restarting the server, you can use `Gateway#order_counters` method which will
285
278
  return a hash of all the counters. Here's an example output:
286
279
 
287
- { new: 132, unconfirmed: 0, paid: 34, underpaid: 1, overpaid: 2, expired: 55 }
280
+ { new: 132, unconfirmed: 0, paid: 34, underpaid: 1, overpaid: 2, expired: 55, canceled: 10 }
288
281
 
289
282
  The default behaviour is to cache the output, so if you want fresh values, use `reload: true`
290
283
  option on this method:
291
284
 
292
285
  Gateway#order_counters(reload: true)
293
286
 
287
+ Throttling
288
+ ----------
289
+
290
+ If Gateway does not require signature check (e.g. it's a public widget), you may wish to limit orders creation.
291
+ This may help to mitigate potential DoS attacks.
292
+ In order to enable throttler, edit your config file and make sure the following options are set:
293
+
294
+ throttle:
295
+ requests_limit: 21
296
+ period: 60
297
+ ip_ban_duration: 300
298
+
299
+ This will allow maximum 21 new orders per 60 seconds per gateway to be created.
300
+ `ip_ban_duration` is optional and prevents users from the banned IP (think of NAT) to create orders via any gateway for 300 seconds.
301
+ When using this option, make sure that `HTTP_X_FORWARDED_FOR` header contains end user's IP. For example, in nginx config:
302
+
303
+ proxy_set_header X-Forwarded-For $remote_addr;
304
+
305
+ Also, check out [ngx_http_realip_module](http://nginx.org/en/docs/http/ngx_http_realip_module.html).
306
+
294
307
  Running in production
295
308
  ---------------------
296
309
  Running in production usually assumes running server as daemon with a pid. Straight server
@@ -346,14 +359,20 @@ adding controllers and routes for them. Now let's look at how we should do that:
346
359
 
347
360
  1. All addons are placed under `~/.straight/addons/` (of course, it is wise to use symlinks).
348
361
 
349
- 2. `./straight/addons.yml` file lists addons and tells straight-server what are the names of the files to be loaded.
362
+ 2. `~/.straight/addons.yml` file lists addons and tells straight-server what are the names of the files to be loaded.
350
363
  The format of the file is the following:
351
364
 
365
+
352
366
  my_addon # <- name doesn't affect anything, just shows up in the log file
353
367
  path: addons/my_addon/lib/my_addon # <- This is unnecessary if addon is already in the LOAD_PATH
354
368
  module: MyAddon # <- actual module should be a submodule of StraightServer::Addon
355
369
 
356
- 3. In `./straight/addons/my_addon/lib/` we will place two files, `my_addon.rb` and 'my_controller.rb'. Below is their contents:
370
+ 3. If addon has dependencies, they can be listed in `~/.straight/AddonsGemfile` and will be installed along with `straight-server` dependencies.
371
+
372
+
373
+ eval_gemfile '/home/app/.straight/addons/my_addon/Gemfile'
374
+
375
+ 4. In `./straight/addons/my_addon/lib/` we will place two files, `my_addon.rb` and 'my_controller.rb'. Below is their contents:
357
376
 
358
377
 
359
378
  # my_addon.rb