Slide 1

Slide 1 text

3BDLϛυϧ΢ΣΞೖ໳ͷͨΊͷ 3BDLϛυϧ΢ΣΞ ԘҪඒ࡙!DPF@ %FD 5PLZP(JSMTSC.FFUVQWPM

Slide 2

Slide 2 text

ٕज़తʹ੿͍಺༰΋ؚ·Ε͍ͯΔ͔ͱࢥ͍·͢ɻ օ༷͔Βͷ͝ࢦఠɾ13Λ ͓଴͓ͪͯ͠Γ·͢

Slide 3

Slide 3 text

ࣗݾ঺հ ԘҪඒ࡙!DPF@ 8FCϓϩάϥϚGSPNגࣜձࣾΩϟλϧ 5BNBSCɺ"TBLVTBSCɺ'VLVPLBSCʢ࿦ཧʣʹ͍·͢ ࠷ۙؾʹͳΔϥΠϒϥϦ͸3BDL

Slide 4

Slide 4 text

ࣗݾ঺հ ԘҪඒ࡙!DPF@ 8FCϓϩάϥϚGSPNגࣜձࣾΩϟλϧ 5BNBSCɺ"TBLVTBSCɺ'VLVPLBSCʢ࿦ཧʣʹ͍·͢ ࠷ۙؾʹͳΔϥΠϒϥϦ͸3BDL ‐ࠓ೔ͷ͓࿩

Slide 5

Slide 5 text

3BDLͬͯԿͰ͚ͨͬ͠ʜʁ ʢهԱ૕ࣦʣ

Slide 6

Slide 6 text

8FCαʔόʔͱ8FCΞϓϦέʔγϣϯΛܨ͙ϓϩτίϧ 8FCαʔόʔͱ8FCΞϓϦέʔγϣϯΛܨ͙ϥΠϒϥϦ ‎3BDLϓϩτίϧΛຬͨͨ͠8FCαʔόʔͱ ‎3BDLϓϩτίϧΛຬͨͨ͠8FCΞϓϦέʔγϣϯؒΛ ‎3BDLϥΠϒϥϦ͕औΓ࣋ͭ 3BDLͱ͸ ը૾ग़యɿIUUQTSVCZPOSBJMTPSH͓ΑͼIUUQTSBDLHJUIVCJP

Slide 7

Slide 7 text

8FCαʔόʔͱ8FCΞϓϦέʔγϣϯΛܨ͙ϓϩτίϧ 8FCαʔόʔͱ8FCΞϓϦέʔγϣϯΛܨ͙ϥΠϒϥϦ ‎3BDLϓϩτίϧΛຬͨͨ͠8FCαʔόʔͱ ‎3BDLϓϩτίϧΛຬͨͨ͠8FCΞϓϦέʔγϣϯؒΛ ‎3BDLϥΠϒϥϦ͕औΓ࣋ͭ 3BDLͱ͸ ը૾ग़యɿIUUQTSVCZPOSBJMTPSH͓ΑͼIUUQTSBDLHJUIVCJP 3BDLΞϓϦέʔγϣϯ

Slide 8

Slide 8 text

3BDLΞϓϦέʔγϣϯͷ͓࿩ ը૾ग़యɿIUUQTSVCZPOSBJMTPSH͓ΑͼIUUQTSBDLHJUIVCJP ɹྫ͑͹ɺ3BJMTΞϓϦέʔγϣϯ͔Β ɹ3BJMTಛ༗ͷॾʑΛશ෦ണ͕͍ͯ͘͠ͱʜ ɹ

Slide 9

Slide 9 text

3BDLΞϓϦέʔγϣϯͷ͓࿩ ɹྫ͑͹ɺ3BJMTΞϓϦέʔγϣϯ͔Β ɹ3BJMTಛ༗ͷॾʑΛશ෦ണ͕͍ͯ͘͠ͱʜ ɹ ࠷ޙʹ࢒Δͷ͕ૉͷ3BDLΞϓϦέʔγϣϯ ˞3BJMTҎ֎ͷ3VCZͰॻ͔Εͨ8FCΞϓϦέʔγϣϯϑϨʔϜϫʔΫ΋ಉ༷ ը૾ग़యɿIUUQTSVCZPOSBJMTPSH͓ΑͼIUUQTSBDLHJUIVCJP

Slide 10

Slide 10 text

Ұ൪γϯϓϧͳྫ ɹ3BDLΞϓϦέʔγϣϯ͸ɺ ɹ8FCΞϓϦέʔγϣϯΛߏ੒͢ΔͨΊʹඞཁͳ ɹͭͷཁૉΛ࣋ͬͨ഑ྻ͔Β੒Δ [ 200, { "Content-Type" => "text/plain" }, ["Hello World!\n"] ] εςʔλείʔυ ϔομ ϘσΟ 3BDLΞϓϦέʔγϣϯͷߏ଄

Slide 11

Slide 11 text

Ұ൪γϯϓϧͳྫ ɹ ͱ͸͍͑ ɹ࣮ࡍͷ8FCΞϓϦέʔγϣϯ͸ ɹ΋ͬͱ৭ʑෳࡶͳػೳΛ͍࣋ͬͯΔ΋ͷͳͷͰ͸ʜʁ [ 200, { "Content-Type" => "text/plain" }, ["Hello World!\n"] ]

Slide 12

Slide 12 text

Ұ൪γϯϓϧͳྫ ɹ ͱ͸͍͑ ‎ͦΜͳ࣌͸3BDLϛυϧ΢ΣΞͷग़൪ ɹ࣮ࡍͷ8FCΞϓϦέʔγϣϯ͸ ɹ΋ͬͱ৭ʑෳࡶͳػೳΛ͍࣋ͬͯΔ΋ͷͳͷͰ͸ʜʁ [ 200, { "Content-Type" => "text/plain" }, ["Hello World!\n"] ]

Slide 13

Slide 13 text

3BDLϛυϧ΢ΣΞͱ͸ 8FCΞϓϦέʔγϣϯ͕ඞཁͱ͢Δ൚༻తͳػೳΛ 3BDLΞϓϦέʔγϣϯʹ௥Ճ͢ΔͨΊͷ ϥΠϒϥϦ ͨͪ ɹɹ˞3BDLϛυϧ΢ΣΞ͸3BDLͷػߏΛར༻͍ͯ͠Δ ը૾ग़యɿIUUQTSBDLHJUIVCJP ػೳ ػೳ ػೳ

Slide 14

Slide 14 text

3BDLϛυϧ΢ΣΞ" "ػೳΛ௥Ճ 3BDLϛυϧ΢ΣΞ# #ػೳΛ௥Ճ 3BDLϛυϧ΢ΣΞ$ $ػೳΛ௥Ճ Α͘ݟΔΠϝʔδਤ 3BDLΞϓϦέʔγϣϯΛத৺ʹɺ ֤3BDLϛυϧ΢ΣΞ͕ͦΕͧΕͷػೳΛ௥Ճ ը૾ग़యɿIUUQTSBDLHJUIVCJP Α͘ݟΔΠϝʔδਤ 3BDLΞϓϦέʔγϣϯ 3BDLΞϓϦ3BDLϛυϧ΢ΣΞ‎Ұͭͷ8FCΞϓϦ ೖΕࢠঢ়ʹͳ͍ͬͯΔ " # $

Slide 15

Slide 15 text

3BJMTͷ৔߹ ʜ Ҿ༻3BJMTΨΠυ3BJMTͱ3BDL"DUJPO%JTQBUDIFSͷϛυϧ΢ΣΞελοΫ 3BJMTΞϓϦέʔγϣϯͰ΋ ଟ͘ͷ3BDLϛυϧ΢ΣΞ͕࢖ΘΕ͍ͯΔ

Slide 16

Slide 16 text

ྫ͑͹ ActionDispatch::Cookies cookieػೳΛఏڙ͠·͢ Ҿ༻3BJMTΨΠυ3BJMTͱ3BDL"DUJPO%JTQBUDIFSͷϛυϧ΢ΣΞελοΫ

Slide 17

Slide 17 text

ྫ͑͹ ͳΔ΄Ͳʂ ʢΘ͔Βͳ͍ʣ Ҿ༻3BJMTΨΠυ3BJMTͱ3BDL"DUJPO%JTQBUDIFSͷϛυϧ΢ΣΞελοΫ

Slide 18

Slide 18 text

ྫɿ"DUJPO%JTQBUDI$PPLJFTͷ৔߹ɹ ஌ࣝͱͯࣗ͠෼͕஌͍ͬͯΔ͜ͱ ɹαʔόʔ͸ΫϥΠΞϯτʹରͯ͠ ɹɹϨεϙϯεϔομΛฦ͢ ɹϨεϙϯεϔομʹ͸ ɹɹ$PPLJFͷ໊લͱ஋ؚ͕·Ε͍ͯΔ Կ͕Θ͔Βͳ͍ͷ͔

Slide 19

Slide 19 text

ྫɿ"DUJPO%JTQBUDI$PPLJFTͷ৔߹ɹ ஌ࣝͱͯࣗ͠෼͕஌͍ͬͯΔ͜ͱ ɹαʔόʔ͸ΫϥΠΞϯτʹରͯ͠ ɹɹϨεϙϯεϔομΛฦ͢ ɹϨεϙϯεϔομʹ͸ ɹɹ$PPLJFͷ໊લͱ஋ؚ͕·Ε͍ͯΔ Կ͕Θ͔Βͳ͍ͷ͔ ‎$PPLJFͷ໊લͱ஋ͱ͸۩ମతʹԿʁ

Slide 20

Slide 20 text

஌Γ͍ͨ ޷ح৺

Slide 21

Slide 21 text

ͱ͍͏͜ͱͰɺ ͔͜͜Β͕ຊฤͰ͢

Slide 22

Slide 22 text

΋͘͡ ɹ3BDLϛυϧ΢ΣΞೖ໳ͷͨΊͷ ɹ3BDLϛυϧ΢ΣΞ ᶃ໨తͱ੒Ռ෺ ᶄ࣮૷ํ਑ͱํ๏ ᶅ༗ޮੑͷݕূ

Slide 23

Slide 23 text

ɹ3BDLϛυϧ΢ΣΞೖ໳ͷͨΊͷ3BDLϛυϧ΢ΣΞ ᶃ໨తͱ੒Ռ෺

Slide 24

Slide 24 text

໨త ྫ͑͹ ֤3BDLϛυϧ΢ΣΞΛ௨͢લͱ௨ͨ͠ޙͰɺ ϨεϙϯεϔομʹͲΜͳมߋ͕͋ͬͨͷ͔஌Γ͍ͨ ը૾ग़యɿIUUQTSBDLHJUIVCJP 3BDLϛυϧ΢ΣΞ#Ͱ ൃੜͨ͠มߋΛ஌Γ͍ͨ 3BDLΞϓϦέʔγϣϯ " # $

Slide 25

Slide 25 text

ର৅ͷ3BDLϛυϧ΢ΣΞΛ௨ͨ͠ޙͷ ϨεϙϯεϔομͷมԽΛλʔϛφϧʹදࣔ͢Δ 3BDLϛυϧ΢ΣΞ Λ࡞Γ·ͨ͠ ੒Ռ෺

Slide 26

Slide 26 text

ͦͷ໊͸ 5SBDF)FBEFS IUUQTHJUIVCDPNTIJPJNNUSBDF@IFBEFS

