jets 1.1.5 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/Gemfile.lock +10 -6
  4. data/README/testing.md +5 -1
  5. data/jets.gemspec +1 -0
  6. data/lib/jets.rb +5 -1
  7. data/lib/jets/application.rb +39 -19
  8. data/lib/jets/aws_services.rb +16 -10
  9. data/lib/jets/aws_services/stack_status.rb +7 -0
  10. data/lib/jets/booter.rb +6 -2
  11. data/lib/jets/builders/code_builder.rb +14 -0
  12. data/lib/jets/builders/handler_generator.rb +15 -0
  13. data/lib/jets/builders/shim_vars/app.rb +4 -3
  14. data/lib/jets/builders/shim_vars/shared.rb +8 -4
  15. data/lib/jets/builders/templates/shim.js +7 -3
  16. data/lib/jets/camelizer.rb +2 -1
  17. data/lib/jets/cfn/builders.rb +0 -1
  18. data/lib/jets/cfn/builders/api_deployment_builder.rb +27 -0
  19. data/lib/jets/cfn/builders/api_gateway_builder.rb +22 -2
  20. data/lib/jets/cfn/ship.rb +38 -6
  21. data/lib/jets/commands/call.rb +0 -1
  22. data/lib/jets/commands/call/guesser.rb +0 -3
  23. data/lib/jets/commands/clean/log.rb +18 -0
  24. data/lib/jets/commands/console.rb +1 -1
  25. data/lib/jets/commands/import/sequence.rb +2 -3
  26. data/lib/jets/commands/runner.rb +1 -1
  27. data/lib/jets/commands/sequence.rb +0 -1
  28. data/lib/jets/commands/templates/skeleton/config/application.rb.tt +11 -0
  29. data/lib/jets/commands/url.rb +32 -7
  30. data/lib/jets/controller/base.rb +21 -5
  31. data/lib/jets/controller/layout.rb +0 -3
  32. data/lib/jets/controller/middleware/local/api_gateway.rb +2 -5
  33. data/lib/jets/controller/middleware/local/mimic_aws_call.rb +2 -2
  34. data/lib/jets/controller/params.rb +42 -10
  35. data/lib/jets/controller/rack/adapter.rb +5 -2
  36. data/lib/jets/controller/rack/env.rb +17 -8
  37. data/lib/jets/controller/renderers/rack_renderer.rb +1 -1
  38. data/lib/jets/controller/rendering.rb +4 -1
  39. data/lib/jets/core.rb +8 -16
  40. data/lib/jets/internal/app/functions/jets/base_path.rb +153 -0
  41. data/lib/jets/klass.rb +38 -5
  42. data/lib/jets/lambda/dsl.rb +0 -2
  43. data/lib/jets/mega/request.rb +44 -13
  44. data/lib/jets/mega/request/source.rb +21 -0
  45. data/lib/jets/middleware/configurator.rb +1 -1
  46. data/lib/jets/middleware/default_stack.rb +2 -2
  47. data/lib/jets/resource.rb +1 -0
  48. data/lib/jets/resource/api_gateway.rb +5 -3
  49. data/lib/jets/resource/api_gateway/base_path.rb +5 -0
  50. data/lib/jets/resource/api_gateway/base_path/function.rb +42 -0
  51. data/lib/jets/resource/api_gateway/base_path/mapping.rb +44 -0
  52. data/lib/jets/resource/api_gateway/base_path/role.rb +76 -0
  53. data/lib/jets/resource/api_gateway/cors.rb +1 -1
  54. data/lib/jets/resource/api_gateway/deployment.rb +9 -5
  55. data/lib/jets/resource/api_gateway/domain_name.rb +56 -0
  56. data/lib/jets/resource/api_gateway/method.rb +3 -4
  57. data/lib/jets/resource/api_gateway/resource.rb +4 -3
  58. data/lib/jets/resource/api_gateway/rest_api.rb +42 -14
  59. data/lib/jets/resource/api_gateway/rest_api/change_detection.rb +42 -0
  60. data/lib/jets/resource/api_gateway/rest_api/logical_id.rb +59 -0
  61. data/lib/jets/resource/api_gateway/rest_api/routes.rb +127 -0
  62. data/lib/jets/resource/child_stack/api_deployment.rb +5 -1
  63. data/lib/jets/resource/function.rb +3 -20
  64. data/lib/jets/resource/function/environment.rb +23 -0
  65. data/lib/jets/resource/iam/application_role.rb +1 -1
  66. data/lib/jets/resource/route53.rb +3 -0
  67. data/lib/jets/resource/route53/record_set.rb +70 -0
  68. data/lib/jets/router.rb +2 -0
  69. data/lib/jets/ruby_server.rb +6 -3
  70. data/lib/jets/stack.rb +1 -3
  71. data/lib/jets/stack/main/dsl.rb +1 -1
  72. data/lib/jets/stack/main/extensions/lambda.rb +4 -2
  73. data/lib/jets/turbine.rb +0 -3
  74. data/lib/jets/version.rb +1 -1
  75. data/vendor/jets-gems/lib/jets/gems.rb +1 -0
  76. data/vendor/jets-gems/lib/jets/gems/agree.rb +41 -0
  77. data/vendor/jets-gems/lib/jets/gems/check.rb +15 -2
  78. metadata +30 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20fa97bccfb5b99e19a2edcf301bf31e53cd433a13862114fcb9648880e11fcc
