Slide 1

Slide 1 text

࣮࿥ -FU`TCVJMEBTJNQMF 3BDLDPNQBUJCMFTFSWFS⚡⚡⚡ ԘҪඒ࡙!DPF@ 'FC େߐށ3VCZձٞ

Slide 2

Slide 2 text

ࣗݾ঺հ ԘҪඒ࡙ ͓͍͠ !DPF@ 8FCϓϩάϥϚ "TBLVTBSCɺ5BNBSCɺ'VLVPLBSCʢ࿦ཧʣʹ͍·͢ "TBLVTBSCʹ௨͍࢝ΊͯૣҰ೥൒ ࠷ۙ8FCαʔόʔΛ࡞Γ·ͨ͠

Slide 3

Slide 3 text

ࣗݾ঺հ ԘҪඒ࡙ ͓͍͠ !DPF@ 8FCϓϩάϥϚ "TBLVTBSCɺ5BNBSCɺ'VLVPLBSCʢ࿦ཧʣʹ͍·͢ "TBLVTBSCʹ௨͍࢝ΊͯૣҰ೥൒ ࠷ۙ8FCαʔόʔΛ࡞Γ·ͨ͠ ‐ࠓ೔ͷ͓࿩

Slide 4

Slide 4 text

3VCZ$POG/BTIWJMMF /PWFNCFS

Slide 5

Slide 5 text

ग़యɿIUUQTOPUJTUFTUIFSD(V(+MFUTCVJMEBTJNQMFIUUQTFSWFSXJUISVCZ ʮ-FU`TCVJMEBTJNQMF)551TFSWFSʯ &45)&30-"56/%&͞Μ!FTUIFS ‎

Slide 6

Slide 6 text

‎JHBJHB͞Μ!JHBJHB‎ ग़యɿIUUQTUXJUUFSDPNJHBJHBTUBUVT T

Slide 7

Slide 7 text

‎͏ͮΒ͞Μ!VE[VSB 'VLVPLBSC ‎ ‎Θͨ͠ !DPF@ ग़యɿIUUQTUXJUUFSDPNVE[VSBTUBUVT T !DPF@

Slide 8

Slide 8 text

ͱ͍͏͜ͱͰɺ ൃදࢿྉΛࢀߟʹ γϯϓϧͳ)551αʔόʔΛ ࡞ͬͯΈ·ͨ͠

Slide 9

Slide 9 text

ग़དྷ্͕ͬͨͷ͕ͪ͜Β 1 require ‘socket’ 2 3 server = TCPServer.new(‘localhost’, 5000) 4 5 loop do 6 client = server.accept 7 request = client.readpartial(2048) 8 9 puts request 10 11 client.puts response <<~MESSAGE 12 HTTP/1.1 200 OK\r\n 13 Content-Type: text/plain\r\n 14 \r\n 15 Hello!\r\n 16 MESSAGE 17 end TPDLFUϥΠϒϥϦΛSFRVJSF

Slide 10

Slide 10 text

1 require ‘socket’ 2 3 server = TCPServer.new(‘localhost’, 5000) 4 5 loop do 6 client = server.accept 7 request = client.readpartial(2048) 8 9 puts request 10 11 client.puts response <<~MESSAGE 12 HTTP/1.1 200 OK\r\n 13 Content-Type: text/plain\r\n 14 \r\n 15 Hello!\r\n 16 MESSAGE 17 end αʔόʔ઀ଓΛPQFO ΫϥΠΞϯτ͔Βͷ઀ଓཁٻΛड͚෇͚Δ ϦΫΤετϝοηʔδΛಡΈࠐΉ ϦΫΤετϝοηʔδΛαʔόʔଆʹग़ྗ ద౰ͳϨεϙϯεϝοηʔδ ϨεϙϯεϝοηʔδΛΫϥΠΞϯτଆʹग़ྗ ग़དྷ্͕ͬͨͷ͕ͪ͜Β

Slide 11

Slide 11 text

DVSMMPDBMIPTU ࡞ͬͨαʔόʔͷϗετͱϙʔτ൪߸

Slide 12

Slide 12 text

ಈ͖·ͨ͠ αʔόʔଆ ΫϥΠΞϯτଆ ϦΫΤετϝοηʔδ͕ ग़ྗ͞Ε͍ͯΔ ϨεϙϯεϘσΟ͕ ग़ྗ͞Ε͍ͯΔ

Slide 13

Slide 13 text

͔͠͠

Slide 14

Slide 14 text

ಈతͳΞϓϦέʔγϣϯʹ͸ରԠ͍ͯ͠ͳ͍⚠ 1 require ‘socket’ 2 3 server = TCPServer.new(‘localhost’, 5000) 4 5 loop do 6 client = server.accept 7 request = client.readpartial(2048) 8 9 puts request 10 11 client.puts response <<~MESSAGE 12 HTTP/1.1 200 OK\r\n 13 Content-Type: text/plain\r\n 14 \r\n 15 Hello!\r\n 16 MESSAGE 17 end ͦ΋ͦ΋ ΞϓϦέʔγϣϯ͕ ଘࡏ͠ͳ͍ ΞΫηε͢Δͨͼɺຖճ ಉ͡Ϩεϙϯεϝοηʔδ͕ ग़ྗ͞ΕΔ

Slide 15

Slide 15 text

͔ͤͬ͘ͳͷͰ 3BDLDPNQBUJCMFʹ͍ͨ͠

Slide 16

Slide 16 text

γϯϓϧͰ3BDLDPNQBUJCMFͳ 4JNQMF3BDL$PNQBUJCMF4FSWFS ͱ͍͏໊લͷαʔόʔΛ ࡞ͬͯΈ͍ͨͱࢥ͍·͢