Slide 27

Slide 27 text

ௐ΂͍ͨϛυϧ΢ΣΞʹରͯ͠ 5SBDF)FBEFSϛυϧ΢ΣΞΛJOTFSU@CFGPSF͢Δ class Application < Rails::Application config.middleware.insert_before ActionDispatch::Cookies, TraceHeader end ࢖͍ํ 3BJMTͷ৔߹ DPOpHBQQMJDBUJPOSC

Slide 28

Slide 28 text

class Application < Rails::Application config.middleware.insert_before ActionDispatch::Cookies, TraceHeader end ɹ[Target Middleware] ɹ ActionDispatch::Cookies ɹ[New Headers] ɹ - ʁʁʁʁ ௐ΂͍ͨϛυϧ΢ΣΞʹରͯ͠ 5SBDF)FBEFSϛυϧ΢ΣΞΛJOTFSU@CFGPSF͢Δ ࢖͍ํ 3BJMTͷ৔߹ λʔϛφϧʹࠩ෼͕දࣔ͞ΕΔ DPOpHBQQMJDBUJPOSC

Slide 29

Slide 29 text

ɹ3BDLϛυϧ΢ΣΞೖ໳ͷͨΊͷ3BDLϛυϧ΢ΣΞ ᶄ࣮૷ํ਑ͱํ๏

