Class: Onlyoffice::DocsIntegrationSdk::DocumentServer::Client

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/onlyoffice/docs_integration_sdk/document_server/client.rb,
lib/onlyoffice/docs_integration_sdk/document_server/client/ua.rb,
lib/onlyoffice/docs_integration_sdk/document_server/client/jwt.rb,
lib/onlyoffice/docs_integration_sdk/document_server/client/command.rb,
lib/onlyoffice/docs_integration_sdk/document_server/client/service.rb,
lib/onlyoffice/docs_integration_sdk/document_server/client/response.rb,
lib/onlyoffice/docs_integration_sdk/document_server/client/conversion.rb,
lib/onlyoffice/docs_integration_sdk/document_server/client/healthcheck.rb

Overview

Client is a class that provides a way to interact with the Document Server API. It acts as a wrapper around the Net::HTTP class, offering a more convenient method for interacting with the API.

Since:

  • 0.1.0

Defined Under Namespace

Modules: CommandServing, ConversionServing, HealthcheckServing Classes: CommandService, ConversionService, HealthcheckService, Jwt, Response, Service

Constant Summary collapse

USER_AGENT =

Since:

  • 0.1.0

T.let("com.onlyoffice.docs-integration-sdk-ruby #{VERSION}", String)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(http: nil, base_uri: nil, user_agent: nil) ⇒ void

initialize initializes a new Client instance. It requires either http or base_uri to be provided. If only one of them is provided, the other one will be built from the provided one. If user_agent is not provided, it will default to the USER_AGENT constant. It makes a shallow copy of the provided instances.

Parameters:

  • http (Net::HTTP, nil) (defaults to: nil) —

    The Net::HTTP instance that is used to make requests to the Document Server.

  • base_uri (URI::HTTP, nil) (defaults to: nil) —

    The base URI of the Document Server.

  • user_agent (String, nil) (defaults to: nil) —

    The User-Agent that is used to make requests to the Document Server.

Raises:

  • (ArgumentError) —

    If neither http nor base_uri is provided.

Since:

  • 0.1.0



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/onlyoffice/docs_integration_sdk/document_server/client.rb', line 117

def initialize(http: nil, base_uri: nil, user_agent: nil)
  if !http && !base_uri
    raise ArgumentError, "Either http or base_uri must be provided"
  end

  if http && base_uri
    @http = T.let(http.clone, Net::HTTP)
    @base_uri = T.let(base_uri.clone, URI::HTTP)
  elsif http
    @http = T.let(http.clone, Net::HTTP)
    @base_uri = T.let(URI::HTTP.build(host: @http.address, port: @http.port), URI::HTTP)
  elsif base_uri
    @http = T.let(Net::HTTP.new(base_uri.host, base_uri.port), Net::HTTP)
    @base_uri = T.let(base_uri.clone, URI::HTTP)
  else
    # :nocov:
    # unreachable
    # :nocov:
  end

  if user_agent
    @user_agent = T.let(user_agent, String)
  else
    @user_agent = T.let(USER_AGENT, String)
  end

  @command = T.let(CommandService.new(client: self), CommandService)
  @conversion = T.let(ConversionService.new(client: self), ConversionService)
  @healthcheck = T.let(HealthcheckService.new(client: self), HealthcheckService)
end

Instance Attribute Details

#command ⇒ CommandService (readonly)

command is a CommandService that is used to interact with the Command Service API.

Returns:

Since:

  • 0.1.0



83
84
85
# File 'lib/onlyoffice/docs_integration_sdk/document_server/client.rb', line 83

def command
  @command
end

#conversion ⇒ ConversionService (readonly)

conversion is a ConversionService that is used to interact with the Conversion Service API.

Returns:

Since:

  • 0.1.0



90
91
92
# File 'lib/onlyoffice/docs_integration_sdk/document_server/client.rb', line 90

def conversion
  @conversion
end

#healthcheck ⇒ HealthcheckService (readonly)

healthcheck is a HealthcheckService that is used to interact with the Healthcheck Service API.

Returns:

Since:

  • 0.1.0



97
98
99
# File 'lib/onlyoffice/docs_integration_sdk/document_server/client.rb', line 97

def healthcheck
  @healthcheck
end

Instance Method Details

#base_uri ⇒ URI::HTTP

base_uri is a base URL of the Document Server. It is used to build the full URL of the request. It stores a shallow copy of the original instance.

Returns:

  • (URI::HTTP)

Since:

  • 0.1.0



65
66
67
# File 'lib/onlyoffice/docs_integration_sdk/document_server/client.rb', line 65

def base_uri
  @base_uri.clone
end

#do(req) ⇒ Array(T.untyped, Response)

do makes a request to the Document Server. It returns a tuple with the body of the response and the response instance.

Parameters:

  • req (Net::HTTPRequest) —

    The Net::HTTPRequest that is used to make the request.

Returns:

  • (Array(T.untyped, Response)) —

    A tuple with the body of the response and the response instance.

Since:

  • 0.1.0



299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'lib/onlyoffice/docs_integration_sdk/document_server/client.rb', line 299

def do(req)
  err = T.let(nil, T.untyped)
  b = T.let(nil, T.untyped)

  # Document Server always returns a response with the status 200, so
  # there is no need to check for any other statuses.

  raw = T.let(@http.request(req), Net::HTTPResponse)

  begin
    b = JSON.parse(raw.body)
  rescue StandardError => e
    err = e
  end

  res = Response.new(request: req, response: raw, error: err)

  [b, res]
end

#get(p) ⇒ Array(T.untyped, Response)

