class UnixRack::Socket
Attributes
hdr_method[RW]
headers[RW]
sock[RW]
Public Class Methods
close(io)
click to toggle source
# File lib/unixrack.rb, line 69 def self.close(io) io.close end
new(sock)
click to toggle source
# File lib/unixrack.rb, line 44 def initialize(sock) TCPSocket.do_not_reverse_lookup = true @sock = sock @buff = "" end
read_sock_num_bytes(sock, num, log = lambda { |x| x })
click to toggle source
# File lib/unixrack.rb, line 73 def self.read_sock_num_bytes(sock, num, log = lambda { |x| x }) retval = [false, ''] buff = "" num_left = num while true begin #log("PRE Doing sysread") numr = num_left < 32768 ? num_left : 32768 dat = sock.sysread(numr) #log("Doing sysread #{dat.inspect}") buff = buff + dat if buff.length == num retval = [true, buff] break else num_left = num_left - dat.length end rescue Errno::EINTR # Ruby threading can cause an alarm/timer interrupt on a syscall retry rescue EOFError retval = [false, "EOF", buff] break rescue Errno::ECONNRESET, Errno::EPIPE, Errno::EINVAL, Errno::EBADF retval = [false, "Exception occurred on socket read"] #log("Got an #{$!} from socket read") break end end retval end
write_buff(io, buff)
click to toggle source
# File lib/unixrack.rb, line 54 def self.write_buff(io, buff) nwritten = 0 out_buff = buff # buff could be UTF-8 while true nw = io.syswrite(out_buff) nwritten = nwritten + nw break if nw == out_buff.bytesize out_buff = out_buff.byteslice(nw..-1) end nwritten end
Public Instance Methods
do_read()
click to toggle source
# File lib/unixrack.rb, line 105 def do_read begin dat = @sock.sysread(16384) rescue Errno::EINTR # Ruby threading can cause an alarm/timer interrupt on a syscall retry rescue EOFError puts "#{$$}: Got an EOF from socket read" $stdout.flush return nil rescue Errno::ECONNRESET, Errno::EPIPE, Errno::EINVAL, Errno::EBADF puts "#{$$}: Got an #{$!} from socket read" $stdout.flush exit! 0 end @buff = @buff + dat return @buff end
peeraddr()
click to toggle source
# File lib/unixrack.rb, line 50 def peeraddr @sock.peeraddr end
read_content()
click to toggle source
# File lib/unixrack.rb, line 123 def read_content cont_len = @headers['Content-Length'].to_i #if cont_len < (8 * 1024 * 1024) if cont_len < (1024 * 1024) # Small file, just use mem while true if @buff.length == cont_len f = StringIO.new(@buff) @buff = "" return f end return nil if not do_read end else # Large file, use disk f = nil tmpname = "./.__tmp__unixrack_upload__#{$$}.tmp" begin tmpfd = IO.sysopen(tmpname, File::RDWR | File::CREAT | File::EXCL, 0600) f = IO.new(tmpfd, "w+") File.unlink(tmpname) rescue p $! $stdout.flush return nil end # Write what we already have len = @buff.length if len > 0 f.syswrite(@buff) @buff = "" end while true if len == cont_len f.rewind return f end return nil if not do_read len += @buff.length f.syswrite(@buff) @buff = "" end end end
read_headers()
click to toggle source
# File lib/unixrack.rb, line 173 def read_headers while true r = do_read break if @buff.index "\r\n\r\n" return false if r == nil end a, b = @buff.split("\r\n\r\n", 2) @buff = b @hdr_buff = a @hdr_lines = @hdr_buff.split("\r\n") @hdr_method_line = @hdr_lines[0] @hdr_method = @hdr_method_line.split(" ") @hdr_field_lines = @hdr_lines.slice(1..-1) # would prefer first, and rest headers = @hdr_field_lines.inject({}) { |h, line| k, v = line.split(": "); h[k] = v; h } @headers = canonicalize_headers(headers) true end
Private Instance Methods
canonicalize_headers(headers)
click to toggle source
# File lib/unixrack.rb, line 197 def canonicalize_headers(headers) headers.keys.each do |key| headers[key.split(/-/).map(&:capitalize).join('-')] = headers.delete(key) end headers end