Slide 30

Slide 30 text

લఏ 3BDLΞϓϦέʔγϣϯͱ3BDLϛυϧ΢ΣΞ͸ɺ ڞ௨ͷن֨ʹԊ࣮ͬͯ૷͞Ε͍ͯΔ ࣮ߦ؀ڥ FOW ΛҾ਺ʹऔΔΠϯελϯεϝιουDBMMΛ࣮૷͢Δ 3BDLΞϓϦέʔγϣϯͷ৔߹ DBMMϝιου͸ <εςʔλείʔυ \ϔομ^ <ϘσΟ>> ͷ഑ྻΛฦ͢ 3BDLϛυϧ΢ΣΞͷ৔߹ ᶃΠϯελϯεม਺!BQQʹ ࣗ෼ͷ಺ଆͷΫϥεͷΠϯελϯεΛ࣋ͭ ᶄDBMMϝιουͷதͰ !BQQʹରͯ͠DBMMϝιουΛݺͿ ࣍ϖʔδͰ ΋͏গ͠ৄ͘͠ )551Ϩεϙϯε " # $

Slide 31

Slide 31 text

3BDLϛυϧ΢ΣΞͷ಺෦ߏ଄ ྫ ᶄDBMMϝιουͷதͰ ɹ!BQQʹରͯ͠DBMMϝιουΛݺͿ ‎!BQQ͔ΒฦΓ஋Λड͚औΔ ‎ࣗ෼ࣗ਎ͷฦΓ஋Λ֎ଆͷϛυϧ΢ΣΞʹ౉͢ BQQ"OFX #OFX $OFX 3BDLΞϓϦέʔγϣϯͷΠϯελϯε "Πϯελϯεͷ!BQQ#Πϯελϯεͷ!BQQ$Πϯελϯεͷ!BQQ BQQ " DBMMͷதͰ!BQQ # DBMM ‎!BQQ # DBMMͷதͰ!BQQ $ DBMM ‎!BQQ $ DBMMͷதͰ!BQQ 3BDLΞϓϦ DBMM ը૾ग़యɿIUUQTSBDLHJUIVCJP ᶃΠϯελϯεม਺!BQQʹࣗ෼ͷ಺ଆͷΫϥεͷΠϯελϯεΛ࣋ͭ " # $

Slide 32

Slide 32 text

require 'rack' require_relative 'sample_middleware' class SampleApp def call(env) [ 200, {"Content-Type" => "text/plain"}, ["Hello World!\n"] ] end end use SampleMiddleware run SampleApp.new 3BDLΞϓϦέʔγϣϯͷ࣮૷ྫ ഑ྻΛฦ͢ ϛυϧ΢ΣΞΛੵΉ εςʔλείʔυ ϘσΟ ϔομ DPOpHSV

Slide 33

Slide 33 text

3BDLϛυϧ΢ΣΞͷ࣮૷ྫ class SampleMiddleware def initialize(app) @app = app end def call(env) status, header, body = @app.call(env) [ status, header, body ] end end ͦͷଞͷॲཧ 3BDLΞϓϦέʔγϣϯͷฦΓ஋ͱͯ͠ ഑ྻΛฦ͢ Πϯελϯεม਺!BQQ Ҿ਺BQQ ͸ ಺ଆͷϛυϧ΢ΣΞͷΠϯελϯε ಺ଆͷϛυϧ΢ΣΞͷฦΓ஋Λ ഑ྻͱͯ͠ड͚औΔ TBNQMF@NJEEMFXBSFSC

Slide 34

Slide 34 text

3BDLϛυϧ΢ΣΞͷ಺෦ߏ଄͔ΒΘ͔Δ͜ͱ ը૾ग़యɿIUUQTSBDLHJUIVCJP $ΠϯελϯεDBMM FOW ‎<εςʔλείʔυ \ϔομ^ <ϘσΟ>> #ΠϯελϯεDBMM FOW ‎<εςʔλείʔυ \ϔομ^ <ϘσΟ>> "ΠϯελϯεDBMM FOW ‎<εςʔλείʔυ \ϔομ^ <ϘσΟ>> 3BDLΞϓϦέʔγϣϯ 3BDLϛυϧ΢ΣΞ͸ڞ௨ͷن֨ʹԊ࣮ͬͯ૷͞Ε͍ͯΔ ‎Ͳͷϛυϧ΢ΣΞʹରͯ͠DBMMΛݺΜͰ΋ ࠷Լ૚ͷ3BDLΞϓϦέʔγϣϯ·ͰDBMM͞ΕΔ ‎࠷ऴతʹಉ͡ߏ଄ͷ഑ྻ͕ฦΔ " # $

Slide 35

Slide 35 text

͔͜͜ΒཱͯͨԾઆ ը૾ग़యɿIUUQTSBDLHJUIVCJP ର৅ͷϛυϧ΢ΣΞͱͦͷ௚લʹݺ͹Εͨϛυϧ΢ΣΞͷ DBMMϝιουΛݺͼɺฦΓ஋ಉ࢜Λൺֱ͢Ε͹ྑ͍ͷͰ͸ʁ $ΠϯελϯεDBMM FOW ‎ $࣌఺ͷฦΓ஋ #ΠϯελϯεDBMM FOW ‎ #࣌఺ͷฦΓ஋ ᶃ#࣌఺ͱ$࣌఺ͷϛυϧ΢ΣΞ ɹͦΕͧΕͷΠϯελϯεʹͦΕͧΕDBMMΛݺͿ ᶄͦΕͧΕͷฦΓ஋Λऔಘ͢Δ ᶅฦΓ஋ಉ࢜ͷࠩ෼Λλʔϛφϧʹग़ྗ͢Δ 3BDLΞϓϦέʔγϣϯ ࣮૷ํ਑λʔήοτ͕#ͷ৔߹ʜ#͕ݺ͹ΕΔ௚લʹ$͕ݺ͹ΕΔ " $ #

