Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Rackミドルウェア入門のためのRackミドルウェア
Misaki Shioi(塩井美咲/しおい)
December 21, 2019
Programming
6
4.7k
Rackミドルウェア入門のためのRackミドルウェア
Misaki Shioi(塩井美咲/しおい)
December 21, 2019
Tweet
Share
More Decks by Misaki Shioi(塩井美咲/しおい)
See All by Misaki Shioi(塩井美咲/しおい)
Packet analysis with mruby on Wireshark - dRuby as example
coe401_
3
1.8k
実録mruby組み込み体験
coe401_
0
1.2k
Toycol: Define your own application protocol
coe401_
2
1.4k
らくらくRactor
coe401_
3
350
[English ver]実録 Let's build a simple Rack compatible server
coe401_
1
100
実録 Let's build a simple Rack compatible server
coe401_
6
1.8k
たのしいOSSコードリーディング:Let's read "cookies"🍪
coe401_
15
7.8k
ApplaudHerJp.pdf
coe401_
2
560
Other Decks in Programming
See All in Programming
はてなリモートインターンシップ2022 Web API 講義資料
hatena
0
150
Git Rebase
bkuhlmann
10
1.2k
フロントエンドで 良いコードを書くために
t_keshi
3
1.6k
はてなリモートインターンシップ2022 フロントエンドブートキャンプ 講義資料
hatena
0
110
TypeScript 4.9のas const satisfiesが便利
tonkotsuboy_com
9
2.2k
【DevFest & ADS JP 22】チームで導入する
[email protected]
おいしい健康
kako351
0
210
AWSとCPUのムフフな関係
cmdemura
0
430
Above All, Make It Fun! #fjordbootcamp / make it fun
kakutani
6
540
An Advanced Introduction to R
nicetak
0
1.5k
Rによる大規模データの処理
s_uryu
2
610
Swift Expression Macros: a practical introduction
kishikawakatsumi
2
680
Form実装基本を学び直してみた
hyugatsukui
0
200
Featured
See All Featured
Three Pipe Problems
jasonvnalue
89
8.9k
VelocityConf: Rendering Performance Case Studies
addyosmani
317
22k
Intergalactic Javascript Robots from Outer Space
tanoku
261
26k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
349
27k
GraphQLとの向き合い方2022年版
quramy
20
9.8k
A better future with KSS
kneath
230
16k
Bash Introduction
62gerente
601
210k
What's in a price? How to price your products and services
michaelherold
233
9.7k
Teambox: Starting and Learning
jrom
124
7.9k
Designing for Performance
lara
601
65k
Happy Clients
brianwarren
90
5.8k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
6
830
Transcript
3BDLϛυϧΣΞೖͷͨΊͷ 3BDLϛυϧΣΞ ԘҪඒ࡙!DPF@ %FD 5PLZP(JSMTSC.FFUVQWPM
ٕज़తʹ͍༰ؚ·Ε͍ͯΔ͔ͱࢥ͍·͢ɻ օ༷͔Βͷ͝ࢦఠɾ13Λ ͓͓ͪͯ͠Γ·͢
ࣗݾհ ԘҪඒ࡙!DPF@ 8FCϓϩάϥϚGSPNגࣜձࣾΩϟλϧ 5BNBSCɺ"TBLVTBSCɺ'VLVPLBSCʢཧʣʹ͍·͢ ࠷ۙؾʹͳΔϥΠϒϥϦ3BDL
ࣗݾհ ԘҪඒ࡙!DPF@ 8FCϓϩάϥϚGSPNגࣜձࣾΩϟλϧ 5BNBSCɺ"TBLVTBSCɺ'VLVPLBSCʢཧʣʹ͍·͢ ࠷ۙؾʹͳΔϥΠϒϥϦ3BDL ‐ࠓͷ͓
3BDLͬͯԿͰ͚ͨͬ͠ʜʁ ʢهԱࣦʣ
8FCαʔόʔͱ8FCΞϓϦέʔγϣϯΛܨ͙ϓϩτίϧ 8FCαʔόʔͱ8FCΞϓϦέʔγϣϯΛܨ͙ϥΠϒϥϦ 3BDLϓϩτίϧΛຬͨͨ͠8FCαʔόʔͱ 3BDLϓϩτίϧΛຬͨͨ͠8FCΞϓϦέʔγϣϯؒΛ 3BDLϥΠϒϥϦ͕औΓ࣋ͭ 3BDLͱ ը૾ग़యɿIUUQTSVCZPOSBJMTPSH͓ΑͼIUUQTSBDLHJUIVCJP
8FCαʔόʔͱ8FCΞϓϦέʔγϣϯΛܨ͙ϓϩτίϧ 8FCαʔόʔͱ8FCΞϓϦέʔγϣϯΛܨ͙ϥΠϒϥϦ 3BDLϓϩτίϧΛຬͨͨ͠8FCαʔόʔͱ 3BDLϓϩτίϧΛຬͨͨ͠8FCΞϓϦέʔγϣϯؒΛ 3BDLϥΠϒϥϦ͕औΓ࣋ͭ 3BDLͱ ը૾ग़యɿIUUQTSVCZPOSBJMTPSH͓ΑͼIUUQTSBDLHJUIVCJP 3BDLΞϓϦέʔγϣϯ
3BDLΞϓϦέʔγϣϯͷ͓ ը૾ग़యɿIUUQTSVCZPOSBJMTPSH͓ΑͼIUUQTSBDLHJUIVCJP ɹྫ͑ɺ3BJMTΞϓϦέʔγϣϯ͔Β ɹ3BJMTಛ༗ͷॾʑΛશ෦ണ͕͍ͯ͘͠ͱʜ ɹ
3BDLΞϓϦέʔγϣϯͷ͓ ɹྫ͑ɺ3BJMTΞϓϦέʔγϣϯ͔Β ɹ3BJMTಛ༗ͷॾʑΛશ෦ണ͕͍ͯ͘͠ͱʜ ɹ ࠷ޙʹΔͷ͕ૉͷ3BDLΞϓϦέʔγϣϯ ˞3BJMTҎ֎ͷ3VCZͰॻ͔Εͨ8FCΞϓϦέʔγϣϯϑϨʔϜϫʔΫಉ༷ ը૾ग़యɿIUUQTSVCZPOSBJMTPSH͓ΑͼIUUQTSBDLHJUIVCJP
Ұ൪γϯϓϧͳྫ ɹ3BDLΞϓϦέʔγϣϯɺ ɹ8FCΞϓϦέʔγϣϯΛߏ͢ΔͨΊʹඞཁͳ ɹͭͷཁૉΛ࣋ͬͨྻ͔ΒΔ [ 200, { "Content-Type" => "text/plain"
}, ["Hello World!\n"] ] εςʔλείʔυ ϔομ ϘσΟ 3BDLΞϓϦέʔγϣϯͷߏ
Ұ൪γϯϓϧͳྫ ɹ ͱ͍͑ ɹ࣮ࡍͷ8FCΞϓϦέʔγϣϯ ɹͬͱ৭ʑෳࡶͳػೳΛ͍࣋ͬͯΔͷͳͷͰʜʁ [ 200, { "Content-Type" =>
"text/plain" }, ["Hello World!\n"] ]
Ұ൪γϯϓϧͳྫ ɹ ͱ͍͑ ͦΜͳ࣌3BDLϛυϧΣΞͷग़൪ ɹ࣮ࡍͷ8FCΞϓϦέʔγϣϯ ɹͬͱ৭ʑෳࡶͳػೳΛ͍࣋ͬͯΔͷͳͷͰʜʁ [ 200, { "Content-Type"
=> "text/plain" }, ["Hello World!\n"] ]
3BDLϛυϧΣΞͱ 8FCΞϓϦέʔγϣϯ͕ඞཁͱ͢Δ൚༻తͳػೳΛ 3BDLΞϓϦέʔγϣϯʹՃ͢ΔͨΊͷ ϥΠϒϥϦ ͨͪ ɹɹ˞3BDLϛυϧΣΞ3BDLͷػߏΛར༻͍ͯ͠Δ ը૾ग़యɿIUUQTSBDLHJUIVCJP
ػೳ ػೳ ػೳ
3BDLϛυϧΣΞ" "ػೳΛՃ 3BDLϛυϧΣΞ# #ػೳΛՃ 3BDLϛυϧΣΞ$ $ػೳΛՃ Α͘ݟΔΠϝʔδਤ 3BDLΞϓϦέʔγϣϯΛத৺ʹɺ ֤3BDLϛυϧΣΞ͕ͦΕͧΕͷػೳΛՃ ը૾ग़యɿIUUQTSBDLHJUIVCJP
Α͘ݟΔΠϝʔδਤ 3BDLΞϓϦέʔγϣϯ 3BDLΞϓϦ 3BDLϛυϧΣΞҰͭͷ8FCΞϓϦ ೖΕࢠঢ়ʹͳ͍ͬͯΔ " # $
3BJMTͷ߹ ʜ Ҿ༻3BJMTΨΠυ3BJMTͱ3BDL"DUJPO%JTQBUDIFSͷϛυϧΣΞελοΫ 3BJMTΞϓϦέʔγϣϯͰ ଟ͘ͷ3BDLϛυϧΣΞ͕ΘΕ͍ͯΔ
ྫ͑ ActionDispatch::Cookies cookieػೳΛఏڙ͠·͢ Ҿ༻3BJMTΨΠυ3BJMTͱ3BDL"DUJPO%JTQBUDIFSͷϛυϧΣΞελοΫ
ྫ͑ ͳΔ΄Ͳʂ ʢΘ͔Βͳ͍ʣ Ҿ༻3BJMTΨΠυ3BJMTͱ3BDL"DUJPO%JTQBUDIFSͷϛυϧΣΞελοΫ
ྫɿ"DUJPO%JTQBUDI$PPLJFTͷ߹ɹ ࣝͱ͕͍ͯࣗͬͯ͠Δ͜ͱ ɹαʔόʔΫϥΠΞϯτʹରͯ͠ ɹɹϨεϙϯεϔομΛฦ͢ ɹϨεϙϯεϔομʹ ɹɹ$PPLJFͷ໊લͱؚ͕·Ε͍ͯΔ Կ͕Θ͔Βͳ͍ͷ͔
ྫɿ"DUJPO%JTQBUDI$PPLJFTͷ߹ɹ ࣝͱ͕͍ͯࣗͬͯ͠Δ͜ͱ ɹαʔόʔΫϥΠΞϯτʹରͯ͠ ɹɹϨεϙϯεϔομΛฦ͢ ɹϨεϙϯεϔομʹ ɹɹ$PPLJFͷ໊લͱؚ͕·Ε͍ͯΔ Կ͕Θ͔Βͳ͍ͷ͔ $PPLJFͷ໊લͱͱ۩ମతʹԿʁ
Γ͍ͨ ح৺
ͱ͍͏͜ͱͰɺ ͔͜͜Β͕ຊฤͰ͢
͘͡ ɹ3BDLϛυϧΣΞೖͷͨΊͷ ɹ3BDLϛυϧΣΞ ᶃతͱՌ ᶄ࣮ํͱํ๏ ᶅ༗ޮੑͷݕূ
ɹ3BDLϛυϧΣΞೖͷͨΊͷ3BDLϛυϧΣΞ ᶃతͱՌ
త ྫ͑ ֤3BDLϛυϧΣΞΛ௨͢લͱ௨ͨ͠ޙͰɺ ϨεϙϯεϔομʹͲΜͳมߋ͕͋ͬͨͷ͔Γ͍ͨ ը૾ग़యɿIUUQTSBDLHJUIVCJP 3BDLϛυϧΣΞ#Ͱ ൃੜͨ͠มߋΛΓ͍ͨ 3BDLΞϓϦέʔγϣϯ "
# $
ରͷ3BDLϛυϧΣΞΛ௨ͨ͠ޙͷ ϨεϙϯεϔομͷมԽΛλʔϛφϧʹදࣔ͢Δ 3BDLϛυϧΣΞ Λ࡞Γ·ͨ͠ Ռ
ͦͷ໊ 5SBDF)FBEFS IUUQTHJUIVCDPNTIJPJNN
[email protected]
ௐ͍ͨϛυϧΣΞʹରͯ͠ 5SBDF)FBEFSϛυϧΣΞΛ
[email protected]
͢Δ class Application < Rails::Application config.middleware.insert_before ActionDispatch::Cookies, TraceHeader end
͍ํ 3BJMTͷ߹ DPOpHBQQMJDBUJPOSC
class Application < Rails::Application config.middleware.insert_before ActionDispatch::Cookies, TraceHeader end ɹ[Target Middleware]
ɹ ActionDispatch::Cookies ɹ[New Headers] ɹ - ʁʁʁʁ ௐ͍ͨϛυϧΣΞʹରͯ͠ 5SBDF)FBEFSϛυϧΣΞΛ
[email protected]
͢Δ ͍ํ 3BJMTͷ߹ λʔϛφϧʹ͕ࠩදࣔ͞ΕΔ DPOpHBQQMJDBUJPOSC
ɹ3BDLϛυϧΣΞೖͷͨΊͷ3BDLϛυϧΣΞ ᶄ࣮ํͱํ๏
લఏ 3BDLΞϓϦέʔγϣϯͱ3BDLϛυϧΣΞɺ ڞ௨ͷن֨ʹԊ࣮ͬͯ͞Ε͍ͯΔ ࣮ߦڥ FOW ΛҾʹऔΔΠϯελϯεϝιουDBMMΛ࣮͢Δ 3BDLΞϓϦέʔγϣϯͷ߹ DBMMϝιου
<εςʔλείʔυ \ϔομ^ <ϘσΟ>> ͷྻΛฦ͢ 3BDLϛυϧΣΞͷ߹ ᶃΠϯελϯεม!BQQʹ ࣗͷଆͷΫϥεͷΠϯελϯεΛ࣋ͭ ᶄDBMMϝιουͷதͰ !BQQʹରͯ͠DBMMϝιουΛݺͿ ࣍ϖʔδͰ ͏গ͠ৄ͘͠ )551Ϩεϙϯε " # $
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ʹࣗͷଆͷΫϥεͷΠϯελϯεΛ࣋ͭ " # $
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
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 ଆͷϛυϧΣΞͷΠϯελϯε ଆͷϛυϧΣΞͷฦΓΛ ྻͱͯ͠ड͚औΔ
[email protected]
SC
3BDLϛυϧΣΞͷ෦ߏ͔ΒΘ͔Δ͜ͱ ը૾ग़యɿIUUQTSBDLHJUIVCJP $ΠϯελϯεDBMM FOW <εςʔλείʔυ \ϔομ^ <ϘσΟ>> #ΠϯελϯεDBMM FOW
<εςʔλείʔυ \ϔομ^ <ϘσΟ>> "ΠϯελϯεDBMM FOW <εςʔλείʔυ \ϔομ^ <ϘσΟ>> 3BDLΞϓϦέʔγϣϯ 3BDLϛυϧΣΞڞ௨ͷن֨ʹԊ࣮ͬͯ͞Ε͍ͯΔ ͲͷϛυϧΣΞʹରͯ͠DBMMΛݺΜͰ ࠷Լͷ3BDLΞϓϦέʔγϣϯ·ͰDBMM͞ΕΔ ࠷ऴతʹಉ͡ߏͷྻ͕ฦΔ " # $
͔͜͜ΒཱͯͨԾઆ ը૾ग़యɿIUUQTSBDLHJUIVCJP ରͷϛυϧΣΞͱͦͷલʹݺΕͨϛυϧΣΞͷ DBMMϝιουΛݺͼɺฦΓಉ࢜Λൺֱ͢Εྑ͍ͷͰʁ $ΠϯελϯεDBMM FOW $࣌ͷฦΓ #ΠϯελϯεDBMM FOW
#࣌ͷฦΓ ᶃ#࣌ͱ$࣌ͷϛυϧΣΞ ɹͦΕͧΕͷΠϯελϯεʹͦΕͧΕDBMMΛݺͿ ᶄͦΕͧΕͷฦΓΛऔಘ͢Δ ᶅฦΓಉ࢜ͷࠩΛλʔϛφϧʹग़ྗ͢Δ 3BDLΞϓϦέʔγϣϯ ࣮ํλʔήοτ͕#ͷ߹ʜ#͕ݺΕΔલʹ$͕ݺΕΔ " $ #
͔͠͠
՝ ը૾ग़యɿIUUQTSBDLHJUIVCJP ྫ͑λʔήοτ͕#ͷ߹ 3BDLΞϓϦέʔγϣϯͷߏ্ɺ ؒʹ͋ΔϛυϧΣΞʹରͯ͠ॲཧΛڬΉ͜ͱ͕Ͱ͖ͳ͍ ᶃ"ͷΠϯελϯεʹରͯ͠DBMM͕ݺΕΔ ᶄ࠷Լͷ3BDLΞϓϦέʔγϣϯ·Ͱ ɹશͯͷϛυϧΣΞͷDBMM͕ݺΕΔ ᶅ8FCΞϓϦέʔγϣϯͱ͕ͯ͠ฦΔ ࠓճDBMMΛݺͼ͍ͨ
#࣌ͱ$࣌Ͱ ॲཧΛڬΉ͜ͱ͕Ͱ͖ͳ͍ ͭ·Γʜ ᶃ ᶄ ᶅ " # $
՝ " # $ ը૾ग़యɿIUUQTSBDLHJUIVCJP ྫ͑λʔήοτ͕#ͷ߹ 3BDLΞϓϦέʔγϣϯͷߏ্ɺ ؒʹ͋ΔϛυϧΣΞʹରͯ͠ॲཧΛڬΉ͜ͱ͕Ͱ͖ͳ͍ "ͷΠϯελϯεʹରͯ͠DBMM͕ݺΕΔͱ ࠷Լͷ3BDLΞϓϦέʔγϣϯ·Ͱ
શͯͷϛυϧΣΞͷDBMM͕ݺΕΔ ࠓճDBMMΛݺͼ͍ͨ #࣌ͱ$࣌Ͱ ॲཧΛڬΉ͜ͱ͕Ͱ͖ͳ͍ ͭ·Γʜ
՝ " # $ ը૾ग़యɿIUUQTSBDLHJUIVCJP ྫ͑λʔήοτ͕#ͷ߹ 3BDLΞϓϦέʔγϣϯͷߏ্ɺ ؒʹ͋ΔϛυϧΣΞʹରͯ͠ॲཧΛڬΉ͜ͱ͕Ͱ͖ͳ͍ "ͷΠϯελϯεʹରͯ͠DBMM͕ݺΕΔͱ ࠷Լͷ3BDLΞϓϦέʔγϣϯ·Ͱ
શͯͷϛυϧΣΞͷDBMM͕ݺΕΔ ࠓճDBMMΛݺͼ͍ͨ #࣌ͱ$࣌Ͱ ॲཧΛڬΉ͜ͱ͕Ͱ͖ͳ͍ ͭ·Γʜ 5SBDF1PJOUͷग़൪Ͱʁ
5SBDF1PJOUͱ ɹϓϩάϥϜ࣮ߦதͷΠϕϯτʹϑοΫͯ͠ ɹԿͰͰ͖Δ3VCZͷΈࠐΈϥΠϒϥϦ ɹৄࡉׂѪ ɹࢀߟهࣄ ɹDMBTT5SBDF1PJOU ɹɹIUUQTEPDTSVCZMBOHPSHKBDMBTT5SBDF1PJOUIUNM 3VCZͷվળΛࣗຫ͍ͨ͠ ɹɹIUUQTUFDIMJGFDPPLQBEDPNFOUSZ ɹ3VCZͷ5SBDF1PJOUʹ͍ͭͯௐͯΈͨ
ɹɹIUUQTRJJUBDPNTJNBOJUFNT⒎DGF ˞Πϕϯτʜϝιουݺͼग़͠Ϧλʔϯɺ ɹɹɹɹɹɹΫϥεఆٛɺྫ֎ͷൃੜFUD
Ҏ্Λ౿·͑ͯ 5SBDF)FBEFSͷ࣮
DMBTT5SBDF)FBEFS 5SBDF1PJOUΛ༻ ɾࣗΑΓલʹ࣮ߦ͞Ε͍ͯΔશͯͷϛυϧΣΞͷใΛऩू ɾࣗͷޙʹ࣮ߦ͞ΕΔϛυϧΣΞ λʔήοτͷϛυϧΣΞͷฦΓΛ͢ ޙଓͷॲཧͷͨΊ ɹ DMBTT3FTVMU ɾλʔήοτͱɺͦͷલʹ࣮ߦ͞ΕͨϛυϧΣΞͷ
ΠϯελϯεΛநग़ͯ͠DBMMΛ࣮ߦ ͦΕͧΕͷฦΓΛൺֱ͠ɺࠩΛฦ͢ϝιουΛ࣮ NPEVMF%FTDSJCBCMF ɾλʔϛφϧʹදࣔ͢ΔจࣈྻΛ͑ΔPVUQVUϝιουΛ࣮ ৄࡉׂѪ ˞5SBDF)FBEFSࣗΞϓϦέʔγϣϯʹมߋΛՃ͑ͳ͍ 5SBDF)FBEFSͷߏ
5SBDF)FBEFSΠϯελϯεͷ!BQQDBMM FOW Λ࣮ߦ 5SBDF1PJOUΛ࣮ߦ ɹࣗΑΓલͷશͯͷϛυϧΣΞͷใΛऩू NPEVMF%FTDSJCBCMF DMBTT3FTVMU DMBTT5SBDF)FBEFS DMBTT5SBDF)FBEFS 5SBDF)FBEFSͷॲཧͷྲྀΕ
!BQQDBMM FOW ͷฦΓΛޙଓͷϛυϧΣΞʹ͢ 5SBDF)FBEFSΠϯελϯεDBMM FOW ͕ݺΕΔͱ ௐ͍ͨϛυϧΣΞͷΠϯελϯεDBMM FOW ɹͦΕͧΕͷฦΓΛൺֱ͠ɺࠩΛऔಘ PVUQVUϝιουͰࠩΛλʔϛφϧʹදࣔ
࣮ 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 # ...লུ...
࣮ 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λʔήοτͷϛυϧΣΞͷΠϯελϯε !EBUBT5SBDF1PJOUͷ࣮ߦ݁ՌΛ֨ೲ͢Δྻ
[email protected]
!BQQDBMM FOW ͷฦΓΛ֨ೲ͢Δม
࣮ 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 ͷฦΓ
[email protected]
Λ ᶆޙଓͷϛυϧΣΞʹ͢ ˞USBDFS5SBDF1PJOUͷΠϯελϯεΛฦ͢ϝιου
࣮ 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 &&
[email protected]
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ΛΠϯελϯεԽ ϝιουݺͼग़͠ͱϦλʔϯ࣌ʹ ϒϩοΫͷॲཧΛ࣮ߦ͢Δ
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Ϧλʔϯ Ͱ͋Δ߹
30 def tracer 31 TracePoint.new(:call, :return) do |tp| 32 if
tp.rack_middleware_called? 33 if tp.event.eql?(:call) \ 34 &&
[email protected]
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ϝιουͷݺͼग़͠ Ͱ͋Δ߹
30 def tracer 31 TracePoint.new(:call, :return) do |tp| 32 if
tp.rack_middleware_called? 33 if tp.event.eql?(:call) \ 34 &&
[email protected]
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ʹอଘ
30 def tracer 31 TracePoint.new(:call, :return) do |tp| 32 if
tp.rack_middleware_called? 33 if tp.event.eql?(:call) \ 34 &&
[email protected]
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ϝιου͕ݺΕͨΦϒδΣΫτ ͦͷϛυϧΣΞͷΠϯελϯε ᶄUQCJOEJOH
[email protected]
@HFU FOW DBMMϝιου͕ݺΕͨίϯςΩετͰ ఆٛ͞Ε͍ͯΔϩʔΧϧมFOW ͦͷϛυϧΣΞͷDBMM࣮ߦ࣌ͷҾFOW ࣮ DMBTT5SBDF)FBEFS ˞ॏཁ
࣮ 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 &&
[email protected]
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ϛυϧΣΞ λʔήοτͷϛυϧΣΞ λʔήοτͷલͷϛυϧΣΞ Ͱಉ͡ΦϒδΣΫτΛࢦ͢
࣮ 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 &&
[email protected]
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ϝιουʹΑͬͯ ͕มߋ͞ΕΔՄೳੑ͕͋Δ
࣮ 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 &&
[email protected]
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ϝιουΛݺͿͱʜ ਖ਼͍͠ฦΓΛฦ͞ͳ͍ ޙଓͷॲཧʹӨڹ͕ग़ΔͳͲ͕ى͜Γ͏Δ յΕΔ
࣮ 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 &&
[email protected]
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 ճආࡦ "DUJWF4VQQPSU
[email protected]
Λͬͯ σΟʔϓίϐʔΛߦ͏ 5SBDF)FBEFSϛυϧΣΞͰ ༻͞Ε͍ͯΔΦϒδΣΫτͱ ແؔͷΦϒδΣΫτͱͯ͠Λऔಘ
࣮ 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 &&
[email protected]
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 ͷฦΓΛ
[email protected]
ʹೖ
࣮ 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 &&
[email protected]
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λʔήοτͷϛυϧΣΞͷΠϯελϯε !EBUBT5SBDF1PJOUͷ࣮ߦ݁ՌΛ֨ೲͨ͠ྻ
࣮ 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
࣮ 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
[email protected]
λʔήοτͷϛυϧΣΞͷΠϯελϯε ҾEBUBT5SBDF1PJOUͷ࣮ߦ݁ՌΛ֨ೲͨ͠ྻ ʲҎԼEBUBT͔Βநग़ʳ
[email protected]
λʔήοτͷϛυϧΣΞͷใ
[email protected]
λʔήοτͷલʹݺΕͨ ϛυϧΣΞͷใ
࣮ 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
[email protected]
ͱ
[email protected]
ʹ ͦΕͧΕ࣍ͷΑ͏ͳϋογϡ͕֨ೲ͞Ε͍ͯΔ \NJEEMFXBSFϛυϧΣΞͷΫϥε BQQϛυϧΣΞͷΠϯελϯε FOWϛυϧΣΞ࣮ߦ࣌ͷڥ^
࣮ 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 ᶄલʹݺΕͨϛυϧΣΞͷใ # ...লུ...
࣮ 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 # ...লུ... ฦΓͦΕͧΕ <εςʔλείʔυ \ϔομ^ <ϘσΟ>> ϔομΛऔಘ͢ΔͨΊʹ ΠϯσοΫε<>Λࢦఆ
࣮ 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 ϛυϧΣΞΛ௨ͨ͠લޙͰڞ௨ͷϔομ໊Λநग़ ৽͘͠Ճ͞Εͨϔομ໊Λநग़ ͕ॻ͖Θͬͨϔομ໊Λநग़ ϔομ໊͔ΒϔομͷΛऔಘ # ...লུ...
࣮ 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 औಘͨ͠Λ 3FTVMU
[email protected]
৽͘͠Ճ͞Εͨϔομ 3FTVMU
[email protected]
͕ॻ͖Θͬͨϔομ ͱ࣮ͯ͠ %FTDSJCBCMFPVUQVUϝιουͰλʔϛφϧʹදࣔ
5SBDF)FBEFSΠϯελϯεͷ!BQQDBMM FOW Λ࣮ߦ PVUQVUϝιουͰࠩΛλʔϛφϧʹදࣔ 5SBDF1PJOUΛ࣮ߦ ɹࣗΑΓલͷશͯͷϛυϧΣΞͷใΛऩू NPEVMF%FTDSJCBCMF DMBTT3FTVMU DMBTT5SBDF)FBEFS DMBTT5SBDF)FBEFS
5SBDF)FBEFSͷॲཧͷྲྀΕͷ͓͞Β͍ !BQQDBMM FOW ͷฦΓΛޙଓͷϛυϧΣΞʹ͢ 5SBDF)FBEFSΠϯελϯεDBMM FOW ͕ݺΕΔͱ ௐ͍ͨϛυϧΣΞͷΠϯελϯεDBMM FOW ɹͦΕͧΕͷฦΓΛൺֱ͠ɺࠩΛऔಘ
͓ർΕ༷Ͱͨ͠✨
ɹ3BDLϛυϧΣΞೖͷͨΊͷ3BDLϛυϧΣΞ ᶅ༗ޮੑͷݕূ
"DUJPO%JTQBUDI$PPLJFTΛ௨ͨ͠ޙɺ ৽͘͠Ճ͞ΕͨϔομΛλʔϛφϧʹදࣔ͢Δ class Application < Rails::Application config.middleware.insert_before ActionDispatch::Cookies, TraceHeader end
ݕূ DPOpHBQQMJDBUJPOSC ݕূڥ3VCZ 3BJMT ɹ4DB⒎PME͚ͨͩ͠ͷ؆୯ͳΞϓϦέʔγϣϯ ݕূํ๏αʔόʔΛ্ཱͪ͛ͯదͳϖʔδʹΞΫηε
ͦͷ݁Ռ
݁Ռ ࣮ࡍͷը໘ Ͱ͖·ͨ͠ "DUJPO%JTQBUDI$PPLJFTΛ௨ͨ͠ޙɺ ৽͘͠Ճ͞ΕͨϔομΛλʔϛφϧʹදࣔ͢Δ
---------------------------------------------------- TraceHeader printing... [Target Middleware] ActionDispatch::Cookies [New Headers] - Set-Cookie:
_sampleapp_session=P8jTL8...; path=/; HttpOnly [Changed Headers] - ETag: W/"f25d17d6ad73a7091771928fef7cc6f8" ---------------------------------------------------- ϛυϧΣΞ໊ ৽͍͠ϔομͷ໊લͱ ͕ॻ͖Θͬͨϔομͷ໊લͱ ݁Ռ ֦େ "DUJPO%JTQBUDI$PPLJFTΛ௨ͨ͠ޙɺ ৽͘͠Ճ͞ΕͨϔομΛλʔϛφϧʹදࣔ͢Δ
৽͘͠Ճ͞Εͨϔομ4FU$PPLJF ᶃ@
[email protected]
1K5-IUCIPHFIPHFGVHBHVGB ᶄQBUI ᶅ)UUQ0OMZ ͕มߋ͞Εͨϔομ&5BH ᶆ8GEEBEBGFGDDG "DUJPO%JTQBUDI$PPLJFT͕ϔομʹ༩࣮͑ͨࡍͷ͔Β ৭ʑͳൃݟ͕͋Γ·ͨ͠ ݁Ռ͔ΒಘΒΕͨͷ ᶃʮ@ΞϓϦ໊@TFTTJPOϥϯμϜͳӳࣈʯ
ᶄσϑΥϧτͰQBUIଐੑ͕ϧʔτʹઃఆ͞ΕΔ ᶅσϑΥϧτͰ)UUQ0OMZʹͳΔ ᶆ&5BHͲͷϛυϧΣΞΛ௨ͯ͠ॻ͖ΘΔ
'VLVPLBSC͔Βͷ͓ͨΑΓհ CZ!VE[VSB͞Μ ൃදࢿྉͷϨϏϡʔΛ͓ئ͍ͨ͠'VLVPLBSC͔Β ײΛ͖·ͨ͠ɻ
5SBDF)FBEFSͷ༗ޮੑ
5SBDF)FBEFSͷ༗ޮੑ ͋Γͦ͏ 13͍ͭͰ͓͓ͪͯ͠Γ·͢ IUUQTHJUIVCDPNTIJPJNN
[email protected]
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ ɹ4QFDJBM5IBOLT✨ !UEUET͞Μ !LBLVUBOJ͞Μ !KPLFS͞Μɹ !ZPVDIBO͞Μ !PLVSBNBTBGVNJ͞Μ
!VE[VSB͞Μ !KJNMPDL͞Μ"TBLVTBSC⚡'VLVPLBSC ը૾ग़యIUUQTUXJUUFSDPN