class Knjappserver::Httpsession::Contentgroup
This class handels the adding of content and writing to socket. Since this can be done with multiple threads and multiple IO's it can get complicated.
Constants
- NL
Attributes
chunked[RW]
cur_data[R]
done[R]
socket[RW]
Public Class Methods
new(args = {})
click to toggle source
# File lib/include/class_httpsession_contentgroup.rb, line 9 def initialize(args = {}) @socket = args[:socket] @chunked = args[:chunked] @resp = args[:resp] @httpsession = args[:httpsession] @mutex = Mutex.new @debug = false end
Public Instance Methods
force_content(newcont)
click to toggle source
Forces the content to be the input - nothing else can be added after calling this.
# File lib/include/class_httpsession_contentgroup.rb, line 48 def force_content(newcont) @ios = [{:str => newcont, :done => true}] end
init()
click to toggle source
# File lib/include/class_httpsession_contentgroup.rb, line 18 def init @done = false @thread = nil @cur_data = { :str => "", :done => false } @ios = [@cur_data] end
join()
click to toggle source
# File lib/include/class_httpsession_contentgroup.rb, line 111 def join return nil if @forced sleep 0.1 while !@thread @thread.join end
mark_done()
click to toggle source
# File lib/include/class_httpsession_contentgroup.rb, line 106 def mark_done @cur_data[:done] = true @done = true end
new_io(obj = "")
click to toggle source
# File lib/include/class_httpsession_contentgroup.rb, line 41 def new_io(obj = "") @cur_data[:done] = true if @cur_data @cur_data = {:str => obj, :done => false} @ios << @cur_data end
new_thread()
click to toggle source
# File lib/include/class_httpsession_contentgroup.rb, line 57 def new_thread cgroup = Knjappserver::Httpsession::Contentgroup.new(:socket => @socket, :chunked => @chunked) cgroup.init @mutex.synchronize do @ios << cgroup self.new_io end self.register_thread return cgroup end
register_thread()
click to toggle source
# File lib/include/class_httpsession_contentgroup.rb, line 52 def register_thread Thread.current[:knjappserver] = {} if !Thread.current[:knjappserver] Thread.current[:knjappserver][:contentgroup] = self end
reset()
click to toggle source
# File lib/include/class_httpsession_contentgroup.rb, line 28 def reset @ios = [] @done = false @thread = nil @forced = false @mutex.synchronize do self.new_io end self.register_thread end
write(cont)
click to toggle source
# File lib/include/class_httpsession_contentgroup.rb, line 78 def write(cont) @mutex.synchronize do @cur_data[:str] << cont end end
write_begin()
click to toggle source
# File lib/include/class_httpsession_contentgroup.rb, line 70 def write_begin begin @resp.write if @httpsession.meta["METHOD"] != "HEAD" rescue Errno::ECONNRESET, Errno::ENOTCONN, Errno::EPIPE #Ignore - the user probaly left. end end
write_force()
click to toggle source
# File lib/include/class_httpsession_contentgroup.rb, line 94 def write_force @mutex.synchronize do @forced = true if !@thread end if @thread @thread.join else self.write_begin end end
write_output()
click to toggle source
# File lib/include/class_httpsession_contentgroup.rb, line 84 def write_output return nil if @thread @mutex.synchronize do @thread = Thread.new do self.write_begin end end end
write_to_socket()
click to toggle source
# File lib/include/class_httpsession_contentgroup.rb, line 117 def write_to_socket count = 0 @ios.each do |data| if data.is_a?(Knjappserver::Httpsession::Contentgroup) data.write_to_socket elsif data.key?(:str) if data[:str].is_a?(Hash) and data[:str][:type] == :file File.open(data[:str][:path], "r") do |file| loop do begin buf = file.sysread(16384) rescue EOFError break end if @chunked @socket.write("#{buf.length.to_s(16)}#{NL}#{buf}#{NL}") else @socket.write(buf) end end end else loop do break if data[:done] and data[:str].size <= 0 sleep 0.1 while data[:str].size < 512 and !data[:done] str = nil @mutex.synchronize do str = data[:str].bytes data[:str] = "" end #512 could take a long time for big pages. 16384 seems to be an optimal number. str.each_slice(16384) do |slice| buf = slice.pack("C*") if @chunked @socket.write("#{buf.length.to_s(16)}#{NL}#{buf}#{NL}") else @socket.write(buf) end end end end else raise "Unknown object: '#{data.class.name}'." end end count += 1 end