Slide 36

Slide 36 text

͔͠͠

Slide 37

Slide 37 text

՝୊ ը૾ग़యɿIUUQTSBDLHJUIVCJP ྫ͑͹λʔήοτ͕#ͷ৔߹ 3BDLΞϓϦέʔγϣϯͷߏ଄্ɺ ؒʹ͋Δϛυϧ΢ΣΞʹରͯ͠ॲཧΛڬΉ͜ͱ͕Ͱ͖ͳ͍ ᶃ"ͷΠϯελϯεʹରͯ͠DBMM͕ݺ͹ΕΔ ᶄ࠷Լ૚ͷ3BDLΞϓϦέʔγϣϯ·Ͱ ɹશͯͷϛυϧ΢ΣΞͷDBMM͕ݺ͹ΕΔ ᶅ8FCΞϓϦέʔγϣϯͱͯ͠஋͕ฦΔ ࠓճDBMMΛݺͼ͍ͨ #࣌఺ͱ$࣌఺Ͱ ॲཧΛڬΉ͜ͱ͕Ͱ͖ͳ͍ ͭ·Γʜ ᶃ ᶄ ᶅ " # $

Slide 38

Slide 38 text

՝୊ " # $ ը૾ग़యɿIUUQTSBDLHJUIVCJP ྫ͑͹λʔήοτ͕#ͷ৔߹ 3BDLΞϓϦέʔγϣϯͷߏ଄্ɺ ؒʹ͋Δϛυϧ΢ΣΞʹରͯ͠ॲཧΛڬΉ͜ͱ͕Ͱ͖ͳ͍ "ͷΠϯελϯεʹରͯ͠DBMM͕ݺ͹ΕΔͱ ࠷Լ૚ͷ3BDLΞϓϦέʔγϣϯ·Ͱ શͯͷϛυϧ΢ΣΞͷDBMM͕ݺ͹ΕΔ ࠓճDBMMΛݺͼ͍ͨ #࣌఺ͱ$࣌఺Ͱ ॲཧΛڬΉ͜ͱ͕Ͱ͖ͳ͍ ͭ·Γʜ

Slide 39

Slide 39 text

՝୊ " # $ ը૾ग़యɿIUUQTSBDLHJUIVCJP ྫ͑͹λʔήοτ͕#ͷ৔߹ 3BDLΞϓϦέʔγϣϯͷߏ଄্ɺ ؒʹ͋Δϛυϧ΢ΣΞʹରͯ͠ॲཧΛڬΉ͜ͱ͕Ͱ͖ͳ͍ "ͷΠϯελϯεʹରͯ͠DBMM͕ݺ͹ΕΔͱ ࠷Լ૚ͷ3BDLΞϓϦέʔγϣϯ·Ͱ શͯͷϛυϧ΢ΣΞͷDBMM͕ݺ͹ΕΔ ࠓճDBMMΛݺͼ͍ͨ #࣌఺ͱ$࣌఺Ͱ ॲཧΛڬΉ͜ͱ͕Ͱ͖ͳ͍ ͭ·Γʜ 5SBDF1PJOUͷग़൪Ͱ͸ʁ

Slide 40

Slide 40 text

5SBDF1PJOUͱ͸ ɹϓϩάϥϜ࣮ߦதͷΠϕϯτʹϑοΫͯ͠ ɹԿͰ΋Ͱ͖Δ3VCZͷ૊ΈࠐΈϥΠϒϥϦ ɹৄࡉ͸ׂѪ ɹࢀߟهࣄ ɹDMBTT5SBDF1PJOU ɹɹIUUQTEPDTSVCZMBOHPSHKBDMBTT5SBDF1PJOUIUNM 3VCZͷվળΛࣗຫ͍ͨ͠ ɹɹIUUQTUFDIMJGFDPPLQBEDPNFOUSZ ɹ3VCZͷ5SBDF1PJOUʹ͍ͭͯௐ΂ͯΈͨ ɹɹIUUQTRJJUBDPNTJNBOJUFNT⒎DGF ˞Πϕϯτʜϝιουݺͼग़͠΍Ϧλʔϯɺ ɹɹɹɹɹɹΫϥεఆٛɺྫ֎ͷൃੜFUD

Slide 41

Slide 41 text

Ҏ্Λ౿·͑ͯ 5SBDF)FBEFSͷ࣮૷

Slide 42

Slide 42 text

DMBTT5SBDF)FBEFS ‏5SBDF1PJOUΛ࢖༻ ɾࣗ෼ΑΓલʹ࣮ߦ͞Ε͍ͯΔશͯͷϛυϧ΢ΣΞͷ৘ใΛऩू ɾࣗ෼ͷޙʹ࣮ߦ͞ΕΔϛυϧ΢ΣΞ΁ λʔήοτͷϛυϧ΢ΣΞͷฦΓ஋Λ౉͢ ޙଓͷॲཧͷͨΊ ɹ DMBTT3FTVMU ɾλʔήοτͱɺͦͷ௚લʹ࣮ߦ͞Εͨϛυϧ΢ΣΞͷ ΠϯελϯεΛநग़ͯ͠DBMMΛ࣮ߦ ͦΕͧΕͷฦΓ஋Λൺֱ͠ɺࠩ෼Λฦ͢ϝιουΛ࣮૷ NPEVMF%FTDSJCBCMF ɾλʔϛφϧʹදࣔ͢ΔจࣈྻΛ੔͑ΔPVUQVUϝιουΛ࣮૷ ৄࡉ͸ׂѪ ˞5SBDF)FBEFSࣗ਎͸ΞϓϦέʔγϣϯʹมߋΛՃ͑ͳ͍ 5SBDF)FBEFSͷߏ଄