4
- data.tar.gz: 124710223a460aed3a74a7498e2d2a15e5227c820d20a59db639ce83bdf2fb73
3
+ metadata.gz: 85ff84fd12cbc8c033636dae3eb3cf3b332389a28c611353a5167837622f7fc4
4
+ data.tar.gz: 492d4d772344cf8e329d02194a52aa6490bb7e47fb5f9e494332ee498f891be7
5
5
  SHA512:
6
- metadata.gz: d6ce23cf7b443de33af876d2ac178eaaa2faca79eb5b70188cedd726861478cb030f4dbcab3d03a894f271878a7d4b1923e9bef1555db97faebc4b34aa5cfb36
7
- data.tar.gz: b415939caba3f43bd03a5c10e47263ca2cd5adb0ebd01c7e76e495b3d09d25228863f51c83b9ece4eee865a0aa6ce5b64f1de3c6ac29234f55c0cde2d3ee0581
6
+ metadata.gz: 899243a605ac1e19c670b14967947605617b86ff347edda853742c091d62b5771a12222d0f34e834d680da4066ea4363eab677ae76ee9b35a87cd596ddec34b6
7
+ data.tar.gz: db515e009cda35564ae4c7fcf757d0fbbe910494a7427867ba6df725ed3b4cddbba308b33c34bbbc54b14ed38a4d2d60a950738b9ecdf1da3895d32e464898b0
@@ -3,6 +3,13 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [1.2.0]
7
+ - major upgrades: binary support, custom domain, bluegreen
8
+ - binary support
9
+ - custom domains support: http://rubyonjets.com/docs/routing-custom-domain/
10
+ - automated bluegreen deploy for api gateway when needed: http://rubyonjets.com/docs/blue-green-deployment/
11
+ - Merge pull request #84 from tongueroo/bluegreen
12
+
6
13
  ## [1.1.5]
7
14
  - Support multiple path parameters. Also allow path parameters to hold any value other than '/'.
8
15
  - Merge pull request #82 from adam-harwood/master
@@ -11,11 +11,12 @@ GIT
11
11
  PATH
12
12
  remote: .
13
13
  specs:
14
- jets (1.1.5)
14
+ jets (1.2.0)
15
15
  actionpack (>= 5.2.1)
16
16
  actionview (>= 5.2.1)
17
17
  activerecord (>= 5.2.1)
18
18
  activesupport (>= 5.2.1)
19
+ aws-sdk-apigateway
19
20
  aws-sdk-cloudformation
20
21
  aws-sdk-cloudwatchlogs
21
22
  aws-sdk-dynamodb
@@ -65,28 +66,31 @@ GEM
65
66
  tzinfo (~> 1.1)
66
67
  arel (9.0.0)
67
68
  aws-eventstream (1.0.1)
68
- aws-partitions (1.118.0)
69
+ aws-partitions (1.121.0)
70
+ aws-sdk-apigateway (1.23.0)
71
+ aws-sdk-core (~> 3, >= 3.39.0)
72
+ aws-sigv4 (~> 1.0)
69
73
  aws-sdk-cloudformation (1.13.0)