Slide 17

Slide 17 text

1 require ‘rack’ 2 require_relative ‘../server/simple_rack_compatible_server’ 3 4 class App 5 def call(env) 6 [ 7 200, 8 { ‘Content-Type’ => ‘text/html’ }, 9 [“

Hello.

This app is running on .…

”] 10 ] 11 end 12 end 13 14 run App.new ݕূ༻ͷ3BDLΞϓϦέʔγϣϯ͕ͪ͜Β app/sample.ru

Slide 18

Slide 18 text

1 require ‘rack’ 2 require_relative ‘../server/simple_rack_compatible_server’ 3 4 class App 5 def call(env) 6 [ 7 200, 8 { ‘Content-Type’ => ‘text/html’ }, 9 [“

Hello.

This app is running on .…

”] 10 ] 11 end 12 end 13 14 run App.new εςʔλε‎)5510, ϔομ‎$POUFOU5ZQFUFYUIUNM ϘσΟ‎EJW I)FMMPI Q5IJTBQQJTʜQ EJW ݕূ༻ͷ3BDLΞϓϦέʔγϣϯ͕ͪ͜Β app/sample.ru ࣮ߦ͢Δͱʜ

Slide 19

Slide 19 text

3BDLΞϓϦέʔγϣϯ͕ىಈ͢ΔྲྀΕ SBDLVQίϚϯυΛ࣮ߦ ϋϯυϥʔΛىಈ ϋϯυϥʔʹαʔόʔΛొ࿥ αʔόʔຊମ͕ॲཧΛ։࢝ αʔόʔΛىಈ 3BDLຊମͱ αʔόʔຊମΛ઀ଓ αʔόʔ͕ ΞϓϦέʔγϣϯΛ࣮ߦ ىಈ։࢝ 3BDLΞϓϦέʔγϣϯΛ࣮ߦ

Slide 20

Slide 20 text

3BDLΞϓϦέʔγϣϯ͕ىಈ͢ΔྲྀΕ SBDLVQίϚϯυΛ࣮ߦ ϋϯυϥʔΛىಈ ϋϯυϥʔʹαʔόʔΛొ࿥ αʔόʔຊମ͕ॲཧΛ։࢝ αʔόʔΛىಈ 3BDLΞϓϦέʔγϣϯΛ࣮ߦ 3BDLຊମͷ )BOEMFSϞδϡʔϧΛ࢖ͬͨ αʔόʔຊମͷॲཧ αʔόʔຊମͷॲཧ 3BDLຊମͷॲཧ

Slide 21

Slide 21 text

3BDLDPNQBUJCMFͳαʔόʔͷػೳཁ݅ 3BDLΞϓϦέʔγϣϯ͕ىಈ͢ΔྲྀΕΛ౿·͑ͯɺ αʔόʔʹඞཁͳػೳΛߟ͑Δ ᶃϋϯυϥʔ 3BDL)BOEMFS4JNQMF3BDL$PNQBUJCMF4FSWFS ⚡3BDLຊମͷ)BOEMFSϞδϡʔϧʹαʔόʔΛొ࿥͢Δ ⚡αʔόʔΛىಈ͢Δ ᶄαʔόʔຊମ 4JNQMF3BDL$PNQBUJCMF4FSWFS4FSWFS ⚡ϦΫΤετΛड͚Δ ⚡ΞϓϦέʔγϣϯΛ࣮ߦ͢Δ ⚡ϨεϙϯεΛฦ͢

Slide 22

Slide 22 text

1 require ‘rack/handler’ 2 3 module Rack 4 module Handler 5 class SimpleRackCompatibleServer 6 def self.run(app, options = {}) 7 environment = ENV[‘RACK_ENV’] || ‘development’ 8 default_host = environment == ‘development’ ? ‘localhost’ : ‘0.0.0.0’ 9 10 host = options.delete(:Host) || default_host 11 port = options.delete(:Port) || 9292 12 args = [host, port, app] 13 ::SimpleRackCompatibleServer::Server.new(*args).start 14 end 15 end 16 17 register :simple_rack_compatible_server, SimpleRackCompatibleServer 18 end 19 end ࢀߟɿIUUQTHJUIVCDPNNBDPVSOPZFSUIJO rack/handler/simple_rack_compatible_server.rb ϋϯυϥʔΛ࣮૷ ࢀߟ5IJO 3BDL)BOEMFSϞδϡʔϧΛSFRVJSF

Slide 23

Slide 23 text

1 require ‘rack/handler’ 2 3 module Rack 4 module Handler 5 class SimpleRackCompatibleServer 6 def self.run(app, options = {}) 7 environment = ENV[‘RACK_ENV’] || ‘development’ 8 default_host = environment == ‘development’ ? ‘localhost’ : ‘0.0.0.0’ 9 10 host = options.delete(:Host) || default_host 11 port = options.delete(:Port) || 9292 12 args = [host, port, app] 13 ::SimpleRackCompatibleServer::Server.new(*args).start 14 end 15 end 16 17 register :simple_rack_compatible_server, SimpleRackCompatibleServer 18 end 19 end rack/handler/simple_rack_compatible_server.rb 3BDL)BOEMFSϞδϡʔϧʹαʔόʔΛొ࿥͢Δ ࢀߟɿIUUQTHJUIVCDPNNBDPVSOPZFSUIJO ϋϯυϥʔΛ࣮૷ ࢀߟ5IJO

Slide 24

Slide 24 text