Slide 43

Slide 43 text

5SBDF)FBEFSΠϯελϯεͷ!BQQDBMM FOW Λ࣮ߦ 5SBDF1PJOUΛ࣮ߦ ɹ‎ࣗ෼ΑΓલͷશͯͷϛυϧ΢ΣΞͷ৘ใΛऩू NPEVMF%FTDSJCBCMF DMBTT3FTVMU DMBTT5SBDF)FBEFS DMBTT5SBDF)FBEFS 5SBDF)FBEFSͷॲཧͷྲྀΕ !BQQDBMM FOW ͷฦΓ஋Λޙଓͷϛυϧ΢ΣΞʹ౉͢ 5SBDF)FBEFSΠϯελϯεDBMM FOW ͕ݺ͹ΕΔͱ ௐ΂͍ͨϛυϧ΢ΣΞͷΠϯελϯεDBMM FOW ɹ‎ͦΕͧΕͷฦΓ஋Λൺֱ͠ɺࠩ෼Λऔಘ PVUQVUϝιουͰࠩ෼Λλʔϛφϧʹදࣔ

Slide 44

Slide 44 text

࣮૷ DMBTT5SBDF)FBEFS 1 require 'active_support/core_ext' 6 class TraceHeader 7 include Describable 8 9 def initialize(app) 10 @app = app 11 @datas = [] 12 @fixed_app = nil 13 end 14 15 def call(env) 16 tracer.enable { @app.call(env) } 17 output(result) 18 @fixed_app 19 end ˞จࣈྻΛ੒ܗ͢Δ %FTDSJCBCMFPVUQVUϝιουΛ ࢖༻͢ΔͨΊʹJODMVEF # ...লུ...

Slide 45

Slide 45 text

࣮૷ DMBTT5SBDF)FBEFS 1 require 'active_support/core_ext' 6 class TraceHeader 7 include Describable 8 9 def initialize(app) 10 @app = app 11 @datas = [] 12 @fixed_app = nil 13 end 14 15 16 17 18 19 # ...লུ... !BQQ‎λʔήοτͷϛυϧ΢ΣΞͷΠϯελϯε !EBUBT‎5SBDF1PJOUͷ࣮ߦ݁ՌΛ֨ೲ͢Δ഑ྻ !pYFE@BQQ‎!BQQDBMM FOW ͷฦΓ஋Λ֨ೲ͢Δม਺

Slide 46

Slide 46 text

࣮૷ DMBTT5SBDF)FBEFS 1 require 'active_support/core_ext' 6 class TraceHeader 7 8 9 10 11 12 13 14 15 def call(env) 16 tracer.enable { @app.call(env) } 17 output(result) 18 @fixed_app 19 end # ...লུ... ᶃ ᶄ ᶅ ᶃ!BQQDBMM FOW ΛϑοΫͯ͠5SBDF1PJOUΛ࣮ߦ ᶄ%FTDSJCBCMFPVUQVUͰ࣮ߦ݁ՌSFTVMUΛλʔϛφϧʹදࣔ ᶅ!BQQDBMM FOW ͷฦΓ஋!pYFE@BQQΛ ᶆޙଓͷϛυϧ΢ΣΞʹ౉͢ ˞USBDFS͸5SBDF1PJOUͷΠϯελϯεΛฦ͢ϝιου

Slide 47

Slide 47 text

࣮૷ DMBTT5SBDF)FBEFS 30 def tracer 31 TracePoint.new(:call, :return) do |tp| 32 if tp.rack_middleware_called? 33 if tp.event.eql?(:call) \ 34 && !@datas.find { |op| op[:middleware].eql? tp.defined_class } 35 @datas << { middleware: tp.defined_class, 36 app: tp.self.deep_dup, 37 env: tp.binding.local_variable_get(:env).deep_dup } 38 end 39 40 @fixed_app = tp.return_value if tp.event.eql?(:return) 41 end 42 end 43 44 def result 45 Result.new(@app, @datas) 46 end 47 end 5SBDF1PJOUΛΠϯελϯεԽ ϝιουݺͼग़͠ͱϦλʔϯ࣌ʹ ϒϩοΫ಺ͷॲཧΛ࣮ߦ͢Δ

Slide 48

Slide 48 text

30 def tracer 31 TracePoint.new(:call, :return) do |tp| 32 if tp.rack_middleware_called? 33 34 35 36 37 38 39 40 41 end 42 end 43 44 def result 45 Result.new(@app, @datas) 46 end 47 end ࣮૷ DMBTT5SBDF)FBEFS ࣮ߦதͷΠϕϯτ͕ 3BDLϛυϧ΢ΣΞͷΠϯελϯεʹର͢Δ DBMMϝιουͷݺͼग़͠PSϦλʔϯ Ͱ͋Δ৔߹

Slide 49

Slide 49 text

30 def tracer 31 TracePoint.new(:call, :return) do |tp| 32 if tp.rack_middleware_called? 33 if tp.event.eql?(:call) \ 34 && !@datas.find { |op| op[:middleware].eql? tp.defined_class } 35 36 37 38 39 40 41 42 43 44 def result 45 Result.new(@app, @datas) 46 end 47 end ࣮૷ DMBTT5SBDF)FBEFS ࣮ߦதͷΠϕϯτ͕ ·ͩॲཧ͞Ε͍ͯͳ͍3BDLϛυϧ΢ΣΞʹର͢Δ DBMMϝιουͷݺͼग़͠ Ͱ͋Δ৔߹

Slide 50

Slide 50 text

30 def tracer 31 TracePoint.new(:call, :return) do |tp| 32 if tp.rack_middleware_called? 33 if tp.event.eql?(:call) \ 34 && !@datas.find { |op| op[:middleware].eql? tp.defined_class } 35 @datas << { middleware: tp.defined_class, 36 app: tp.self.deep_dup, 37 env: tp.binding.local_variable_get(:env).deep_dup } 38 end 39 40 41 end 42 end 43 44 def result 45 Result.new(@app, @datas) 46 end 47 end ᶄ ᶅ ࣮૷ DMBTT5SBDF)FBEFS ᶃ ֤ϛυϧ΢ΣΞͷ ᶃΫϥεᶄΠϯελϯεᶅ࣮ߦ؀ڥ Λ഑ྻ!EBUBTʹอଘ

