Class: Sghtmltopdf::ServerClient

Inherits:
Object
  • Object
show all
Defined in:
lib/sghtmltopdf/server_client.rb

Overview

HTTPサーバモード(sghtmltopdf server)へ変換を委譲するクライアント。

Sghtmltopdf.configure { |c| c.server_url = "http://pdf.internal:8080" }
pdf = Sghtmltopdf.render(html, page_size: "A4")

Constant Summary collapse

DEFAULT_OPEN_TIMEOUT =
5
DEFAULT_READ_TIMEOUT =
120
CHUNK_SIZE =

一度に読むチャンクの目安。?stream=1のときはこの単位でブロックへ渡る。

64 * 1024

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url, open_timeout: nil, read_timeout: nil) ⇒ ServerClient

Returns a new instance of ServerClient.

Parameters:

  • url (String)

    サーバのベースURL(http://host:port)



23
24
25
26
27
# File 'lib/sghtmltopdf/server_client.rb', line 23

def initialize(url, open_timeout: nil, read_timeout: nil)
  @uri = parse(url)
  @open_timeout = (open_timeout || DEFAULT_OPEN_TIMEOUT).to_f
  @read_timeout = (read_timeout || DEFAULT_READ_TIMEOUT).to_f
end

Instance Attribute Details

#open_timeoutObject (readonly)

Returns the value of attribute open_timeout.



20
21
22
# File 'lib/sghtmltopdf/server_client.rb', line 20

def open_timeout
  @open_timeout
end

#read_timeoutObject (readonly)

Returns the value of attribute read_timeout.



20
21
22
# File 'lib/sghtmltopdf/server_client.rb', line 20

def read_timeout
  @read_timeout
end

#uriObject (readonly)

Returns the value of attribute uri.



20
21
22
# File 'lib/sghtmltopdf/server_client.rb', line 20

def uri
  @uri
end

Instance Method Details

#render(html, options, &block) ⇒ Object

HTMLをPDFへ変換する。

ブロックを渡すと?stream=1(chunked transfer encoding)を使い、 サーバがページを確定したそばからチャンクを渡す。ブロックが無ければ PDF全体をStringで返す。



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/sghtmltopdf/server_client.rb', line 34

def render(html, options, &block)
  request = build_request(html, options, stream: !block.nil?)
  pdf = nil
  start do |http|
    # `request`はブロック付きだとレスポンスオブジェクトを返すので、
    # 結果は外の変数で受ける。
    http.request(request) do |response|
      ensure_success!(response)
      if block
        response.read_body { |chunk| block.call(chunk.b) }
      else
        pdf = read_all(response)
      end
    end
  end
  pdf
end

#render_to_file(html, options, path) ⇒ Object

変換結果をpathへ書き出す。途中で失敗しても壊れたPDFを残さないよう、 一時ファイルへ書いてからrenameする(ネイティブ拡張のFileSinkと同じ 挙動に揃えている)。



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/sghtmltopdf/server_client.rb', line 55

def render_to_file(html, options, path)
  tmp = "#{path}.#{Process.pid}.tmp"
  begin
    File.open(tmp, "wb") do |file|
      render(html, options) { |chunk| file.write(chunk) }
    end
  rescue SystemCallError => e
    File.unlink(tmp) if File.exist?(tmp)
    raise InputError, "#{path}への書き出しに失敗しました: #{e.message}"
  rescue StandardError
    File.unlink(tmp) if File.exist?(tmp)
    raise
  end
  File.rename(tmp, path)
  nil
end