1 require ‘rack/handler’ 2 3 module Rack 4 module Handler 5 class SimpleRackCompatibleServer 6 def self.run(app, options = {}) 7 environment = ENV[‘RACK_ENV’] || ‘development’ 8 default_host = environment == ‘development’ ? ‘localhost’ : ‘0.0.0.0’ 9 10 host = options.delete(:Host) || default_host 11 port = options.delete(:Port) || 9292 12 args = [host, port, app] 13 ::SimpleRackCompatibleServer::Server.new(*args).start 14 end 15 end 16 17 register :simple_rack_compatible_server, SimpleRackCompatibleServer 18 end 19 end rack/handler/simple_rack_compatible_server.rb ࢀߟɿIUUQTHJUIVCDPNNBDPVSOPZFSUIJO αʔόʔΛىಈ͢Δϝιου ϋϯυϥʔΛ࣮૷ ࢀߟ5IJO

Slide 25

Slide 25 text

1 require ‘rack/handler’ 2 3 module Rack 4 module Handler 5 class SimpleRackCompatibleServer 6 def self.run(app, options = {}) 7 environment = ENV[‘RACK_ENV’] || ‘development’ 8 default_host = environment == ‘development’ ? ‘localhost’ : ‘0.0.0.0’ 9 10 host = options.delete(:Host) || default_host 11 port = options.delete(:Port) || 9292 12 13 14 end 15 end 16 17 18 end 19 end rack/handler/simple_rack_compatible_server.rb ࣮ߦ؀ڥ͔Βϗετͱϙʔτ൪߸Λઃఆ͢Δ ˞σϑΥϧτͰMPDBMIPTUʹ઀ଓ ࢀߟɿIUUQTHJUIVCDPNNBDPVSOPZFSUIJO ϋϯυϥʔΛ࣮૷ ࢀߟ5IJO

Slide 26

Slide 26 text

1 require ‘rack/handler’ 2 3 module Rack 4 module Handler 5 class SimpleRackCompatibleServer 6 def self.run(app, options = {}) 7 environment = ENV[‘RACK_ENV’] || ‘development’ 8 default_host = environment == ‘development’ ? ‘localhost’ : ‘0.0.0.0’ 9 10 host = options.delete(:Host) || default_host 11 port = options.delete(:Port) || 9292 12 args = [host, port, app] 13 14 end 15 end 16 17 18 end 19 end rack/handler/simple_rack_compatible_server.rb αʔόʔʹ౉͢Ҿ਺Λ༻ҙ͢Δ ⚡ϗετ ⚡ϙʔτ൪߸ ⚡3BDLΞϓϦέʔγϣϯຊମ ࢀߟɿIUUQTHJUIVCDPNNBDPVSOPZFSUIJO ϋϯυϥʔΛ࣮૷ ࢀߟ5IJO

Slide 27

Slide 27 text

1 require ‘rack/handler’ 2 3 module Rack 4 module Handler 5 class SimpleRackCompatibleServer 6 def self.run(app, options = {}) 7 environment = ENV[‘RACK_ENV’] || ‘development’ 8 default_host = environment == ‘development’ ? ‘localhost’ : ‘0.0.0.0’ 9 10 host = options.delete(:Host) || default_host 11 port = options.delete(:Port) || 9292 12 args = [host, port, app] 13 ::SimpleRackCompatibleServer::Server.new(*args).start 14 end 15 end 16 17 18 end 19 end rack/handler/simple_rack_compatible_server.rb αʔόʔ 4JNQMF3BDL$PNQBUJCMF4FSWFS4FSWFS Λ ΠϯελϯεԽ͠ OFX ɺىಈ͢Δ TUBSU ࢀߟɿIUUQTHJUIVCDPNNBDPVSOPZFSUIJO ϋϯυϥʔΛ࣮૷ ࢀߟ5IJO

Slide 28

Slide 28 text

1 require ‘socket’ 2 3 module SimpleRackCompatibleServer 4 class Server 5 def initialize(*args) 6 @host, @port, @app = args 7 end 8 9 def start 26 end 27 end 28 end simple_rack_compatible_server.rb αʔόʔΛ࣮૷શମ૾ ʜ ϋϯυϥʔ͔ΒҾ͖ܧ͍ͩ ⚡ϗετ ⚡ϙʔτ൪߸ ⚡3BDLΞϓϦέʔγϣϯຊମ ͰΠϯελϯεΛॳظԽ͢Δ ݩʑͷ)551αʔόʔͷॲཧʹ ͭͷมߋ఺Λ௥Ճ ৄ͘͠͸࣍ͷεϥΠυ

Slide 29

Slide 29 text

9 def start 10 server = TCPServer.new(@host, @port) 11 12 loop do 13 client = server.accept 14 request = client.readpartial(2048) 15 16 @status, @header, @body = @app.call 17 18 puts request 19 20 client.puts <<~MESSAGE 21 #{‘HTTP/1.1 200 OK’ if @status.eql? 200}\r\n 22 #{@header.map { |k, v| [k, v].join(’: ’) }.join(“\r\n”)}\r\n 23 \r\n 24 #{@body} 25 MESSAGE 26 end simple_rack_compatible_server.rb มߋ఺ᶄ 3BDLΞϓϦέʔγϣϯ࣮ߦ ฦΓ஋Λऔಘ͢Δ มߋ఺ᶅ ฦΓ஋͔ΒϨεϙϯεϝοηʔδΛੜ੒ αʔόʔΛ࣮૷TUBSUϝιου มߋ఺ᶃ ϋϯυϥʔ͔Β౉ͨ͠ ϗετͱϙʔτ൪߸Λઃఆ

Slide 30

Slide 30 text

͔͠͠

Slide 31