Slide 51

Slide 51 text

30 def tracer 31 TracePoint.new(:call, :return) do |tp| 32 if tp.rack_middleware_called? 33 if tp.event.eql?(:call) \ 34 && !@datas.find { |op| op[:middleware].eql? tp.defined_class } 35 @datas << { middleware: tp.defined_class, 36 app: tp.self.deep_dup, 37 env: tp.binding.local_variable_get(:env).deep_dup } 38 end 39 40 41 end 42 end 43 44 45 46 47 end ᶃ ᶄ ᶃUQTFMG DBMMϝιου͕ݺ͹ΕͨΦϒδΣΫτ ‎ͦͷϛυϧ΢ΣΞͷΠϯελϯε ᶄUQCJOEJOHMPDBM@WBSJBCMF@HFU FOW DBMMϝιου͕ݺ͹ΕͨίϯςΩετͰ ఆٛ͞Ε͍ͯΔϩʔΧϧม਺FOW ‎ͦͷϛυϧ΢ΣΞͷDBMM࣮ߦ࣌ͷҾ਺FOW ࣮૷ DMBTT5SBDF)FBEFS ˞ॏཁ

Slide 52

Slide 52 text

࣮૷ DMBTT5SBDF)FBEFS ˞ॏཁ 30 def tracer 31 TracePoint.new(:call, :return) do |tp| 32 if tp.rack_middleware_called? 33 if tp.event.eql?(:call) \ 34 && !@datas.find { |op| op[:middleware].eql? tp.defined_class } 35 @datas << { middleware: tp.defined_class, 36 app: tp.self.deep_dup, 37 env: tp.binding.local_variable_get(:env).deep_dup } 38 end 39 40 41 end 42 end 43 44 45 46 47 end ཹҙ఺ᶃ ֤ϛυϧ΢ΣΞͷΠϯελϯεͱҾ਺FOW͸ 5SBDF)FBEFSϛυϧ΢ΣΞ λʔήοτͷϛυϧ΢ΣΞ λʔήοτͷ௚લͷϛυϧ΢ΣΞ Ͱಉ͡ΦϒδΣΫτΛࢦ͢

Slide 53

Slide 53 text

࣮૷ DMBTT5SBDF)FBEFS ˞ॏཁ 30 def tracer 31 TracePoint.new(:call, :return) do |tp| 32 if tp.rack_middleware_called? 33 if tp.event.eql?(:call) \ 34 && !@datas.find { |op| op[:middleware].eql? tp.defined_class } 35 @datas << { middleware: tp.defined_class, 36 app: tp.self.deep_dup, 37 env: tp.binding.local_variable_get(:env).deep_dup } 38 end 39 40 41 end 42 end 43 44 45 46 47 end ཹҙ఺ᶄ ֤ϛυϧ΢ΣΞͷΠϯελϯεͱҾ਺FOW͸ DBMMϝιουʹΑͬͯ ஋͕มߋ͞ΕΔՄೳੑ͕͋Δ

Slide 54

Slide 54 text

࣮૷ DMBTT5SBDF)FBEFS ˞ॏཁ 30 def tracer 31 TracePoint.new(:call, :return) do |tp| 32 if tp.rack_middleware_called? 33 if tp.event.eql?(:call) \ 34 && !@datas.find { |op| op[:middleware].eql? tp.defined_class } 35 @datas << { middleware: tp.defined_class, 36 app: tp.self.deep_dup, 37 env: tp.binding.local_variable_get(:env).deep_dup } 38 end 39 40 41 end 42 end 43 44 45 46 47 end ཹҙ఺ᶅ ஋͕มߋ͞ΕͨΦϒδΣΫτʹ ࠶౓DBMMϝιουΛݺͿͱʜ ਖ਼͍͠ฦΓ஋Λฦ͞ͳ͍ ޙଓͷॲཧʹӨڹ͕ग़ΔͳͲ͕ى͜Γ͏Δ ‎յΕΔ

Slide 55

Slide 55 text

࣮૷ DMBTT5SBDF)FBEFS ˞ॏཁ 30 def tracer 31 TracePoint.new(:call, :return) do |tp| 32 if tp.rack_middleware_called? 33 if tp.event.eql?(:call) \ 34 && !@datas.find { |op| op[:middleware].eql? tp.defined_class } 35 @datas << { middleware: tp.defined_class, 36 app: tp.self.deep_dup, 37 env: tp.binding.local_variable_get(:env).deep_dup } 38 end 39 40 41 end 42 end 43 44 45 46 47 end ճආࡦ "DUJWF4VQQPSUEFFQ@EVQΛ࢖ͬͯ σΟʔϓίϐʔΛߦ͏ ‎5SBDF)FBEFSϛυϧ΢ΣΞ಺Ͱ ࢖༻͞Ε͍ͯΔΦϒδΣΫτͱ͸ ແؔ܎ͷΦϒδΣΫτͱͯ͠஋Λऔಘ

Slide 56

Slide 56 text

࣮૷ DMBTT5SBDF)FBEFS 30 def tracer 31 TracePoint.new(:call, :return) do |tp| 32 if tp.rack_middleware_called? 33 if tp.event.eql?(:call) \ 34 && !@datas.find { |op| op[:middleware].eql? tp.defined_class } 35 @datas << { middleware: tp.defined_class, 36 app: tp.self.deep_dup, 37 env: tp.binding.local_variable_get(:env).deep_dup } 38 end 39 40 @fixed_app = tp.return_value if tp.event.eql?(:return) 41 end 42 end 43 44 45 46 47 end ࣮ߦதͷΠϕϯτ͕ DBMMϝιουͷϦλʔϯͰ͋Δ৔߹ ‎!BQQDBMM FOW ͷฦΓ஋Λ!pYFE@BQQʹ୅ೖ

