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

Rackミドルウェア入門のためのRackミドルウェア

 Rackミドルウェア入門のためのRackミドルウェア

More Decks by Misaki Shioi(塩井美咲/しおい)

Other Decks in Programming

Transcript

  1. class Application < Rails::Application config.middleware.insert_before ActionDispatch::Cookies, TraceHeader end ɹ[Target Middleware]

    ɹ ActionDispatch::Cookies ɹ[New Headers] ɹ - ʁʁʁʁ ௐ΂͍ͨϛυϧ΢ΣΞʹରͯ͠ 5SBDF)FBEFSϛυϧ΢ΣΞΛJOTFSU@CFGPSF͢Δ ࢖͍ํ 3BJMTͷ৔߹ λʔϛφϧʹࠩ෼͕දࣔ͞ΕΔ DPOpHBQQMJDBUJPOSC
  2. લఏ 3BDLΞϓϦέʔγϣϯͱ3BDLϛυϧ΢ΣΞ͸ɺ ڞ௨ͷن֨ʹԊ࣮ͬͯ૷͞Ε͍ͯΔ ࣮ߦ؀ڥ FOW ΛҾ਺ʹऔΔΠϯελϯεϝιουDBMMΛ࣮૷͢Δ  3BDLΞϓϦέʔγϣϯͷ৔߹  DBMMϝιου͸

    <εςʔλείʔυ \ϔομ^ <ϘσΟ>> ͷ഑ྻΛฦ͢  3BDLϛυϧ΢ΣΞͷ৔߹  ᶃΠϯελϯεม਺!BQQʹ ࣗ෼ͷ಺ଆͷΫϥεͷΠϯελϯεΛ࣋ͭ ᶄDBMMϝιουͷதͰ !BQQʹରͯ͠DBMMϝιουΛݺͿ ࣍ϖʔδͰ ΋͏গ͠ৄ͘͠ )551Ϩεϙϯε " # $
  3. 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ʹࣗ෼ͷ಺ଆͷΫϥεͷΠϯελϯεΛ࣋ͭ " # $
  4. 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
  5. 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
  6. 3BDLϛυϧ΢ΣΞͷ಺෦ߏ଄͔ΒΘ͔Δ͜ͱ ը૾ग़యɿIUUQTSBDLHJUIVCJP $ΠϯελϯεDBMM FOW  ‎<εςʔλείʔυ \ϔομ^ <ϘσΟ>> #ΠϯελϯεDBMM FOW

     ‎<εςʔλείʔυ \ϔομ^ <ϘσΟ>> "ΠϯελϯεDBMM FOW  ‎<εςʔλείʔυ \ϔομ^ <ϘσΟ>> 3BDLΞϓϦέʔγϣϯ 3BDLϛυϧ΢ΣΞ͸ڞ௨ͷن֨ʹԊ࣮ͬͯ૷͞Ε͍ͯΔ ‎Ͳͷϛυϧ΢ΣΞʹରͯ͠DBMMΛݺΜͰ΋ ࠷Լ૚ͷ3BDLΞϓϦέʔγϣϯ·ͰDBMM͞ΕΔ ‎࠷ऴతʹಉ͡ߏ଄ͷ഑ྻ͕ฦΔ " # $
  7. ͔͜͜ΒཱͯͨԾઆ ը૾ग़యɿIUUQTSBDLHJUIVCJP ର৅ͷϛυϧ΢ΣΞͱͦͷ௚લʹݺ͹Εͨϛυϧ΢ΣΞͷ DBMMϝιουΛݺͼɺฦΓ஋ಉ࢜Λൺֱ͢Ε͹ྑ͍ͷͰ͸ʁ $ΠϯελϯεDBMM FOW ‎ $࣌఺ͷฦΓ஋ #ΠϯελϯεDBMM FOW

    ‎ #࣌఺ͷฦΓ஋ ᶃ#࣌఺ͱ$࣌఺ͷϛυϧ΢ΣΞ ɹͦΕͧΕͷΠϯελϯεʹͦΕͧΕDBMMΛݺͿ ᶄͦΕͧΕͷฦΓ஋Λऔಘ͢Δ ᶅฦΓ஋ಉ࢜ͷࠩ෼Λλʔϛφϧʹग़ྗ͢Δ 3BDLΞϓϦέʔγϣϯ ࣮૷ํ਑λʔήοτ͕#ͷ৔߹ʜ#͕ݺ͹ΕΔ௚લʹ$͕ݺ͹ΕΔ " $ #
  8. DMBTT5SBDF)FBEFS ‏5SBDF1PJOUΛ࢖༻  ɾࣗ෼ΑΓલʹ࣮ߦ͞Ε͍ͯΔશͯͷϛυϧ΢ΣΞͷ৘ใΛऩू ɾࣗ෼ͷޙʹ࣮ߦ͞ΕΔϛυϧ΢ΣΞ΁ λʔήοτͷϛυϧ΢ΣΞͷฦΓ஋Λ౉͢ ޙଓͷॲཧͷͨΊ ɹ DMBTT3FTVMU ɾλʔήοτͱɺͦͷ௚લʹ࣮ߦ͞Εͨϛυϧ΢ΣΞͷ

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

    !BQQDBMM FOW ͷฦΓ஋Λޙଓͷϛυϧ΢ΣΞʹ౉͢ 5SBDF)FBEFSΠϯελϯεDBMM FOW ͕ݺ͹ΕΔͱ ௐ΂͍ͨϛυϧ΢ΣΞͷΠϯελϯεDBMM FOW  ɹ‎ͦΕͧΕͷฦΓ஋Λൺֱ͠ɺࠩ෼Λऔಘ PVUQVUϝιουͰࠩ෼Λλʔϛφϧʹදࣔ
  10. ࣮૷ 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 # ...লུ...
  11. ࣮૷ 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 ͷฦΓ஋Λ֨ೲ͢Δม਺
  12. ࣮૷ 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ͷΠϯελϯεΛฦ͢ϝιου
  13. ࣮૷ 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ΛΠϯελϯεԽ ϝιουݺͼग़͠ͱϦλʔϯ࣌ʹ ϒϩοΫ಺ͷॲཧΛ࣮ߦ͢Δ
  14. 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Ϧλʔϯ Ͱ͋Δ৔߹
  15. 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ϝιουͷݺͼग़͠ Ͱ͋Δ৔߹
  16. 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ʹอଘ
  17. 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 ˞ॏཁ
  18. ࣮૷ 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ϛυϧ΢ΣΞ λʔήοτͷϛυϧ΢ΣΞ λʔήοτͷ௚લͷϛυϧ΢ΣΞ Ͱಉ͡ΦϒδΣΫτΛࢦ͢
  19. ࣮૷ 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ϝιουʹΑͬͯ ஋͕มߋ͞ΕΔՄೳੑ͕͋Δ
  20. ࣮૷ 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ϝιουΛݺͿͱʜ ਖ਼͍͠ฦΓ஋Λฦ͞ͳ͍ ޙଓͷॲཧʹӨڹ͕ग़ΔͳͲ͕ى͜Γ͏Δ ‎յΕΔ
  21. ࣮૷ 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ϛυϧ΢ΣΞ಺Ͱ ࢖༻͞Ε͍ͯΔΦϒδΣΫτͱ͸ ແؔ܎ͷΦϒδΣΫτͱͯ͠஋Λऔಘ
  22. ࣮૷ 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ʹ୅ೖ
  23. ࣮૷ 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ͷ࣮ߦ݁ՌΛ֨ೲͨ͠഑ྻ
  24. ࣮૷ 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
  25. ࣮૷ 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‎λʔήοτͷ௚લʹݺ͹Εͨ ϛυϧ΢ΣΞͷ৘ใ
  26. ࣮૷ 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ϛυϧ΢ΣΞ࣮ߦ࣌ͷ؀ڥ^
  27. ࣮૷ 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 ᶄ௚લʹݺ͹Εͨϛυϧ΢ΣΞͷ৘ใ # ...লུ...
  28. ࣮૷ 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 # ...লུ... ฦΓ஋͸ͦΕͧΕ <εςʔλείʔυ \ϔομ^ <ϘσΟ>> ‎ϔομΛऔಘ͢ΔͨΊʹ ‎ΠϯσοΫε<>Λࢦఆ
  29. ࣮૷ 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 ϛυϧ΢ΣΞΛ௨ͨ͠લޙͰڞ௨ͷϔομ໊Λநग़ ৽͘͠௥Ճ͞Εͨϔομ໊Λநग़ ஋͕ॻ͖׵Θͬͨϔομ໊Λநग़ ϔομ໊͔Βϔομͷ஋Λऔಘ # ...লུ...
  30. ࣮૷ 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ϝιουͰλʔϛφϧʹදࣔ
  31. 5SBDF)FBEFSΠϯελϯεͷ!BQQDBMM FOW Λ࣮ߦ PVUQVUϝιουͰࠩ෼Λλʔϛφϧʹදࣔ 5SBDF1PJOUΛ࣮ߦ ɹ‎ࣗ෼ΑΓલͷશͯͷϛυϧ΢ΣΞͷ৘ใΛऩू NPEVMF%FTDSJCBCMF DMBTT3FTVMU DMBTT5SBDF)FBEFS DMBTT5SBDF)FBEFS

    5SBDF)FBEFSͷॲཧͷྲྀΕͷ͓͞Β͍ !BQQDBMM FOW ͷฦΓ஋Λޙଓͷϛυϧ΢ΣΞʹ౉͢ 5SBDF)FBEFSΠϯελϯεDBMM FOW ͕ݺ͹ΕΔͱ ௐ΂͍ͨϛυϧ΢ΣΞͷΠϯελϯεDBMM FOW  ɹ‎ͦΕͧΕͷฦΓ஋Λൺֱ͠ɺࠩ෼Λऔಘ
  32. "DUJPO%JTQBUDI$PPLJFTΛ௨ͨ͠ޙɺ ৽͘͠௥Ճ͞ΕͨϔομΛλʔϛφϧʹදࣔ͢Δ class Application < Rails::Application config.middleware.insert_before ActionDispatch::Cookies, TraceHeader end

    ݕূ DPOpHBQQMJDBUJPOSC ݕূ؀ڥ3VCZ  3BJMT ɹ4DB⒎PME͚ͨͩ͠ͷ؆୯ͳΞϓϦέʔγϣϯ ݕূํ๏αʔόʔΛ্ཱͪ͛ͯద౰ͳϖʔδʹΞΫηε
  33. ---------------------------------------------------- TraceHeader printing... [Target Middleware] ActionDispatch::Cookies [New Headers] - Set-Cookie:

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