Slide 31 text

9 def start 10 server = TCPServer.new(@host, @port) 11 12 loop do 13 client = server.accept 14 request = client.readpartial(2048) 15 16 @status, @header, @body = @app.call(???) 17 18 puts request 19 20 client.puts <<~MESSAGE 21 #{‘HTTP/1.1 200 OK’ if @status.eql? 200}\r\n 22 #{@header.map { |k, v| [k, v].join(’: ’) }.join(“\r\n”)}\r\n 23 \r\n 24 #{@body} 25 MESSAGE 26 end simple_rack_compatible_server.rb Ͳ͏͠Α͏ʜ DBMMϝιουʹ౉͢Ҿ਺͕Θ͔Βͳ͍⚠ ؀ڥม਺ΛϋογϡͷܗͰ ೖΕΔඞཁ͕͋Δ

Slide 32

Slide 32 text

9 def start 10 server = TCPServer.new(@host, @port) 11 12 loop do 13 client = server.accept 14 request = client.readpartial(2048) 15 16 @status, @header, @body = @app.call({ }) 17 18 puts request 19 20 client.puts <<~MESSAGE 21 #{‘HTTP/1.1 200 OK’ if @status.eql? 200}\r\n 22 #{@header.map { |k, v| [k, v].join(’: ’) }.join(“\r\n”)}\r\n 23 \r\n 24 #{@body} 25 MESSAGE 26 end simple_rack_compatible_server.rb Θ͔Βͳ͍ͷͰ ۭϋογϡΛ ೖΕͯΈ·ͨ͠

Slide 33

Slide 33 text

SBDLVQTTJNQMF@SBDL@DPNQBUJCMF@TFSWFS ͱΓ͋͑ͣ

Slide 34

Slide 34 text

‎ͩΊͰͨ͠ ר͖ى͜ΔΤϥʔ☠☠☠

Slide 35

Slide 35 text

ೖྗඞਢͷ؀ڥม਺͕͋ΔΒ͍͠ FOWNJTTJOHSFRVJSFELFZ3&26&45@.&5)0% 3BDL-JOU-JOU&SSPS

Slide 36

Slide 36 text

rack/lib/rack/lint.rb 3BDL-JOUΫϥεΛ֬ೝ

Slide 37

Slide 37 text

rack/lib/rack/lint.rb 3BDL-JOUΫϥεΛ֬ೝ ඞཁͳ؀ڥม਺ʹ͍ͭͯղઆͯ͘͠Ε͍ͯΔʂ ʜ

Slide 38

Slide 38 text