Slide 57

Slide 57 text

࣮૷ DMBTT5SBDF)FBEFS 30 def tracer 31 TracePoint.new(:call, :return) do |tp| 32 if tp.rack_middleware_called? 33 if tp.event.eql?(:call) \ 34 && !@datas.find { |op| op[:middleware].eql? tp.defined_class } 35 @datas << { middleware: tp.defined_class, 36 app: tp.self.deep_dup, 37 env: tp.binding.local_variable_get(:env).deep_dup } 38 end 39 40 41 end 42 end 43 44 def result 45 Result.new(@app, @datas) 46 end 47 end ࠩ෼Λऔಘ͢ΔͨΊ3FTVMUΫϥεΛΠϯελϯεԽ !BQQ‎λʔήοτͷϛυϧ΢ΣΞͷΠϯελϯε !EBUBT‎5SBDF1PJOUͷ࣮ߦ݁ՌΛ֨ೲͨ͠഑ྻ

Slide 58

Slide 58 text

࣮૷ DMBTT3FTVMU 1 class TraceHeader 2 class Result 3 attr_reader :target_app 4 5 def initialize(target_app, datas) 6 @target_app = target_app 7 @target_hash = datas.find { |dt| dt[:middleware].eql?(target_app.class) } 8 @inner_hash = datas[datas.index(target_hash) + 1] 9 end 10 11 def new_headers 12 headers(new_fields) 13 end 14 15 def changed_headers 16 headers(changed_fields) 17 end 18

Slide 59

Slide 59 text

࣮૷ DMBTT3FTVMU 1 class TraceHeader 2 class Result 3 attr_reader :target_app 4 5 def initialize(target_app, datas) 6 @target_app = target_app 7 @target_hash = datas.find { |dt| dt[:middleware].eql?(target_app.class) } 8 @inner_hash = datas[datas.index(target_hash) + 1] 9 end 10 11 def new_headers 12 headers(new_fields) 13 end 14 15 def changed_headers 16 headers(changed_fields) 17 end 18 !UBSHFU@BQQ‎λʔήοτͷϛυϧ΢ΣΞͷΠϯελϯε Ҿ਺EBUBT‎5SBDF1PJOUͷ࣮ߦ݁ՌΛ֨ೲͨ͠഑ྻ ʲҎԼ͸EBUBT͔Βநग़ʳ !UBSHFU@IBTI‎λʔήοτͷϛυϧ΢ΣΞͷ৘ใ !JOOFS@IBTI‎λʔήοτͷ௚લʹݺ͹Εͨ ϛυϧ΢ΣΞͷ৘ใ

Slide 60

Slide 60 text

࣮૷ DMBTT3FTVMU 1 class TraceHeader 2 class Result 3 attr_reader :target_app 4 5 def initialize(target_app, datas) 6 @target_app = target_app 7 @target_hash = datas.find { |dt| dt[:middleware].eql?(target_app.class) } 8 @inner_hash = datas[datas.index(target_hash) + 1] 9 end 10 11 def new_headers 12 headers(new_fields) 13 end 14 15 def changed_headers 16 headers(changed_fields) 17 end 18 !UBSHFU@IBTIͱ!JOOFS@IBTIʹ͸ ͦΕͧΕ࣍ͷΑ͏ͳϋογϡ͕֨ೲ͞Ε͍ͯΔ \NJEEMFXBSFϛυϧ΢ΣΞͷΫϥε BQQϛυϧ΢ΣΞͷΠϯελϯε FOWϛυϧ΢ΣΞ࣮ߦ࣌ͷ؀ڥ^

Slide 61

Slide 61 text

࣮૷ DMBTT3FTVMU 1 class TraceHeader 2 class Result 3 attr_reader :target_app 4 32 33 def target_header 34 @target_header ||= rack_app( @target_hash )[1] 35 end 36 37 def prev_header 38 @prev_header ||= rack_app( @inner_hash )[1] 39 end 40 41 def rack_app(hash) 42 hash[:app].call(hash[:env]) 43 end 44 ᶃλʔήοτͷϛυϧ΢ΣΞͷ৘ใ ᶃͱᶄɺ ͦΕͧΕͷϛυϧ΢ΣΞͷ Πϯελϯεʹରͯ͠DBMM ᶄ௚લʹݺ͹Εͨϛυϧ΢ΣΞͷ৘ใ # ...লུ...

Slide 62

Slide 62 text

࣮૷ DMBTT3FTVMU 1 class TraceHeader 2 class Result 3 attr_reader :target_app 4 32 33 def target_header 34 @target_header ||= rack_app( @target_hash )[1] 35 end 36 37 def prev_header 38 @prev_header ||= rack_app( @inner_hash )[1] 39 end 40 41 def rack_app(hash) 42 hash[:app].call(hash[:env]) 43 end 44 # ...লུ... ฦΓ஋͸ͦΕͧΕ <εςʔλείʔυ \ϔομ^ <ϘσΟ>> ‎ϔομΛऔಘ͢ΔͨΊʹ ‎ΠϯσοΫε<>Λࢦఆ

Slide 63

Slide 63 text

࣮૷ DMBTT3FTVMU 20 21 def common_fields 22 target_header.keys & prev_header.keys 23 end 24 25 def new_fields 26 target_header.keys - common_fields 27 end 28 29 def changed_fields 30 common_fields.select { |field| target_header[field] != prev_header[field] } 31 end 32 46 def headers(fields) 47 fields.map { |field| { field => target_header[field].to_s } } 48 end 49 end ϛυϧ΢ΣΞΛ௨ͨ͠લޙͰڞ௨ͷϔομ໊Λநग़ ৽͘͠௥Ճ͞Εͨϔομ໊Λநग़ ஋͕ॻ͖׵Θͬͨϔομ໊Λநग़ ϔομ໊͔Βϔομͷ஋Λऔಘ # ...লུ...

Slide 64

Slide 64 text

