Class: Hatetepe::Builder
- Inherits:
-
Object
- Object
- Hatetepe::Builder
- Defined in:
- lib/hatetepe/builder.rb
Instance Attribute Summary collapse
-
#state ⇒ Object
readonly
Returns the value of attribute state.
Class Method Summary collapse
Instance Method Summary collapse
- #body(body) ⇒ Object
- #body_chunk(chunk) ⇒ Object
- #chunked? ⇒ Boolean
- #complete ⇒ Object
- #error(message) ⇒ Object
- #header(name, value) ⇒ Object
- #headers(hash) ⇒ Object
-
#initialize(&block) ⇒ Builder
constructor
A new instance of Builder.
- #raw_header(header) ⇒ Object
- #ready? ⇒ Boolean
- #request(req) ⇒ Object
- #request_line(verb, uri, version = "1.1") ⇒ Object
- #reset ⇒ Object
- #response(res) ⇒ Object
- #response_line(code, version = "1.1") ⇒ Object
- #write(data) ⇒ Object
- #writing_body? ⇒ Boolean
- #writing_headers? ⇒ Boolean
- #writing_trailing_headers? ⇒ Boolean
Constructor Details
#initialize(&block) ⇒ Builder
Returns a new instance of Builder.
21 22 23 24 25 26 27 28 |
# File 'lib/hatetepe/builder.rb', line 21 def initialize(&block) reset @on_write, @on_complete, @on_error = [], [], [] if block block.arity == 0 ? instance_eval(&block) : block.call(self) end end |
Instance Attribute Details
#state ⇒ Object (readonly)
Returns the value of attribute state.
19 20 21 |
# File 'lib/hatetepe/builder.rb', line 19 def state @state end |
Class Method Details
.build(&block) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/hatetepe/builder.rb', line 7 def self.build(&block) = "" builder = new do |b| b.on_write {|data| << data } end block.arity == 0 ? builder.instance_eval(&block) : block.call(builder) builder.complete return .empty? ? nil : end |
Instance Method Details
#body(body) ⇒ Object
120 121 122 123 |
# File 'lib/hatetepe/builder.rb', line 120 def body(body) body.each {|c| body_chunk c } # XXX complete here? end |
#body_chunk(chunk) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/hatetepe/builder.rb', line 125 def body_chunk(chunk) if ready? error "A request or response line and headers are required before writing body" elsif writing_trailing_headers? error "Cannot write body after trailing headers" elsif writing_headers? if @chunked.nil? header "Transfer-Encoding", "chunked" end write "\r\n" @state = :writing_body end chunk = chunk.to_s if chunked? write "#{chunk.bytesize.to_s(16)}\r\n#{chunk}\r\n" else write chunk unless chunk.empty? end end |
#chunked? ⇒ Boolean
59 60 61 |
# File 'lib/hatetepe/builder.rb', line 59 def chunked? @chunked end |
#complete ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/hatetepe/builder.rb', line 146 def complete if ready? return elsif writing_headers? && @chunked.nil? header "Content-Length", "0" end body_chunk "" on_complete.each {|blk| blk.call } reset end |
#error(message) ⇒ Object
162 163 164 165 166 167 168 169 |
# File 'lib/hatetepe/builder.rb', line 162 def error() exception = BuilderError.new() unless on_error.empty? on_error.each {|blk| blk.call exception } else raise exception end end |
#header(name, value) ⇒ Object
93 94 95 96 |
# File 'lib/hatetepe/builder.rb', line 93 def header(name, value) value = String(value) raw_header "#{name}: #{value}" unless value.empty? end |
#headers(hash) ⇒ Object
98 99 100 |
# File 'lib/hatetepe/builder.rb', line 98 def headers(hash) hash.each {|k, v| header k, v } end |
#raw_header(header) ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/hatetepe/builder.rb', line 102 def raw_header(header) if ready? error "A request or response line is required before writing headers" elsif writing_body? error "Trailing headers require chunked transfer encoding" unless chunked? write "0\r\n" @state = :writing_trailing_headers end if @chunked.nil? && header[0..13] == "Content-Length" @chunked = false elsif @chunked.nil? && header[0..16] == "Transfer-Encoding" @chunked = true end write "#{header}\r\n" end |
#ready? ⇒ Boolean
43 44 45 |
# File 'lib/hatetepe/builder.rb', line 43 def ready? state == :ready end |
#request(req) ⇒ Object
63 64 65 66 67 68 |
# File 'lib/hatetepe/builder.rb', line 63 def request(req) request_line req[0], req[1], (req[4] || "1.1") headers req[2] body req[3] if req[3] complete end |
#request_line(verb, uri, version = "1.1") ⇒ Object
70 71 72 73 74 |
# File 'lib/hatetepe/builder.rb', line 70 def request_line(verb, uri, version = "1.1") complete unless ready? write "#{verb.upcase} #{uri} HTTP/#{version}\r\n" @state = :writing_headers end |
#reset ⇒ Object
30 31 32 33 |
# File 'lib/hatetepe/builder.rb', line 30 def reset @state = :ready @chunked = nil end |
#response(res) ⇒ Object
76 77 78 79 80 81 |
# File 'lib/hatetepe/builder.rb', line 76 def response(res) response_line res[0], (res[3] || "1.1") headers res[1] body res[2] if res[2] complete end |
#response_line(code, version = "1.1") ⇒ Object
83 84 85 86 87 88 89 90 91 |
# File 'lib/hatetepe/builder.rb', line 83 def response_line(code, version = "1.1") complete unless ready? unless status = Rack::Utils::HTTP_STATUS_CODES[code] error "Unknown status code: #{code}" end write "HTTP/#{version} #{code} #{status}\r\n" @state = :writing_headers end |
#write(data) ⇒ Object
158 159 160 |
# File 'lib/hatetepe/builder.rb', line 158 def write(data) on_write.each {|blk| blk.call data } end |
#writing_body? ⇒ Boolean
51 52 53 |
# File 'lib/hatetepe/builder.rb', line 51 def writing_body? state == :writing_body end |
#writing_headers? ⇒ Boolean
47 48 49 |
# File 'lib/hatetepe/builder.rb', line 47 def writing_headers? state == :writing_headers end |
#writing_trailing_headers? ⇒ Boolean
55 56 57 |
# File 'lib/hatetepe/builder.rb', line 55 def writing_trailing_headers? state == :writing_trailing_headers end |