⚡1"5)@*/'0‎ϦΫΤετ63-ͷύε ⚡26&3:@453*/(‎ΫΤϦจࣈྻ ⚡.&5)0%‎)551ϝιου ⚡4&37&3@/".&‎4$3*15@/".&ͱ1"5)@*/'0ͱͷ ૊Έ߹ΘͤͰ63-Λߏங͢Δ ⚡4&37&3@1035‎4$3*15@/".&ͱ1"5)@*/'0ͱͷ ૊Έ߹ΘͤͰ63-Λߏங͢Δ 1&1Ͱఆٛ͞Εͨ؀ڥม਺ 1&1‎1ZUIPO8FC4FSWFS(BUFXBZ*OUFSGBDFW IUUQTXXXQZUIPOPSHEFWQFQTQFQ

Slide 39

Slide 39 text

⚡SBDLWFSTJPO‎3BDLͷόʔδϣϯ ഑ྻ ⚡SBDLJOQVU‎ೖྗετϦʔϜ *0ϥΠΫͳΦϒδΣΫτ ⚡SBDLFSSPST‎ΤϥʔετϦʔϜ QVUTXSJUFqVTIΛݺ΂ΔΦϒδΣΫτ ⚡SBDLNVMUJQSPDFTT‎ΞϓϦέʔγϣϯ͕ෳ਺ͷϓϩηεʹΑͬͯ ಉ࣌ʹݺͼग़͞ΕΔ͔Ͳ͏͔ ⚡SBDLNVMUJUISFBE‎ΞϓϦέʔγϣϯ͕ ಉ͡ϓϩηε಺ͷෳ਺ͷεϨουʹΑͬͯ ಉ࣌ʹݺͼग़͞ΕΔ͔Ͳ͏͔ ⚡SBDLSVO@PODF‎ΞϓϦέʔγϣϯ͕ͦͷϓϩηεͷ࣮ߦதʹ Ұ౓͚ͩݺͼग़͞ΕΔ͔Ͳ͏͔ $(*ϕʔεͷαʔόʔͰͷΈUSVFʹͳΔ ⚡SBDLVSM@TDIFNF‎63*εΩʔϜ IUUQPSIUUQT 3BDL؀ڥݻ༗ͷ؀ڥม਺

Slide 40

Slide 40 text

18 def env 19 { 20 ‘PATH_INFO’ => @path || ‘/’, 21 ‘QUERY_STRING’ => @query || ‘’, 22 ‘METHOD’ => @method || ‘GET’, 23 ‘SERVER_NAME’ => ‘simple_rack_compatible_server’, 24 ‘SERVER_PORT’ => @port.to_s, 25 ‘rack.version’ => Rack::VERSION, 26 ‘rack.input’ => StringIO.new(@input || ‘’).set_encoding(‘ASCII_8BIT’), 27 ‘rack.errors’ => $stderr, 28 ‘rack.multiprocess’ => false, 29 ‘rack.multithread’ => false, 30 ‘rack.run_once’ => false, 31 ‘rack.url_scheme’ => @scheme&.downcase&.slice(/http[a-z]*/) || ‘http’ 32 } 33 end simple_rack_compatible_server.rb 3BDL-JOUΛࢀߟʹ؀ڥม਺Λઃఆ ϦΫΤετ͔Βಈతʹੜ੒ͨ͠؀ڥม਺ PSσϑΥϧτ஋

Slide 41

Slide 41 text

35 def start 36 server = TCPServer.new(@host, @port) 37 38 loop do 39 client = server.accept 40 41 request = client.readpartial(2048).split(“\r\n”) 42 @method, path, @scheme = request.first.split 43 @path, @query = path.split(‘?’) 44 @input = request.index(‘’) ? request[request.index(‘’) + 1] : ‘’ 45 46 puts “Received request message: #{@method} #{@path} #{@scheme}” 47 48 @status, @header, @body = @app.call(env) 49 50 client.puts <<~MESSAGE 51 # … simple_rack_compatible_server.rb ϦΫΤετϝοηʔδ͔Β؀ڥม਺Λੜ੒ ؀ڥม਺Λੜ੒͢ΔίʔυΛ௥Ճ

Slide 42

Slide 42 text

35 def start 36 server = TCPServer.new(@host, @port) 37 38 loop do 39 client = server.accept 40 41 request = client.readpartial(2048).split(“\r\n”) 42 @method, path, @scheme = request.first.split 43 44 45 46 47 48 49 50 51 simple_rack_compatible_server.rb !NFUIPE‎)551ϝιου ˏTDIFNB‎63*εΩʔϜ ϦΫΤετϝοηʔδ͔Β؀ڥม਺Λੜ੒

Slide 43

Slide 43 text

35 def start 36 server = TCPServer.new(@host, @port) 37 38 loop do 39 client = server.accept 40 41 request = client.readpartial(2048).split(“\r\n”) 42 @method, path, @scheme = request.first.split 43 @path, @query = path.split(‘?’) 44 45 46 47 48 49 50 51 simple_rack_compatible_server.rb !QBUI‎ϦΫΤετ63-ͷύε !RVFSZ‎ΫΤϦจࣈྻ ϦΫΤετϝοηʔδ͔Β؀ڥม਺Λੜ੒

Slide 44

Slide 44 text

35 def start 36 server = TCPServer.new(@host, @port) 37 38 loop do 39 client = server.accept 40 41 request = client.readpartial(2048).split(“\r\n”) 42 @method, path, @scheme = request.first.split 43 @path, @query = path.split(‘?’) 44 @input = request.index(‘’) ? request[request.index(‘’) + 1] : ‘’ 45 46 47 48 49 50 51 simple_rack_compatible_server.rb !JOQVU‎ೖྗετϦʔϜ ϦΫΤετϘσΟ ϦΫΤετϝοηʔδ͔Β؀ڥม਺Λੜ੒

Slide 45

Slide 45 text

35 def start 36 server = TCPServer.new(@host, @port) 37 38 loop do 39 client = server.accept 40 41 request = client.readpartial(2048).split(“\r\n”) 42 @method, path, @scheme = request.first.split 43 @path, @query = path.split(‘?’) 44 @input = request.index(‘’) ? request[request.index(‘’) + 1] : ‘’ 45 46 puts “Received request message: #{@method} #{@path} #{@scheme}” 47 48 49 50 51 simple_rack_compatible_server.rb ͔ͤͬ͘ͳͷͰϩά ΋ग़ྗ ϦΫΤετϝοηʔδ͔Β؀ڥม਺Λੜ੒

Slide 46

Slide 46 text

SBDLVQTTJNQMF@SBDL@DPNQBUJCMF@TFSWFS ͋ΒͨΊͯ

Slide 47

Slide 47 text

‎ಈ͖·ͨ͠ 3FDFJWFESFRVFTUNFTTBHF(&5)551 3BDL-JOU-JOU&SSPSΤϥʔ͕ফ͑ͯ ϩά͕ग़ྗ͞Ε͍ͯΔʂ λʔϛφϧʹͯ

Slide 48

Slide 48 text

ϒϥ΢βͷݕূπʔϧʹͯ 3BDLΞϓϦέʔγϣϯ͔Βऔಘͨ͠ εςʔλείʔυͱϔομΛ ΫϥΠΞϯτଆʹ౉͢͜ͱ͕Ͱ͖͍ͯΔʂ ϔομ $POUFOU5ZQFUFYUIUNM εςʔλείʔυ

Slide 49

Slide 49 text

ϨεϙϯεϘσΟ͸ʜ

Slide 50

Slide 50 text

ϨεϙϯεϘσΟ͸ʜ

Slide 51

Slide 51 text

Կ͔͕͓͔͍͠ ཧ૝ ݱ࣮ SBDLCPEZQSPYZ ϨεϙϯεϘσΟΛಡΈࠐΜͰ %0.͕ੜ੒͞ΕΔ

Slide 52

Slide 52 text

35 def start 36 server = TCPServer.new(@host, @port) 37 38 loop do … 47 48 @status, @header, @body = @app.call(env) 49 50 client.puts <<~MESSAGE 51 #{‘HTTP/1.1 200 OK’ if @status.eql? 200}\r\n 52 #{@header.map { |k, v| [k, v].join(’: ’) }.join(“\r\n”)}\r\n 53 \r\n 54 #{@body} 55 MESSAGE 56 end 57 end simple_rack_compatible_server.rb Ϩεϙϯεϝοηʔδ͸Ͳ͏ͳ͍ͬͯΔʁ ཧ૝ͷϨεϙϯεϘσΟ͸ [“

Hello.

This app is …

”] 3BDLΞϓϦέʔγϣϯΛ࣮ߦͯ͠ฦΓ஋Λऔಘ ‎<εςʔλείʔυ \ϔομ^ <ϘσΟ>>

