Class: ForestLiana::WorkflowExecutionsController

Inherits:
ApplicationController show all
Defined in:
app/controllers/forest_liana/workflow_executions_controller.rb

Constant Summary collapse

SKIPPED_HEADERS =

Never forwarded (request or response): hop-by-hop, Host, and body-framing headers. render json: re-serializes the body, so the upstream length/encoding no longer match — and forwarding accept-encoding would defeat Net::HTTP’s transparent gzip decompression.

%w[
  connection keep-alive transfer-encoding upgrade te trailer
  proxy-authenticate proxy-authorization host
  content-length content-encoding accept-encoding
].freeze
UNSAFE_PATH_FRAGMENTS =
['..', '%2e', '%2E', '\\', "\0"].freeze
OPEN_TIMEOUT_IN_SECONDS =
2
REQUEST_TIMEOUT_IN_SECONDS =
120
UPSTREAM_ERRORS =
[
  HTTParty::Error,
  SocketError,
  Errno::ECONNREFUSED,
  Net::OpenTimeout,
  Net::ReadTimeout,
  Timeout::Error,
  OpenSSL::SSL::SSLError
].freeze

Instance Method Summary collapse

Methods inherited from ApplicationController

#authenticate_user_from_jwt, #deactivate_count_response, #forest_user, #get_collection, #internal_server_error, papertrail?, #serialize_model, #serialize_models

Methods inherited from BaseController

#route_not_found

Instance Method Details

#proxyObject

Catch-all: forward any verb/sub-path verbatim to the executor, so a new executor route needs no change here.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'app/controllers/forest_liana/workflow_executions_controller.rb', line 29

def proxy
  base = ForestLiana.workflow_executor_url
  return head(:not_found) if base.blank?

  normalized_base = base.sub(%r{/+\z}, '')
  path = safe_executor_path
  return head(:not_found) if path.nil?
  return head(:not_found) unless same_origin?(normalized_base, path)

  response = HTTParty.send(
    request.request_method_symbol,
    "#{normalized_base}#{path}",
    headers: forwarded_request_headers,
    query: forwarded_query,
    body: forwarded_body,
    verify: Rails.env.production?,
    # Don't follow redirects: a 3xx Location to an off-origin host would bypass the origin guard.
    follow_redirects: false,
    open_timeout: OPEN_TIMEOUT_IN_SECONDS,
    timeout: REQUEST_TIMEOUT_IN_SECONDS
  )

  forward_response_headers(response)
  render json: response.parsed_response, status: response.code
rescue *UPSTREAM_ERRORS => e
  Rails.logger.error("[ForestLiana] workflow executor proxy error: #{e.class}: #{e.message}")
  render json: { error: 'workflow_executor_unreachable' }, status: :service_unavailable
end