Class: MtaJson::Wrapper

Inherits:
Object
  • Object
show all
Defined in:
lib/mta_json/wrapper.rb

Overview

wraps calls to .mta-urls in a MTA-specific format. The main difference is:

  • the request body needs to have the surrounding [ ] removed (which technically represents a JSON-Array)

  • the response body needs [ ] added (again, a JSON-Array) which consists of:

    • body of the response

    • headers

MTA technically allows multiple parameters, but that doesn’t really suit rails’ named parameters (param).

Constant Summary collapse

CONTENT_TYPE =

env

'CONTENT_TYPE'.freeze
BODY =
'rack.input'.freeze
FORM_INPUT =
'rack.request.form_input'.freeze
FORM_HASH =
'rack.request.form_hash'.freeze
SESSION =
'rack.session'.freeze
METHOD =
'REQUEST_METHOD'.freeze
POST =
'POST'.freeze
PATH_INFO =
'PATH_INFO'.freeze
IP =
'REMOTE_ADDR'.freeze
CSRF_TOKEN =
'X-CSRF-Token'.freeze
CONTENT_LENGTH =

HTTP-Response-Headers

'Content-Length'.freeze
ALLOWED_METHODS =

Allowed Methods to be set by MTA

%w(GET)
ALLOWED_METHODS_PRIVATE =
%w(POST PUT DELETE)

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ Wrapper

Returns a new instance of Wrapper.



29
30
31
# File 'lib/mta_json/wrapper.rb', line 29

def initialize app
  @app = app
end

Instance Method Details

#call(env) ⇒ Object

callRemote on the MTA-side may have [0, 1 or 2] parameter(s):

  • if no parameters, params is empty within rails

  • first parameter - as a table - fills the params hash which is accessible in controllers (etc) i.e.

    callRemote("http://localhost/auth.mta", function, { name = 'a', password = 'b' })
    

    makes the following parameters available in the called controller

    params[:name] = 'a'
    params[:password] = 'b'
    
  • second parameter - as a table - options on how the request is handled. See update_options for details, for example { ‘method’ = ‘GET’ } allows GET-Requests, while usually callRemote does only POST-Requests.

This is unlike the PHP-SDK, which may have multiple parameters and allows access via numbers

$input = mta::getInput();
$name = $input[0];
$password = $input[1];

Rails has named parameters, so there’s no explicit support for them numbers.

callRemote for MTA should always call files ending with .mta, for example:

  • /auth => /auth.mta

This will call the related JSON-Methods, i.e.

respond_to do |format|
  format.html { ... } # certainly not this
  format.json { render :json => @object } # this gets called!
end

There is no support for elements and/or resources (yet?).



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/mta_json/wrapper.rb', line 60

def call env
  path = env[PATH_INFO]
  if path.end_with?('.mta') and (body = env[BODY].read).length != 0 and env[METHOD] == POST
    # replace ".mta" with ".json"
    env[PATH_INFO] = path[0..-5] + '.json'

    json = JSON.parse body
    raise Exception, "Number of JSON elements > 2: actual #{json.size}" if json.size > 2

    # optional options!
    update_options env, json[1].with_indifferent_access if json.size >= 2

    verify_request_method env

    # any parameters given? otherwise we don't really care for any params
    update_params env, json[0] if json.size >= 1 and json[0] != 0 # 0 is nil in terms of callRemote. JSON has 'null' though!

    # add some CSRF info... maybe.
    add_csrf_info env

    # call the other middlewares
    status, headers, response = @app.call(env)

    # alter only successful status codes to be more mta-ish
    if (200..299).include?(status)
      # mta /can/ handle multiple parameters as response.
      # We do not want and/or need this, but merely wrap the response body in square brackets as to return a single element
      # If render :json => @obj is used in the controller, this should make exactly @obj available in MTA.
      response = to_response(response, headers)

      # overwrite the length if already set
      if headers['Content-Length']
        headers['Content-Length'] = response.length
      end
    end

    return [status, headers, response]
  else
    # normal call, nevermind that whole mta business
    @app.call(env)
  end
end