Slide 53

Slide 53 text

!CPEZͷத਎͸Ͳ͏ͳ͍ͬͯΔʁ JSC 4JNQMF3BDL$PNQBUJCMF4FSWFS4FSWFSYʜ QQ!CPEZ 3BDL#PEZ1SPYZYʜ !CMPDL 1SPDYʜ!ʜSBDLMJCSBDLDPNNPO@MPHHFSSC !CPEZ 3BDL-JOUYʜ !BQQ 3BDL5FNQpMF3FBQFSYʜ!BQQ"QQYʜ !CPEZ 3BDL#PEZ1SPYZYʜ !CMPDL 1SPDYʜ!ʜSBDLMJCSBDLUFNQpMF@SFBQFSSC !CPEZ !DMPTFEGBMTF

Slide 54

Slide 54 text

!CPEZͷத਎͸Ͳ͏ͳ͍ͬͯΔʁ JSC 4JNQMF3BDL$PNQBUJCMF4FSWFS4FSWFSYʜ QQ!CPEZ 3BDL#PEZ1SPYZYʜ !CMPDL 1SPDYʜ!ʜSBDLMJCSBDLDPNNPO@MPHHFSSC !CPEZ 3BDL-JOUYʜ !BQQ 3BDL5FNQpMF3FBQFSYʜ!BQQ"QQYʜ !CPEZ 3BDL#PEZ1SPYZYʜ !CMPDL 1SPDYʜ!ʜSBDLMJCSBDLUFNQpMF@SFBQFSSC !CPEZ !DMPTFEGBMTF 3BDL#PEZ1SPYZͷΠϯελϯεʂ

Slide 55

Slide 55 text

JSC 4JNQMF3BDL$PNQBUJCMF4FSWFS4FSWFSYʜ QQ!CPEZ 3BDL#PEZ1SPYZYʜ !CMPDL 1SPDYʜ!ʜSBDLMJCSBDLDPNNPO@MPHHFSSC !CPEZ 3BDL-JOUYʜ !BQQ 3BDL5FNQpMF3FBQFSYʜ!BQQ"QQYʜ !CPEZ 3BDL#PEZ1SPYZYʜ !CMPDL 1SPDYʜ!ʜSBDLMJCSBDLUFNQpMF@SFBQFSSC !CPEZ !DMPTFEGBMTF ͋Δ औΓग़͠ํ͕Θ͔Βͳ͍ʜ !CPEZͷத਎͸Ͳ͏ͳ͍ͬͯΔʁ

Slide 56

Slide 56 text

!CPEZΛDBMMͯ͠Έ·ͨ͠ JSC 4JNQMF3BDL$PNQBUJCMF4FSWFSTFSWʜ QQ!CPEZDBMM FOW < \$POUFOU5ZQFUFYUIUNM^ 3BDL-JOUYʜ !BQQ 3BDL5FNQpMF3FBQFSYʜ!BQQ"QQYʜ !CPEZ 3BDL#PEZ1SPYZYʜ !CMPDL 1SPDYʜ!ʜSBDLMJCSBDLUFNQpMF@SFBQFSSC !CPEZ <EJWI)FMMPIQ5IJTBQQJTʜQEJW> !DMPTFEGBMTF !DPOUFOU@MFOHUIOJM !IFBE@SFRVFTUGBMTF>

Slide 57

Slide 57 text

!CPEZΛDBMMͯ͠Έ·ͨ͠ JSC 4JNQMF3BDL$PNQBUJCMF4FSWFSTFSWFʜ QQ!CPEZDBMM FOW < \$POUFOU5ZQFUFYUIUNM^ 3BDL-JOUYʜ !BQQ 3BDL5FNQpMF3FBQFSYʜ!BQQ"QQYʜ !CPEZ 3BDL#PEZ1SPYZYʜ !CMPDL 1SPDYʜ!ʜSBDLMJCSBDLUFNQpMF@SFBQFSSC !CPEZ !DMPTFEGBMTF !DPOUFOU@MFOHUIOJM !IFBE@SFRVFTUGBMTF> ԕ͍ʜ ϨεϙϯεϘσΟͦͷ΋ͷ͕ औಘͰ͖ΔΑ͏ʹͳΔ·Ͱ ԆʑDBMM͠ଓ͚Δ͔͠ͳ͍ʜʁʁ ϘσΟ 3BDL-JOUͷΠϯελϯε

Slide 58

Slide 58 text

ߴڮ͞Μ͔Βͷώϯτ DBMMϝιουͷฦ͢ཁૉ഑ྻͷͭ໨͸CPEZͰɺ CPEZ͸FBDIϝιουͱ͔UP@QBUIϝιουͱ͔Λୟ͚Δ ΦϒδΣΫτͰ͔͠ͳ͘

Slide 59

Slide 59 text

ʜFBDIϝιουʁ ߴڮ͞Μ͔Βͷώϯτ DBMMϝιουͷฦ͢ཁૉ഑ྻͷͭ໨͸CPEZͰɺ CPEZ͸FBDIϝιουͱ͔UP@QBUIϝιουͱ͔Λୟ͚Δ ΦϒδΣΫτͰ͔͠ͳ͘

Slide 60

Slide 60 text

3BDL#PCZ1SPYZFBDI 3BDL#PCZ1SPYZ͸FBDIϝιουΛ࣋ͭ ࢖͑ΔͷͰ͸ʁ

Slide 61

Slide 61 text