70
74
  aws-sdk-core (~> 3, >= 3.39.0)
71
75
  aws-sigv4 (~> 1.0)
72
76
  aws-sdk-cloudwatchlogs (1.12.0)
73
77
  aws-sdk-core (~> 3, >= 3.39.0)
74
78
  aws-sigv4 (~> 1.0)
75
- aws-sdk-core (3.41.0)
79
+ aws-sdk-core (3.42.0)
76
80
  aws-eventstream (~> 1.0)
77
81
  aws-partitions (~> 1.0)
78
82
  aws-sigv4 (~> 1.0)
79
83
  jmespath (~> 1.0)
80
- aws-sdk-dynamodb (1.17.0)
84
+ aws-sdk-dynamodb (1.18.0)
81
85
  aws-sdk-core (~> 3, >= 3.39.0)
82
86
  aws-sigv4 (~> 1.0)
83
87
  aws-sdk-kms (1.13.0)
84
88
  aws-sdk-core (~> 3, >= 3.39.0)
85
89
  aws-sigv4 (~> 1.0)
86
- aws-sdk-lambda (1.15.0)
90
+ aws-sdk-lambda (1.16.0)
87
91
  aws-sdk-core (~> 3, >= 3.39.0)
88
92
  aws-sigv4 (~> 1.0)
89
- aws-sdk-s3 (1.27.0)
93
+ aws-sdk-s3 (1.29.0)
90
94
  aws-sdk-core (~> 3, >= 3.39.0)
91
95
  aws-sdk-kms (~> 1)
92
96
  aws-sigv4 (~> 1.0)
@@ -16,7 +16,9 @@ To run the integration tests locally, you need to create a new Jets CRUD project
16
16
 
17
17
  jets new demo
18
18
  cd demo
19
+ # edit Gemfile to use the branch of jets being tested
19
20
  jets generate scaffold Post title:string
21
+ jets import:rails http://github.com/tongueroo/demo-rails.git
20
22
  jets server --no-reload
21
23
 
22
24
  Then you can run the postman tests:
@@ -40,12 +42,14 @@ Then you can deploy the jets app and test it on real AWS Lambda.
40
42
 
41
43
  Run the remote integration script:
42
44
 
45
+ eval "export $(cat demo/.env.development.remote)" # for DATABASE_URL for mega mode
43
46
  BASE_URL=xxx spec/integration/remote.sh
44
47
 
45
48
  Example:
46
49
 
50
+ eval "export $(cat demo/.env.development.remote)" # for DATABASE_URL for mega mode
47
51
  BASE_URL=https://wb5dcjc09a.execute-api.us-west-2.amazonaws.com/dev spec/integration/remote.sh
48
52
 
49
53
  ## Manual Test
50
54
 
51
- Test books create, update and delete manually until it's scripted.
55
+ Test books create, update and delete manually until it's scripted.
@@ -31,6 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.add_dependency "actionview", ">= 5.2.1"
32
32
  spec.add_dependency "activerecord", ">= 5.2.1"
33
33
  spec.add_dependency "activesupport", ">= 5.2.1"
34
+ spec.add_dependency "aws-sdk-apigateway"
34
35
  spec.add_dependency "aws-sdk-cloudformation"
35
36
  spec.add_dependency "aws-sdk-cloudwatchlogs"
36
37
  spec.add_dependency "aws-sdk-dynamodb"
@@ -1,8 +1,12 @@
1
1
  $:.unshift(File.expand_path("../", __FILE__))
2
2
  require "jets/version"
3
3
  require "jets/camelizer"
4
- require "active_support/core_ext/string"
4
+ require "active_support"
5
+ require "active_support/core_ext"
6
+ require "active_support/dependencies"
5
7
  require "active_support/ordered_hash"
8
+ require "active_support/ordered_options"
9
+ require "active_support/concern"
6
10
  require "colorize"
7
11
  require "fileutils"
8
12
  require "memoist"
@@ -1,4 +1,3 @@
1
- require "active_support/ordered_options"
2
1
  require "singleton"
3
2
  require "rack"
4
3
 
@@ -13,7 +12,10 @@ class Jets::Application
13
12
  end
14
13
 
15
14
  def setup!
16
- load_configs # load config object so following methods can use it
15
+ load_configs
16
+ end
17
+
18
+ def finish!
17
19
  load_inflections