get makes a GET request to the Document Server. It is a wrapper around the #uri, #request and #do methods.

Parameters:

  • p (String) —

    The path to join with the base URI.

Returns:

Since:

  • 0.1.0



231
232
233
234
235
# File 'lib/onlyoffice/docs_integration_sdk/document_server/client.rb', line 231

def get(p)
  u = uri(p)
  r = request(Net::HTTP::Get, u)
  self.do(r)
end

#http ⇒ Net::HTTP

http is a Net::HTTP that is used to make requests to the Document Server. This should only be used for requests to the Document Server, because requests may contain a JWT token. It stores a shallow copy of the original instance.

Returns:

  • (Net::HTTP)

Since:

  • 0.1.0



49
50
51
# File 'lib/onlyoffice/docs_integration_sdk/document_server/client.rb', line 49

def http
  @http.clone
end

#post(p, b = nil) ⇒ Array(T.untyped, Response)

post makes a POST request to the Document Server. It is a wrapper around the #uri, #request and #do methods.

Parameters:

  • p (String) —

    The path to join with the base URI.

  • b (T.untyped) (defaults to: nil) —

    The body of the request.

Returns:

Since:

  • 0.1.0



245
246
247
248
249
# File 'lib/onlyoffice/docs_integration_sdk/document_server/client.rb', line 245

def post(p, b = nil)
  u = uri(p)
  r = request(Net::HTTP::Post, u, b)
  self.do(r)
end

#request(m, u, b = nil) ⇒ Net::HTTPRequest

request creates a new Net::HTTPRequest instance with the provided method, URI, and body.

Parameters:

  • m (T.class_of(Net::HTTPRequest)) —

    The method of the request.

  • u (URI::HTTP) —

    The URI of the request.

  • b (T.untyped) (defaults to: nil) —

    The body of the request.

Returns:

  • (Net::HTTPRequest) —

    A new Net::HTTPRequest instance.

Since:

  • 0.1.0



274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/onlyoffice/docs_integration_sdk/document_server/client.rb', line 274

def request(m, u, b = nil)
  r = m.new(u)

  r["Accept"] = "application/json"
  r["User-Agent"] = @user_agent

  if b
    r["Content-Type"] = "application/json"
    r.body = b.to_json
  end

  r
end

#uri(p) ⇒ URI::HTTP

uri creates a new URI::HTTP instance by joining the base URI with the provided path.

Parameters:

  • p (String) —

    The path to join with the base URI.

Returns:

  • (URI::HTTP) —

    A new URI::HTTP instance.

Since:

  • 0.1.0



258
259
260
261
262
263
# File 'lib/onlyoffice/docs_integration_sdk/document_server/client.rb', line 258

def uri(p)
  # The URI.join returns a URI in the same implementation as the first
  # argument. Therefore, calling T.cast is safe because the @base_url is a
  # URI::HTTP and the result will be a URI::HTTP.
  T.cast(URI.join(@base_uri.to_s, p), URI::HTTP)
end

#user_agent ⇒ String

user_agent is a User-Agent that is used to make requests to the Document Server.

Returns:

  • (String)

Since:

  • 0.1.0



74
75
76
# File 'lib/onlyoffice/docs_integration_sdk/document_server/client.rb', line 74

def user_agent
  @user_agent
end

#with_jwt(jwt) ⇒ Client

with_jwt creates a new Client instance with the provided JWT configuration. It modifies the Net::HTTP#request method to add the JWT token to the request. The JWT token is added to the request based on the locations provided in the JWT configuration.

Parameters:

  • jwt (Jwt) —

    The JWT configuration that is used to sign requests.

Returns:

  • (Client) —

    A new Client instance with the JWT configuration applied.

Since:

  • 0.1.0



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/onlyoffice/docs_integration_sdk/document_server/client.rb', line 157

def with_jwt(jwt)
  # The idea of this approach has its roots in the practice of Go, where
  # you can implement your own http.Transport. Unfortunately, Ruby does
  # not have a direct equivalent of http.Transport, so you have to create
  # a sort of patch for the request method.
  #
  # https://pkg.go.dev/net/http@go1.23.5/#Transport
  # https://github.com/ruby/ruby/blob/v3_4_1/lib/net/http.rb/#L2367

  r = @http.method(:request)
  c = copy

  c.http!.define_singleton_method(:request) do |req, body = nil, &block|
    req = T.let(req.clone, Net::HTTPRequest)

    if (req.body || req.body_stream) && body
      # Leave it untouched so Ruby can raise an error.
      # https://github.com/ruby/ruby/blob/v3_4_1/lib/net/http/generic_request.rb/#L186
    elsif req.body
      if !jwt.locations.empty?
        b = JSON.parse(req.body)

        if jwt.locations.include?(Jwt::Location::Header)
          p = jwt.jwt.encode_header(b)
          req[jwt.header] = "#{jwt.schema} #{p}"
        end

        if jwt.locations.include?(Jwt::Location::Body)
          p = jwt.jwt.encode_body(b)
          req.body = p.to_json
        end
      end
    elsif req.body_stream
      # There are doubts regarding the necessity of implementing this
      # branch.
    elsif body
      if !jwt.locations.empty?
        b = JSON.parse(body)

        if jwt.locations.include?(Jwt::Location::Header)
          p = jwt.jwt.encode_header(b)
          req[jwt.header] = "#{jwt.schema} #{p}"
        end

        if jwt.locations.include?(Jwt::Location::Body)
          p = jwt.jwt.encode_body(b)
          body = p.to_json
        end
      end
    end

    r.call(req, body, &block)
  end

  c
end