1 require ‘socket’ 2 3 module SimpleRackCompatibleServer 4 class Server 69 def body 70 res_body = [] 71 @body.each { |body| res_body << body } 72 res_body.join(“\n”) 73 end 74 end 75 end simple_rack_compatible_server.rb FBDIΛ࢖ͬͯϨεϙϯεϘσΟΛऔΓग़͢ … !CPEZʹFBDIΛݺͼ഑ྻͱͯ͠୅ೖ͠௚͢ ࠷ޙʹจࣈྻʹ௚͢

Slide 62

Slide 62 text

35 def start 48 @status, @header, @body = @app.call(env) 49 50 client.puts <<~MESSAGE 51 #{‘HTTP/1.1 200 OK’ if @status.eql? 200}\r\n 52 #{@header.map { |k, v| [k, v].join(’: ’) }.join(“\r\n”)}\r\n 53 \r\n 54 #{body} 55 MESSAGE 56 end 57 end simple_rack_compatible_server.rb ϨεϙϯεϘσΟΛݺͼग़͢ … CPEZϝιουΛݺͿ

Slide 63

Slide 63 text

SBDLVQTTJNQMF@SBDL@DPNQBUJCMF@TFSWFS ͋ΒͨΊͯ

Slide 64

Slide 64 text

ಈ͖·ͨ͠ ϨεϙϯεϘσΟ΋දࣔͰ͖·ͨ͠

Slide 65

Slide 65 text

εςʔλείʔυɺϔομɺϘσΟͷશͯΛ ΫϥΠΞϯτଆʹग़ྗͰ͖·ͨ͠ʂ ಈ͖·ͨ͠ εςʔλε‎)5510, ϔομ‎$POUFOU5ZQFUFYUIUNM ϘσΟ‎EJW I)FMMPI Q5IJTBQQJTʜQ EJW

Slide 66

Slide 66 text

࠷ऴతʹ͜͏ͳΓ·ͨ͠⚡

Slide 67

Slide 67 text