࣮૷ DMBTT3FTVMU 1 class TraceHeader 2 class Result 3 4 5 6 7 8 9 10 11 def new_headers 12 headers(new_fields) 13 end 14 15 def changed_headers 16 headers(changed_fields) 17 end 18 औಘͨ͠஋Λ 3FTVMUOFX@IFBEFST ৽͘͠௥Ճ͞Εͨϔομ 3FTVMUDIBOHFE@IFBEFST ஋͕ॻ͖׵Θͬͨϔομ ͱ࣮ͯ͠૷ ‎%FTDSJCBCMFPVUQVUϝιουͰλʔϛφϧʹදࣔ

Slide 65

Slide 65 text

5SBDF)FBEFSΠϯελϯεͷ!BQQDBMM FOW Λ࣮ߦ PVUQVUϝιουͰࠩ෼Λλʔϛφϧʹදࣔ 5SBDF1PJOUΛ࣮ߦ ɹ‎ࣗ෼ΑΓલͷશͯͷϛυϧ΢ΣΞͷ৘ใΛऩू NPEVMF%FTDSJCBCMF DMBTT3FTVMU DMBTT5SBDF)FBEFS DMBTT5SBDF)FBEFS 5SBDF)FBEFSͷॲཧͷྲྀΕͷ͓͞Β͍ !BQQDBMM FOW ͷฦΓ஋Λޙଓͷϛυϧ΢ΣΞʹ౉͢ 5SBDF)FBEFSΠϯελϯεDBMM FOW ͕ݺ͹ΕΔͱ ௐ΂͍ͨϛυϧ΢ΣΞͷΠϯελϯεDBMM FOW ɹ‎ͦΕͧΕͷฦΓ஋Λൺֱ͠ɺࠩ෼Λऔಘ

Slide 66

Slide 66 text

͓ർΕ༷Ͱͨ͠✨

Slide 67

Slide 67 text

ɹ3BDLϛυϧ΢ΣΞೖ໳ͷͨΊͷ3BDLϛυϧ΢ΣΞ ᶅ༗ޮੑͷݕূ

Slide 68

Slide 68 text

"DUJPO%JTQBUDI$PPLJFTΛ௨ͨ͠ޙɺ ৽͘͠௥Ճ͞ΕͨϔομΛλʔϛφϧʹදࣔ͢Δ class Application < Rails::Application config.middleware.insert_before ActionDispatch::Cookies, TraceHeader end ݕূ DPOpHBQQMJDBUJPOSC ݕূ؀ڥ3VCZ 3BJMT ɹ4DB⒎PME͚ͨͩ͠ͷ؆୯ͳΞϓϦέʔγϣϯ ݕূํ๏αʔόʔΛ্ཱͪ͛ͯద౰ͳϖʔδʹΞΫηε

Slide 69

Slide 69 text

ͦͷ݁Ռ

Slide 70

Slide 70 text

݁Ռ ࣮ࡍͷը໘ ‎Ͱ͖·ͨ͠ "DUJPO%JTQBUDI$PPLJFTΛ௨ͨ͠ޙɺ ৽͘͠௥Ճ͞ΕͨϔομΛλʔϛφϧʹදࣔ͢Δ

Slide 71

Slide 71 text

---------------------------------------------------- TraceHeader printing... [Target Middleware] ActionDispatch::Cookies [New Headers] - Set-Cookie: _sampleapp_session=P8jTL8...; path=/; HttpOnly [Changed Headers] - ETag: W/"f25d17d6ad73a7091771928fef7cc6f8" ---------------------------------------------------- ϛυϧ΢ΣΞ໊ ৽͍͠ϔομͷ໊લͱ஋ ஋͕ॻ͖׵Θͬͨϔομͷ໊લͱ஋ ݁Ռ ֦େ "DUJPO%JTQBUDI$PPLJFTΛ௨ͨ͠ޙɺ ৽͘͠௥Ճ͞ΕͨϔομΛλʔϛφϧʹදࣔ͢Δ

Slide 72

Slide 72 text

৽͘͠௥Ճ͞Εͨϔομ4FU$PPLJF ᶃ@TBNQMFBQQ@TFTTJPO1K5-IUCIPHFIPHFGVHBHVGB ᶄQBUI ᶅ)UUQ0OMZ ஋͕มߋ͞Εͨϔομ&5BH ᶆ8GEEBEBGFGDDG "DUJPO%JTQBUDI$PPLJFT͕ϔομʹ༩࣮͑ͨࡍͷ஋͔Β ৭ʑͳൃݟ͕͋Γ·ͨ͠ ݁Ռ͔ΒಘΒΕͨ΋ͷ ᶃ஋͸ʮ@ΞϓϦ໊@TFTTJPOϥϯμϜͳӳ਺ࣈʯ ᶄσϑΥϧτͰQBUIଐੑ͕ϧʔτʹઃఆ͞ΕΔ ᶅσϑΥϧτͰ)UUQ0OMZʹͳΔ ᶆ&5BH͸Ͳͷϛυϧ΢ΣΞΛ௨ͯ͠΋ॻ͖׵ΘΔ

Slide 73

Slide 73 text

'VLVPLBSC͔Βͷ͓ͨΑΓ঺հ CZ!VE[VSB͞Μ ൃදࢿྉͷϨϏϡʔΛ͓ئ͍ͨ͠'VLVPLBSC͔Β ײ૝Λ௖͖·ͨ͠ɻ

Slide 74

Slide 74 text

5SBDF)FBEFSͷ༗ޮੑ

Slide 75

Slide 75 text

5SBDF)FBEFSͷ༗ޮੑ ͋Γͦ͏ 13͍ͭͰ΋͓଴͓ͪͯ͠Γ·͢ IUUQTHJUIVCDPNTIJPJNNUSBDF@IFBEFS

Slide 76

Slide 76 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ ɹ4QFDJBM5IBOLT✨ !UEUET͞Μ !LBLVUBOJ͞Μ !KPLFS͞Μɹ !ZPVDIBO͞Μ !PLVSBNBTBGVNJ͞Μ !VE[VSB͞Μ !KJNMPDL͞Μ"TBLVTBSC⚡'VLVPLBSC ը૾ग़యIUUQTUXJUUFSDPN