18
20
  setup_auto_load_paths
19
21
  load_routes
@@ -31,14 +33,7 @@ class Jets::Application
31
33
  config = ActiveSupport::OrderedOptions.new
32
34
  config.project_name = project_name
33
35
  config.cors = true
34
- config.autoload_paths = %w[
35
- app/controllers
36
- app/models
37
- app/jobs
38
- app/rules
39
- app/helpers
40
- app/shared/resources
41
- ]
36
+ config.autoload_paths = default_autoload_paths
42
37
  config.extra_autoload_paths = []
43
38
 
44
39
  # function properties defaults
@@ -80,8 +75,14 @@ class Jets::Application
80
75
 
81
76
  config.api = ActiveSupport::OrderedOptions.new
82
77
  config.api.authorization_type = "NONE"
78
+ config.api.binary_media_types = ['multipart/form-data']
83
79
  config.api.endpoint_type = 'EDGE' # PRIVATE, EDGE, REGIONAL
84
80
 
81
+ config.domain = ActiveSupport::OrderedOptions.new
82
+ # config.domain.name = "#{Jets.project_namespace}.coolapp.com" # Default is nil
83
+ # config.domain.cert_arn = "..."
84
+ config.domain.endpoint_type = "REGIONAL" # EDGE or REGIONAL. Default to EDGE because CloudFormation update is faster
85
+
85
86
  config
86
87
  end
87
88
 
@@ -110,7 +111,14 @@ class Jets::Application
110
111
 
111
112
  def eval_app_config
112
113
  app_config = "#{Jets.root}config/application.rb"
113
- require app_config
114
+ load app_config # use load instead of require so reload_configs! works
115
+ end
116
+
117
+ # After the mimimal template gets build, we need to reload it for the full stack
118
+ # creation. This allows us to reference IAM policies configs that depend on the
119
+ # creation of the s3 bucket.
120
+ def reload_configs!
121
+ load_configs
114
122
  end
115
123
 
116
124
  def load_environments_config
@@ -129,12 +137,31 @@ class Jets::Application
129
137
 
130
138
  def setup_auto_load_paths
131
139
  autoload_paths = config.autoload_paths + config.extra_autoload_paths
132
- autoload_paths = autoload_paths.uniq.map { |p| "#{Jets.root}#{p}" }
133
140
  # internal_autoload_paths are last
134
141
  autoload_paths += internal_autoload_paths
135
142
  ActiveSupport::Dependencies.autoload_paths += autoload_paths
136
143
  end
137
144
 
145
+ # Essentially folders under app folder will be the default_autoload_paths. Example:
146
+ # app/controllers
147
+ # app/helpers
148
+ # app/jobs
149
+ # app/models
150
+ # app/rules
151
+ # app/shared/resources
152
+ def default_autoload_paths
153
+ paths = []
154
+ Dir.glob("#{Jets.root}app/*").each do |p|
155
+ p.sub!('./','')
156
+ paths << p unless exclude_autoload_path?(p)
157
+ end
158
+ paths
159
+ end
160
+
161
+ def exclude_autoload_path?(path)
162
+ path =~ %r{app/javascript} || path =~ %r{app/views}
163
+ end
164
+
138
165
  def internal_autoload_paths
139
166
  internal = File.expand_path("../internal", __FILE__)