1 require ‘socket’ 2 3 module SimpleRackCompatibleServer 4 class Server 5 def initialize(*args) 6 @host, @port, @app = args 7 @method = nil 8 @path = nil 9 @scheme = nil 10 @query = nil 11 @input = nil 12 @status = nil 13 @header = nil 14 @body = nil 15 end simple_rack_compatible_server.rb 4JNQMF3BDL$PNQBUJCMF4FSWFS4FSWFSJOJUJBMJ[F ⚡TPDLFUϥΠϒϥϦΛSFRVJSF ⚡ඞཁͳΠϯελϯεม਺ΛॳظԽ

Slide 68

Slide 68 text

18 def env 19 { 20 ‘PATH_INFO’ => @path || ‘/’, 21 ‘QUERY_STRING’ => @query || ‘’, 22 ‘METHOD’ => @method || ‘GET’, 23 ‘SERVER_NAME’ => ‘simple_rack_campatible_server’, 24 ‘SERVER_PORT’ => @port.to_s, 25 ‘rack.version’ => Rack::VERSION, 26 ‘rack.input’ => StringIO.new(@input || ‘’).set_encoding(‘ASCII_8BIT’), 27 ‘rack.errors’ => $stderr, 28 ‘rack.multiprocess’ => false, 29 ‘rack.multithread’ => false, 30 ‘rack.run_once’ => false, 31 ‘rack.url_scheme’ => @scheme&.downcase&.slice(/http[a-z]*/) || ‘http’ 32 } 33 end simple_rack_compatible_server.rb 4JNQMF3BDL$PNQBUJCMF4FSWFS4FSWFSFOW ⚡3BDLΞϓϦέʔγϣϯͷ࣮ߦʹඞཁͳ؀ڥม਺Λ༻ҙ

Slide 69

Slide 69 text

35 def start 36 server = TCPServer.new(@host, @port) 37 38 puts <<~MESSAGE 39 #{@app} is running on #{@host}: #{@port} 40 => Use Ctrl-C to stop 41 MESSAGE 42 43 loop do 44 client = server.accept 60 end 61 end simple_rack_compatible_server.rb … 4JNQMF3BDL$PNQBUJCMF4FSWFS4FSWFSTUBSU ⚡ϧʔϓॲཧΛ։࢝͢Δ ⚡ΫϥΠΞϯτ͔Βͷ઀ଓཁٻΛड͚෇͚Δ ⚡αʔόʔ઀ଓΛ։࢝͢Δ ⚡։࢝ϝοηʔδΛग़ྗ͢Δ

Slide 70

Slide 70 text

46 begin 47 request = client.readpartial(2048).split(“\r\n”) 48 @method, path, @scheme = request.first.split 49 @path, @query = path.split(‘?’) 50 @input = request.index(‘’) ? request[request.index(‘’) + 1] : ‘’ 51 52 puts “Received request message: #{@method} #{@path} #{@schema}” 53 54 55 56 57 58 59 end simple_rack_compatible_server.rb 4JNQMF3BDL$PNQBUJCMF4FSWFS4FSWFSTUBSU ⚡ϦΫΤετϝοηʔδΛಡΈࠐΉ ⚡3BDLΞϓϦέʔγϣϯͷ࣮ߦʹඞཁͳ؀ڥม਺Λੜ੒͢Δ ⚡αʔόʔʹϩάΛग़ྗ͢Δ

Slide 71

Slide 71 text

46 begin 47 48 49 50 51 52 53 54 @status, @header, @body = @app.call(env) 55 56 client.puts [status, header, ‘’, body].join(“\r\n”) 57 ensure 58 client.close 59 end simple_rack_compatible_server.rb 4JNQMF3BDL$PNQBUJCMF4FSWFS4FSWFSTUBSU ⚡3BDLΞϓϦέʔγϣϯΛ࣮ߦ͠ɺฦΓ஋Λऔಘ͢Δ ⚡ฦΓ஋͔ΒϨεϙϯεϝοηʔδΛੜ੒͠ɺग़ྗ͢Δ ⚡ιέοτΛด͡Δ

Slide 72

Slide 72 text

46 begin 47 48 49 50 51 52 53 54 55 56 client.puts [status, header, ‘’, body].join(“\r\n”) 57 ensure 58 client.close 59 end simple_rack_compatible_server.rb 4JNQMF3BDL$PNQBUJCMF4FSWFS4FSWFSTUBSU 67 def status 68 case @status 69 when 200 70 “#{@schema} 200 OK” 82 def header 83 @header.map { |k, v| [k, v].join(’: ’) }.join(“\r\n”) 84 end 86 def body 87 res_body = [] 88 @body.each { |body| res_body << body } 89 res_body.join(“\n”) 90 end

Slide 73

Slide 73 text

͓ർΕ༷Ͱͨ͠✨

Slide 74

Slide 74 text

ը૾ɿIUUQTUXJUUFSDPNUFOEFSMPWF ग़యɿIUUQTTQFBLFSEFDLDPNUFOEFSMPWFHBPEVOBLPEP "BSPO͞Μɹɹɹɹ

Slide 75

Slide 75 text

ײ૝ 3BDLΛ࢖ͬͯ 3BDLDPNQBUJCMFͳ 8FCαʔόʔΛ࡞Δͷ͸ ָ

Slide 76

Slide 76 text

⚡Ұ෦͸Ծ࣮૷ͷ··ͩ͠ɺ ·ͩ·ͩߟ͑Δ΂͖͜ͱ͸ͨ͘͞Μ͋Δ ೖྗʁฒྻԽʁύϑΥʔϚϯεʁFUD ⚡΋ͬͱ3BDLͷ͜ͱΛ஌Γ͍ͨʂ ⚡օ͞Μ͔Βͷٕज़తࢦఠΛ͓଴͍ͪͯ͠·͢ IUUQTHJUIVCDPNTIJPJNNTJNQMF@SBDL@DPNQBUJCMF@TFSWFS ͱ͸͍͑

Slide 77

Slide 77 text

3BDL͸ָɹ

Slide 78

Slide 78 text

3BDL͸ָ͍͠ʂ

Slide 79

Slide 79 text

͓ΘΓʹ⚡⚡⚡

Slide 80

Slide 80 text

ࣗݾ঺հ࠶ͼ

Slide 81

Slide 81 text

Ұ೥൒લʹԿ͕͔͋ͬͨ օ͞Μ͍֮͑ͯ·͔͢ʜʁ

Slide 82

Slide 82 text

೥݄೔ େߐށ3VCZձٞ ը૾ɿIUUQTSFHJPOBMSVCZLBJHJPSHPFEP

Slide 83

Slide 83 text

લճͷେߐށ3VCZձٞͷ௚લʹॳࢀՃ "TBLVTBSCͷFTBʹΑΔͱ ͦͯͦ͠ͷ৔Ͱେߐށ3VCZձٞʹ ਃ͠ࠐΈΛͨ͠هԱ͕ʜ ୈճ ը૾ɿIUUQTBTBLVTBSCFTBJPQPTUT

Slide 84

Slide 84 text

લճͷେߐށ3VCZձٞ ը૾ɿIUUQTSFHJPOBMSVCZLBJHJPSHPFEP

Slide 85

Slide 85 text

લճͷେߐށ3VCZձٞ ָ͔ͬͨ͘͢͝͠ ը૾ɿIUUQTSFHJPOBMSVCZLBJHJPSHPFEP

Slide 86

Slide 86 text

લճͷେߐށ3VCZձٞ جௐߨԋ +POBO͞Μʮ)PXUPCFσΧʯ ը૾ɿIUUQTSFHJPOBMSVCZLBJHJPSHPFEP

Slide 87

Slide 87 text

લճͷେߐށ3VCZձٞ جௐߨԋ +POBO͞Μʮ)PXUPCFσΧʯ Have your heroes ը૾ɿIUUQTSFHJPOBMSVCZLBJHJPSHPFEP

Slide 88

Slide 88 text

Ұ೥൒લͷࣗ෼ʹͱͬͯ "TBLVTBSCͷਓʑ͸ ʮώʔϩʔʯ

Slide 89

Slide 89 text

Ұ೥൒ܦͬͨࠓ͸ ʮಉ͡ίϛϡχςΟͷਓʑʯ Ͱ΋͋Δ

Slide 90

Slide 90 text

3VCZ ͳͲͳͲ ͷ͓࿩Λͨ͠Γ✨ ίʔυΛॻ͍ͨΓ+ ͓͍͍͠΋ͷΛ௖͍ͨΓ Θͨ͠ʹͱͬͯͷ"TBLVTBSC͸ɺ 3VCZJTU͕ू·ͬͯ ͍ͭ΋Θ͍Θ͍͍ͯ͠Δ৔ॴ

Slide 91

Slide 91 text

"TBLVTBSC͸ָ͍͠ʂ

Slide 92

Slide 92 text

4QFDJBM5IBOLT ܟশུ ✨ JOTQJSFEGSPN !FTUIFS !UFOEFSMPWFUIF3BDLUFBN ŠŠ !JHBJHB!VE[VSB !UBLBIBTIJN!PLVSBNBTBGVNJ !UIFKPOBOTIPX"TBLVTBSC'VLVPLBSC ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠⚡⚡⚡