Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby Systems Programming

Ruby Systems Programming

From Ruby on Ales 2013

Andy Delcambre

March 08, 2013
Tweet

More Decks by Andy Delcambre

Other Decks in Programming

Transcript

  1. “operate and control the computer hardware and to provide a

    platform for running application software” http://en.wikipedia.org/wiki/System_software Monday, March 11, 13
  2. $ lsof -p 34866 -a -i COMMAND PID TYPE NODE

    NAME ruby 34866 IPv4 TCP 127.0.0.1:80 (LISTEN) ruby 34866 IPv4 TCP 127.0.0.1:80->127.0.0.1:61898 (ESTABLISHED) Monday, March 11, 13
  3. HTTP Response HTTP/1.1 200 OK Date: Tue, 05 Mar 2013

    23:03:52 GMT Cache-Control: private, max-age=0 Content-Type: text/html Server: gws Transfer-Encoding: chunked <data> Monday, March 11, 13
  4. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end Monday, March 11, 13
  5. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end Require the socket lib Monday, March 11, 13
  6. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end Some constants for later Monday, March 11, 13
  7. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end socket = Socket.new(:INET, :STREAM) Monday, March 11, 13
  8. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) Monday, March 11, 13
  9. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end socket.listen(5) Monday, March 11, 13
  10. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end while client_socket = socket.accept[0] Monday, March 11, 13
  11. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end path = client_socket.recv(1024).split[1] Monday, March 11, 13
  12. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end path = client_socket.recv(1024).split[1] GET /index.html HTTP/1.1 Monday, March 11, 13
  13. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end filename = File.expand_path("../#{path}", __FILE__) Monday, March 11, 13
  14. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end if File.file?(filename) Monday, March 11, 13
  15. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) Monday, March 11, 13
  16. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) OK = "HTTP/1.1 200 OK\n" Monday, March 11, 13
  17. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end client_socket.send(NOT_FOUND, 0) Monday, March 11, 13
  18. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end client_socket.send(NOT_FOUND, 0) NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found" Monday, March 11, 13
  19. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end client_socket.close Monday, March 11, 13
  20. require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"

    OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.recv(1024).split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.send(OK, 0) client_socket.send("Content-Length: #{contents.size}\n\n", 0) client_socket.send("#{contents}", 0) else client_socket.send(NOT_FOUND, 0) end client_socket.close end Monday, March 11, 13
  21. def new_ipv6_server(addr, port, opt) opt.key?(:ipv6only) or return Kgio::TCPServer.new(addr, port) defined?(IPV6_V6ONLY)

    or abort "Socket::IPV6_V6ONLY not defined, upgrade Ruby and/or your OS" sock = Socket.new(AF_INET6, SOCK_STREAM, 0) sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, opt[:ipv6only] ? 1 : 0) sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sock.bind(Socket.pack_sockaddr_in(port, addr)) IO_PURGATORY << sock Kgio::TCPServer.for_fd(sock.fileno) end ret = IO.select(l, nil, SELF_PIPE, @timeout) and ready = ret[0] Unicorn Monday, March 11, 13
  22. def new_ipv6_server(addr, port, opt) opt.key?(:ipv6only) or return Kgio::TCPServer.new(addr, port) defined?(IPV6_V6ONLY)

    or abort "Socket::IPV6_V6ONLY not defined, upgrade Ruby and/or your OS" sock = Socket.new(AF_INET6, SOCK_STREAM, 0) sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, opt[:ipv6only] ? 1 : 0) sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sock.bind(Socket.pack_sockaddr_in(port, addr)) IO_PURGATORY << sock Kgio::TCPServer.for_fd(sock.fileno) end ret = IO.select(l, nil, SELF_PIPE, @timeout) and ready = ret[0] Unicorn sock = Socket.new(AF_INET6, SOCK_STREAM, 0) Monday, March 11, 13
  23. def new_ipv6_server(addr, port, opt) opt.key?(:ipv6only) or return Kgio::TCPServer.new(addr, port) defined?(IPV6_V6ONLY)

    or abort "Socket::IPV6_V6ONLY not defined, upgrade Ruby and/or your OS" sock = Socket.new(AF_INET6, SOCK_STREAM, 0) sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, opt[:ipv6only] ? 1 : 0) sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sock.bind(Socket.pack_sockaddr_in(port, addr)) IO_PURGATORY << sock Kgio::TCPServer.for_fd(sock.fileno) end ret = IO.select(l, nil, SELF_PIPE, @timeout) and ready = ret[0] Unicorn sock.bind( Socket.pack_sockaddr_in(port, addr)) Monday, March 11, 13
  24. def new_ipv6_server(addr, port, opt) opt.key?(:ipv6only) or return Kgio::TCPServer.new(addr, port) defined?(IPV6_V6ONLY)

    or abort "Socket::IPV6_V6ONLY not defined, upgrade Ruby and/or your OS" sock = Socket.new(AF_INET6, SOCK_STREAM, 0) sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, opt[:ipv6only] ? 1 : 0) sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sock.bind(Socket.pack_sockaddr_in(port, addr)) IO_PURGATORY << sock Kgio::TCPServer.for_fd(sock.fileno) end ret = IO.select(l, nil, SELF_PIPE, @timeout) and ready = ret[0] Unicorn IO.select(l, nil, SELF_PIPE, @timeout) Monday, March 11, 13