140
167
  paths = %w[
@@ -175,13 +202,6 @@ class Jets::Application
175
202
  config.managed_policy_definitions ||= [] # default empty
176
203
  end
177
204
 
178
- # After the mimimal template gets build, we need to reload it for the full stack
179
- # creation. This allows us to reference IAM policies configs that depend on the
180
- # creation of the s3 bucket.
181
- def reload_configs!
182
- load_configs
183
- end
184
-
185
205
  def self.default_iam_policy
186
206
  project_namespace = Jets.project_namespace
187
207
  logs = {
@@ -1,3 +1,4 @@
1
+ require "aws-sdk-apigateway"
1
2
  require "aws-sdk-cloudformation"
2
3
  require "aws-sdk-cloudwatchlogs"
3
4
  require "aws-sdk-lambda"
@@ -11,21 +12,26 @@ module Jets::AwsServices
11
12
  include StackStatus
12
13
  extend Memoist
13
14
 
15
+ def apigateway
16
+ Aws::APIGateway::Client.new
17
+ end
18
+ memoize :apigateway
19
+
14
20
  def cfn
15
21
  Aws::CloudFormation::Client.new
16
22
  end
17
23
  memoize :cfn
18
24
 
19
- def logs
20
- Aws::CloudWatchLogs::Client.new
21
- end
22
- memoize :logs
23
-
24
25
  def lambda
25
26
  Aws::Lambda::Client.new
26
27
  end
27
28
  memoize :lambda
28
29
 
30
+ def logs
31
+ Aws::CloudWatchLogs::Client.new
32
+ end
33
+ memoize :logs
34
+
29
35
  def s3
30
36
  Aws::S3::Client.new
31
37
  end
@@ -36,13 +42,13 @@ module Jets::AwsServices
36
42
  end
37
43
  memoize :s3_resource
38
44
 
39
- def sts
40
- Aws::STS::Client.new
41
- end
42
- memoize :sts
43
-
44
45
  def sns
45
46
  Aws::SNS::Client.new
46
47
  end
47
48
  memoize :sns
49
+
50
+ def sts
51
+ Aws::STS::Client.new
52
+ end
53
+ memoize :sts
48
54
  end
@@ -48,5 +48,12 @@ module Jets::AwsServices
48
48
  true
49
49
  end
50
50
  end
51
+
52
+ # Lookup output value.
53
+ # Used in Jets::Resource::ApiGateway::RestApi::* andJets::Commands::Url
54
+ def lookup(outputs, key)
55
+ out = outputs.find { |o| o.output_key == key }
56
+ out&.output_value
57
+ end
51
58
  end
52
59
  end
@@ -7,10 +7,14 @@ class Jets::Booter
7
7
  confirm_jets_project!
8
8
  require_bundle_gems
9
9
  Jets::Dotenv.load!
10
- Jets.application # triggers Application.instance setup # autoload_paths, routes, etc
11
- setup_db
10
+
11
+ Jets.application.setup!
12
12
  app_initializers
13
13
  turbine_initializers
14
+ Jets.application.finish!
15
+
16
+ Jets.eager_load!
17
+ setup_db
14
18
  # build_middleware_stack # TODO: figure out how to build middleware during Jets.boot without breaking jets new and webpacker:install
15
19
 
16
20
  @booted = true
@@ -165,12 +165,26 @@ class Jets::Builders
165
165
  update_lazy_load_config # at the top, must be called before Jets.lazy_load? is used
166
166
  store_s3_base_url
167
167
  disable_webpacker_middleware
168
+ copy_internal_jets_code
168
169
  setup_tmp
169
170
  calculate_md5s # must be called before generate_node_shims and create_zip_files
170
171
  generate_node_shims
171
172
  create_zip_files
172
173
  end
173
174
 
175
+ # We copy the files into the project because we cannot require simple functions
176
+ # directly since they are wrapped by an anonymous class.
177
+ # TODO: Do this with the other files we required the same way.
178
+ def copy_internal_jets_code
179
+ files = []
180
+ files.each do |relative_path|
181
+ src = File.expand_path("../internal/#{relative_path}", File.dirname(__FILE__))
182
+ dest = "#{full(tmp_code)}/#{relative_path}"
183
+ FileUtils.mkdir_p(File.dirname(dest))
184
+ FileUtils.cp(src, dest)
185
+ end
186
+ end
187
+
174
188
  def update_lazy_load_config
175
189
  size_limit = AWS_CODE_SIZE_LIMIT
176
190
  code_size = dir_size(full(tmp_code))
@@ -18,6 +18,7 @@ class Jets::Builders
18
18
  app_ruby_shims
19
19
  poly_shims
20
20
  shared_shims
21
+ internal_shims
21
22
  end
22
23
 
23
24
  def app_ruby_shims
@@ -67,6 +68,20 @@ class Jets::Builders
67
68
  end
68
69
  end
69
70
 
71
+ def internal_shims
72
+ jets_base_path if Jets.custom_domain?
73
+ end
74
+
75
+ def jets_base_path
76
+ path = "jets/base_path.rb"
77
+ internal = File.expand_path("../internal", File.dirname(__FILE__))
78
+ src = "#{internal}/app/functions/#{path}"
79
+ result = Jets::Erb.result(src, stage_name: Jets::Resource::ApiGateway::Deployment.stage_name)
80
+ dest = "#{tmp_code}/handlers/functions/#{path}"
81
+ FileUtils.mkdir_p(File.dirname(dest))
82
+ IO.write(dest, result)
83
+ end
84
+
70
85
  # app/shared/functions/kevin.py => /tmp/jets/demo/app_root/handlers/shared/functions/kevin.py
71
86
  def copy_source_as_handler(fun)
72
87
  source_path = fun.source_file
@@ -6,9 +6,9 @@
6
6
  #
7
7
  # Implements:
8
8
  #
9
- # functions
10
- # handler_for(function_name)
11
- # js_path
9
+ # functions: IE [:index, :show]
10
+ # handler_for(function_name): IE handlers/controllers/posts_controller.index
11
+ # js_path: IE: handlers/controllers/posts_controller.js
12
12
  #
13
13
  module Jets::Builders::ShimVars
14
14
  class App < Base
@@ -61,6 +61,7 @@ module Jets::Builders::ShimVars
61
61
  end
62
62
 
63
63
  # This gets called in the node shim js template
64
+ # IE handlers/controllers/posts_controller.index
64
65
  def handler_for(meth)
65
66
  # possibly not include _function
66
67
  underscored_name = @relative_path.sub(%r{app/(\w+)/},'').sub('.rb','')
@@ -6,9 +6,9 @@
6
6
  #
7
7
  # Implements:
8
8
  #
9
- # functions
10
- # handler_for(function_name)
11
- # js_path
9
+ # functions: IE [:index, :show]
10
+ # handler_for(function_name): IE handlers/controllers/posts_controller.index
11
+ # js_path: IE: handlers/controllers/posts_controller.js
12
12
  #
13
13
  module Jets::Builders::ShimVars
14
14
  class Shared < Base
@@ -17,15 +17,19 @@ module Jets::Builders::ShimVars
17
17
  @fun = fun
18
18
  end
19
19
 
20
+ # Always only one element for shared functions
21
+ # functions: IE [:handle]
20
22
  def functions
21
23
  [@fun.meth] # function_names
22
24
  end
23
25
 
24
- # dont need function_name arg but keeping the same interface as parent class
26
+ # Dont need function_name arg but keeping the same interface as parent class
27
+ # IE handlers/shared/functions/bob.handle
25
28
  def handler_for(function_name)
26
29
  @fun.handler_dest
27
30
  end
28
31
 
32
+ # IE handlers/shared/functions/bob.js
29
33
  def js_path
30
34
  @fun.handler_dest
31
35
  end
@@ -179,23 +179,27 @@ const once = async () => {
179
179
  // currying function to make handler code prettier
180
180
  function handler(full_handler_name) {
181
181
  return function(event, context, callback) {
182
- request(event, full_handler_name, callback);
182
+ request(event, context, full_handler_name, callback);
183
183
  };
184
184
  }
185
185
 
186
186
  ////////////////////////////////////////////////////////////////////////////////
187
187
  // main logic for handler
188
- function request(event, handler, callback) {
188
+ function request(event, context, handler, callback) {
189
189
  truncate(JETS_OUTPUT);
190
190
  truncate(TMP_LOG_PATH);
191
191
 
192
192
  log("event:");
193
193
  log(event);
194
+ log("context:");
195
+ log(context);
194
196
  var client = new net.Socket();
195
197
  client.connect(8080, '127.0.0.01', function() {
196
198
  log('Connected to socket');
197
199
  client.write(JSON.stringify(event));
198
200
  client.write("\r\n"); // important: \r\n is how server knows input is done
201
+ client.write(JSON.stringify(context));
202
+ client.write("\r\n"); // important: \r\n is how server knows input is done
199
203
  client.write(handler);
200
204
  client.write("\r\n"); // important: \r\n is how server knows input is done
201
205
  });
@@ -260,7 +264,7 @@ function request(event, handler, callback) {
260
264
  truncate(TMP_LOG_PATH);
261
265
 
262
266
  log("Retrying request NOW");
263
- request(event, handler, callback);
267
+ request(event, context, handler, callback);
264
268
  }, 500);
265
269
  });
266
270
  }