そろそろPerlでのHTTP/2について触れたい

 そろそろPerlでのHTTP/2について触れたい

YAPC::Okinawa 2018 ONNASON
Mar 03, 2018

2d524d56b2ddff49363c995f2d795da0?s=128

Yuji Shimada

March 03, 2018
Tweet

Transcript

  1. ͦΖͦΖPerlͰͷ HTTP/2ʹ͍ͭͯ ৮Ε͍ͨ Yuji Shimada @xaicron YAPC::Okinawa 2018 ONNASON Mar

    03, 2018
  2. ͸͍

  3. Έͳ͞Μԭೄ ͨͷ͠ΜͰ·͔͢ʂʁ

  4. ΦϦΦϯ࠷ߴͰ͢Ͷʂʂ

  5. ࣗ෼͸ւͿͲ͏͕େ޷͖Ͱ͢

  6. None
  7. ே͔ΒւͿͲ͏৯΂ΒΕͯ ࠷ߴͰ͢Ͷ

  8. ͯ͞

  9. ͖ͬ͞ @kazuho ͞Μͷ τʔΫฉ͍ͨਓʙʁ

  10. ్த·Ͱ৸ͯͯେৎ෉Ͱ͢

  11. HTTP/2ʹ͍ͭͯΘ͔Βͳ͍͜ ͱ͕͋Δਓ͸ @kazuho ͞Μ ʹฉ͜͏ʂʂ

  12. Perlʹ͍ͭͯΘ͔Βͳ͍͜ͱ ͕͋Δਓ͸࠙਌ձͰ༗ࣝऀʹ ฉ͜͏ʂʂ

  13. ͯ͞

  14. HTTP/1.1ͱHTTP/2Ͳ͕ͬͪ ଎͍ͱࢥ͍·͔͢ʁ

  15. H1ͱH2Ͳ͕ͬͪ͸΍͍ʁ • H1͕͸΍͍ • H2͕͸΍͍ • ৔߹ʹΑΔ • Θ͔Βͳ͍

  16. H1ͱH2Ͳ͕ͬͪ͸΍͍ʁ • H1͕͸΍͍ • H2͕͸΍͍ • ৔߹ʹΑΔ • Θ͔Βͳ͍

  17. ͸͍

  18. ΞδΣϯμ • HTTP/2ʹ͍ͭͯ • PerlͰHTTP/2Λѻ͓͏ • ͓·͚: gRPCͱPerl • ·ͱΊ

  19. HTTP/2ʹ͍ͭͯ

  20. HTTP/2஀ੜ·ͰͷܦҢ

  21. ͸͡ΊʹSPDY͕͋ͬͨ

  22. ͸͡ΊʹSPDY͕͋ͬͨ • 2009೥11݄ʹGoogle͕SPDYͷυϥϑτ࢓༷ Λެ։ • 2010೥6݄ʹϦϦʔε͞ΕͨChrome 6͔Βσ ϑΥϧτͰ༗ޮʹͳͬͨ

  23. SPDYྑͦ͞͏ͩ͠ ඪ४Խ͠Α͏ʂʂ

  24. ͷͪͷHTTP/2Ͱ͋Δ

  25. ͷͪͷHTTP/2Ͱ͋Δ • ࠷ॳ͸HTTP/2.0ͱ͍͏໊લͩͬͨ • HTTP/2͕ਖ਼໊ࣜশʹ • 2015೥5݄ʹHTTP/2͕RFC 7540ͱͯ͠ެ։ • ಉ࣌ʹHPACK͕RFC

    7541ͱͯ͠ެ։
  26. ໿16೥ͿΓʹHTTP͕ Ξοϓσʔτ͞Εͨʂʂ (ͦΕ·Ͱʹ΋ͪΐͪ͘ΐ͘มߋ͸͚͋ͬͨͲ΋)

  27. SPDY͸Ͳ͏ͳͬͨʁ

  28. SPDY͸Ͳ͏ͳͬͨʁ • SPDY͸όʔδϣϯ3.1Ͱऴྃ • SPDY4͸࠷ऴతʹHTTP/2ͷυϥϑτ14ͷΤ ΠϦΞεʹͳͬͨ • 2016/5/15ʹChrome͸SPDYͷαϙʔτΛऴ ྃ

  29. SPDY͸HTTP/2ʹ ஔ͖׵Θͬͨʂ

  30. ͱ͜ΖͰ

  31. ͳͥHTTP/2(SPDY) ͕ඞཁʹͳͬͨʁ

  32. ͳͥHTTP/2͕ඞཁʹͳͬͨʁ • HTTP/1.1ͷެ։ʢ1999೥ʣ͔Β10೥ܦͬͯɺ Webίϯςϯπͷ༰ྔ͕ग़དྷతʹ૿Ճ • ੩తϖʔδ͚ͩͰͳ͘ಈతϖʔδ͕૿͖͑ͯ ͨ • 1ϖʔδදࣔ͢ΔͨΊʹ਺ेճҎ্ͷϦΫΤ ετ͕ൃߦ͞ΕΔ͜ͱ΋βϥʹ

  33. Web͕஗͘ͳ͖ͬͯͨʂʁ

  34. Web͕஗͍͍͔ͭ͘ͷཧ༝(1) • ωοτϫʔΫͷଳҬ͕ڱ͍ʢ·ͩ·ͩ3Gճઢ΋ଟ͍ʣ • ղܾࡦͷྫ • ૹ৴͢ΔσʔλΛѹॖͯ͠ݮΒ͢ • ΑΓૣ͍ճઢΛීٴͤ͞Δ •

    10GbpsͷݻఆճઢΛීٴͤ͞Δ • 5Gͷొ৔Ͱ௿஗Ԇ͔ͭ20Gbpsඈ͹ͤΔͧ • 120TbpsͷւఈέʔϒϧʹҾ͖௚͢ʢPLCNʣ
  35. Web͕஗͍͍͔ͭ͘ͷཧ༝(2) • TCPʹແବ͕ଟ͍ • ղܾࡦͷྫ • ᫔᫓΢Οϯυ΢αΠζͷॳظ஋Λେ͖͘͢Δ • Google͕৽͍͠᫔᫓੍ޚΞϧΰϦζϜBBRΛ։ൃ •

    ͨͱ͑͹TCPΛ΍ΊͯUDPϕʔεͷQUICʹ͢Δ
  36. Web͕஗͍͍͔ͭ͘ͷཧ༝(3) • HTTP/1.1ͷϓϩτίϧ্ͷ໰୊ʹىҼ • HTTP/2͸͜͜ʹΞϓϩʔνʂ

  37. HTTP/1.1ͷ໰୊఺

  38. HTTP/1.1ͷ໰୊఺ • 1ͭͷϦΫΤετ͕׬ྃ͢Δ·Ͱ࣍ͷϦΫΤετ Λૹ৴͢Δ͜ͱ͕Ͱ͖ͳ͍ • ଴͕ͪ࣌ؒແବ • ಉ͡HTTP HeaderΛԿ౓΋Կ౓΋ૹड৴͍ͯ͠Δ •

    ύέοτ͕ແବ
  39. 1ͭͷϦΫΤετ͕׬ྃ͢Δ ·Ͱ࣍ͷϦΫΤετΛૹ৴͢ Δ͜ͱ͕Ͱ͖ͳ͍ ↓ ϦΫΤετ͕௚ྻ

  40. ϦΫΤετ͕௚ྻ • HTTP/1.1Ͱ͸1ͭͷTCPίωΫγϣϯʹରͯ͠ɺ1 ϦΫΤετ͕ऴΘΔ·Ͱ଴ͨͳͯ͘͸͍͚ͳ͍ • ChromeͰ͸1ͭͷυϝΠϯʹରͯ͠࠷େ6ͭ· ͰTCPίωΫγϣϯΛషΔ͜ͱͰߴ଎ԽΛ࣮ݱ ʢ౰ࣾൺ6ഒʣ • ͨͩ͠ɺHTTP/1.1ͷ࢓༷Ͱ͸2ͭ·Ͱʹ੍ݶ

  41. ͦ͜Ͱ HTTPύΠϓϥΠϯ Ͱ͢Αʂ

  42. HTTPύΠϓϥΠϯͱ͸ • 1ͭͷTCP্ͰϨεϙϯεΛ଴ͭ͜ͱͳ͘ϦΫ ΤετΛૹ৴͢Δ͜ͱ͕Ͱ͖Δ࢓༷

  43. None
  44. HTTPύΠϓϥΠϯ • ႈ౳ͳϦΫΤετͰ͔͠ར༻Ͱ͖ͳ͍ • GET΍HEAD͕࿈ଓ͢ΔϦΫΤετͰ͸ར༻Մೳ • PUT΍DELETEͰ΋ར༻Ͱ͖Δ৔߹͕͋Δ • Ϩεϙϯε͸ϦΫΤετΛૹͬͨॱ൪Ͱड৴͠ͳ͚Ε͹ͳΒͳ͍ •

    Head of Line (HOL) Blocking ͸݁ہൃੜ͢Δ • ຆͲͷϒϥ΢βͰ࣮૷͞Ε͍ͯͳ͍͔σϑΥϧτͰແޮ • ΫϥΠΞϯτଆ͸ߟྀ͢Δ͜ͱ͕ଟ࣮͘૷͕೉͍͠
  45. ͦͷଞͷ༷ʑͳ࠷దԽ • Ϧιʔεͷ݁߹ • JavaScriptϑΝΠϧͷ݁߹΍ը૾ͷCSSεϓϥΠτʹΑΔϦΫΤετ ਺ͷ࡟ݮ • ը૾ͷΠϯϥΠϯԽ • base64ܗࣜͰը૾ΛHTMLʹຒΊࠐΉ͜ͱʹΑΔϦΫΤετ਺ͷ࡟ݮ

    • υϝΠϯγϟʔσΟϯά • ෳ਺ͷυϝΠϯΛར༻͢Δ͜ͱͰTCPͷಉ࣌઀ଓ਺Λ૿΍͢
  46. ಉ͡HTTP HeaderΛԿ౓΋Կ ౓΋ૹ৴͍ͯ͠Δ

  47. ͕Μ͹ͬͯෆཁͳϔομʔΛ ৬ਓ͕࡟Δ͔͠ແ͍ʂʂ

  48. HTTP/1.1Ͱ͸ ύϑΥʔϚϯεΛ্͛ΔͨΊ ʹϓϩτίϧҎ֎ͷͱ͜ΖͰ ͳΜͱ͔͠ͳ͚Ε͹͍͚ͳ͔ͬ ͨ

  49. HTTP/2Ͱ͸ϓϩτίϧΛ վྑ͢Δ͜ͱͰղܾ͠Α͏ͱ ͨ͠

  50. ͱ͍͏Θ͚Ͱ

  51. HTTP/2ͷಛ௃

  52. HTTP/2ͷಛ௃ • HTTP/1.1ͷηϚϯςΟΫεͱޓ׵ੑ͕͋Δ • ετϦʔϜ • όΠφϦϓϩτίϧ • HTTPϔομʔѹॖ •

    αʔόʔϓογϡ
  53. HTTP/1.1ͷηϚϯςΟΫεͱ ޓ׵ੑ͕͋Δ • εΩʔϚ͸”http://“ٴͼ”https://“Λͦͷ··ར༻ • ϙʔτ͸80ͱ443Λͦͷ··ར༻ • HTTPϔομʔ΋΄΅ͦͷ··ར༻ • શͯখจࣈʹͳͬͨΓར༻ෆՄͷΩʔ͕͋ͬ

    ͨΓ͸͢Δ
  54. ετϦʔϜ(1) • ༏ઌ౓෇͖શೋॏଟॏԽ௨৴ • ̍ͭͷTCPίωΫγϣϯ্Ͱෳ਺ͷετϦʔϜΛฒྻ ʹѻ͏͜ͱ͕Ͱ͖Δ • SETTINGS_MAX_CONCURRENT_STREAMSͰ࠷ େ஋Λઃఆ •

    ͦΕͧΕͷετϦʔϜ͸ಠཱ͍ͯͯ͠ϒϩοΫ͠ͳ͍
  55. ετϦʔϜ(2) • ΫϥΠΞϯτɺαʔόʔͲͪΒ͔ΒͰ΋։࢝͢Δ͜ͱ͕Ͱ ͖Δ • ετϦʔϜIDͰ֤ετϦʔϜΛ؅ཧ͢Δ • ΫϥΠΞϯτ͸ح਺ɺαʔόʔ͸ۮ਺͔Β࢝ΊΔ͜ͱͰ ڝ߹Λճආ •

    ૹड৴͢Δσʔλ͸όΠφϦܗࣜ • ૹड৴͢Δσʔλ͸ϑϨʔϜͱ͍͏୯ҐͰૹड৴͢Δ
  56. όΠφϦϓϩτίϧ • HTTP/2͸ϦΫΤετ/ϨεϙϯεʹϑϨʔϜͱ ͍͏όΠφϦϑΥʔϚοτͰσʔλͷ΍Γऔ ΓΛߦ͏ • ͍··ͰςΩετϓϩτίϧͰύʔε΍ղऍ͕ ͕ᐆດͩͬͨͱ͜Ζ͕ݫ֨ʹͳͬͨ

  57. ϑϨʔϜͷϑΥʔϚοτ # 9ΦΫςοτͷϔομʔͱՄม௕ͷϖΠϩʔυ͔Β੒Δ # ͔ͬ͜ͷதͷ਺ࣈ͸1Ϗοτ +-----------------------------------------------+ | Length (24) |

    +---------------+---------------+---------------+ | Type (8) | Flags (8) | +-+-+-----------+---------------+-------------------------------+ |R| Stream Identifier (31) | +=+=============================================================+ | Frame Payload (0...) ... +———————————————————————————————+
  58. ϑϨʔϜͷछྨ 5ZQF छྨ ໾ׂ  %"5" ϦΫΤετϨεϙϯεͷϘσΟʔ  )&"%&34 ϦΫΤετϨεϙϯεͷϔομʔ

     13*03*5: ετϦʔϜͷ༏ઌॱҐΛࢦఆʢΫϥΠΞϯτͷΈʣ  345@453&". ΤϥʔͳͲͰετϦʔϜΛऴྃ͢Δͱ͖ʹ࢖༻  4&55*/(4 ઀ଓઃఆΛมߋ͢Δ  164)@130.*4& αʔόʔϓογϡΛ༧ࠂ͢ΔʢαʔόʔͷΈʣ  1*/( ઀ଓͷੜଘ֬ೝ  (0"8": ΤϥʔͳͲͰ઀ଓΛऴྃ͢Δͱ͖ʹ࢖༻  8*/%08@61%"5& ΢Οϯυ΢αΠζΛมߋ͢Δ  $0/5*/6"5*0/ αΠζͷେ͖ͳ)&"%&34164)@130.*4&ͷஅย
  59. HTTPϔομʔѹॖ • “HPACK”ͱ͍͏ܗࣜͰϔομΛѹॖ͢Δ • SPDYͰ͸gzipΛ༻͍͍͕ͯͨʮCRIMEʯͱ͍ ͏߈ܸํ๏͕ݟ͔ͭͬͨͨΊผͷํ๏Ͱ࢓༷ ࡦఆ

  60. HPACKͷಛ௃ • όΠφϦܗࣜ • ΩʔΛখจࣈʹ౷Ұ • Α͘࢖ΘΕΔϔομʔͷΩʔͱ஋Λ૊Έʹͨࣙ͠ॻΛ࣋ͭ • ಈతʹࣙॻΛߋ৽͠ɺ2ճ໨Ҏ߱͸ΠϯσοΫεΛ༻͍Δ •

    Ωʔ΍஋ͷจࣈྻΛϋϑϚϯූ߸Ͱѹॖ͢Δ͜ͱ΋Ͱ͖Δ
  61. αʔόʔϓογϡ • HTTP/2Ͱ͸ΫϥΠΞϯτ͔ΒͷϦΫΤετ͕ͳ ͯ͘΋αʔόʔ͔ΒσʔλΛૹ৴͢Δ͜ͱ͕Ͱ ͖Δ • HTMLʹؔ࿈෇͚ΒΕ͍ͯΔCSS΍JavaScriptɺ ը૾ͳͲΛΫϥΠΞϯτͷϦΫΤετΛ଴ͨͣ ʹૹΓ͚ͭΒΕΔͷͰɺϖʔδදࣔ·Ͱͷ࣌ؒ ୹ॖ͕ݟࠐΊΔ

  62. αʔόʔϓογϡͷྲྀΕ • ΫϥΠΞϯτ͕ετϦʔϜ1Ͱindex.htmlΛཁٻ • αʔόʔ͸index.htmlʹ͸style.css͕ؔ࿈͍͍ͮͯΔ͜ͱΛ஌͍ͬͯ ΔͷͰstyle.cssΛετϦʔϜ2Ͱϓογϡ͢ΔʢPUSH_PROMISEʣ • ετϦʔϜ1Ͱindex.htmlΛड͚औͬͨΫϥΠΞϯτ͸ϦΫΤετΛ ߦ͏͜ͱͳ͘style.cssͷ౸ணΛ଴ͭ •

    αʔόʔ͔ΒετϦʔϜ2ʹΑͬͯstyle.css͕ಧ͖ɺϨϯμϦϯάΛ ։࢝͢Δ
  63. αʔόʔϓογϡͷ஫ҙ఺ • HTTP/2Λಋೖ͚ͨͩ͠Ͱࣗಈతʹ͜ͷΑ͏ͳڍಈʹͳΔΘ͚Ͱ ͸ͳ͍ • ΞϓϦέʔγϣϯଆͰઃఆ΍ϩδοΫΛ࣮૷͢Δඞཁ͕͋Δ • ϓογϡ͢Δίϯςϯπ͕ΫϥΠΞϯτͰΩϟογϡ͞Ε͍ͯ Δ͔Ͳ͏͔Θ͔Βͳ͍ͷͰແବͳϦΫΤετ͕ൃੜ͢ΔՄೳੑ ͕͋Δ

    • 103 Early HintsͳͲΛར༻͢Δ͜ͱͰΑΓޮ཰తʹͰ͖ΔՄ ೳੑ͕͋Δ
  64. HTTP/2Ͱ઀ଓΛߦ͏ํ๏

  65. HTTP/2Ͱ઀ଓΛߦ͏ํ๏ (http઀ଓͷ৔߹) • HTTP/1.1ͱޓ׵ੑ͕͋ΔͨΊɺΫϥΠΞϯτ͸HTTP/ 2ͰΞΫηεͰ͖Δ͔Ͳ͏͔Λ൑ఆ͠ͳͯ͘͸͍͚ͳ͍ • URL΍ϙʔτ൪߸͚ͩͰ͸൑அ͕Ͱ͖ͳ͍ • ΫϥΠΞϯτ͸HTTP/1.1ͰಛఆͷHTTPϔομʔΛૹ ৴͢Δ͜ͱͰαʔόʔ͕HTTP/2ʹରԠ͍ͯ͠Δ͔Ͳ͏

    ͔൑அ͢Δ
  66. HTTP/2Ͱ઀ଓΛߦ͏ํ๏ (http઀ଓͷ৔߹) • ϦΫΤετ࣌ʹ·ͣҎԼͷϔομʔΛ෇͚ͯ HTTP/1.1ϦΫΤετΛߦ͏ • Connection: Upgrade, HTTP2-Settings •

    Upgrade: h2c • HTTP2-Settings: <HTTP/2 SETTINGS ϖΠϩʔ υͷ base64url Τϯίʔυ>
  67. ॳճϦΫΤετͷྫ # http://www.example.com/ ʹϦΫΤετͨ͠৔߹ > GET / HTTP/1.1 > Host:

    www.example.com > Connection: Upgrade, HTTP2-Settings > Upgrade: h2c > HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
  68. ॳճϦΫΤετͷྫ # http://www.example.com/ ʹϦΫΤετͨ͠৔߹ > GET / HTTP/1.1 > Host:

    www.example.com > Connection: Upgrade, HTTP2-Settings > Upgrade: h2c > HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA < HTTP/1.1 101 Switching Protocols < Connection: Upgrade < Upgrade: h2c # ͔͜͜ΒHTTP/2઀ଓ < server: perl-Protocol-HTTP2/1.08 < content-length: 13 < cache-control: max-age=3600 < date: Thu, 01 Mar 2018 14:30:15 GMT < last-modified: Thu, 01 Mar 2018 14:30:15 GMT < hello, world!
  69. HTTP/2Ͱ઀ଓΛߦ͏ํ๏ (http઀ଓͷ৔߹) • 101 Switching Protocol͕ฦ͖ͬͯͨΒ੒ޭ • ্هͷ͋ͱʹϦΫΤετΛૹΒͣʹHTTP/2 Ϩεϙϯε͕ฦ͖͍ͬͯͯΔͱ͜Ζ͕ϛι •

    ͍͍ͩͨWebSocketͱҰॹ
  70. HTTP/2Ͱ઀ଓΛߦ͏ํ๏ (https઀ଓͷ৔߹) • HTTP/2͸TLS1.2Ҏ্͕ඞਢ • application-layer protocol negotiation (ALPN) extension

    ͕ར ༻Ͱ͖Δඞཁ͕͋Δ • ҉߸εΠʔτ͸ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256Ҏ্͕ඞਢ • TLSϋϯυγΣΠΫ͕ऴΘͬͨޙʹʮHTTP/2ίωΫγϣϯϓϦ ϑΣΠεʯͱ͍͏24ΦΫςοτͷσʔλΛૹ৴͢Δ
  71. ίωΫγϣϯϓϦϑΣΠε • “PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n” Λૹ৴ • ͜Ε͸HTTP/1.1ͷαʔόʔͩͱ PRI ͱ͍͏

    METHOD ͱͯ͠ղऍ͞Εͯ౴͑ΒΕͳ͍ͷͰ HTTP/2ʹରԠ͍ͯ͠ͳ͍ͱ൑அͰ͖Δ • ௚ޙʹαʔόʔ͔Β SETTINGS ϑϨʔϜʢޙड़ʣ ͕ฦͬͯ͘Ε͹੒ޭ
  72. ͸͍

  73. ͜͜·Ͱ؆୯ʹͰ͕͢ HTTP/2ͷ֓ཁʹ͍ͭͯ৮Εͯ ͖·ͨ͠

  74. ·ͩ·ͩແݶʹ࿩୊͸͋Γ· ͢

  75. ͨͱ͑͹ • ετϦʔϜͷ༏ઌ౓ • ϑϩʔ੍ޚ • HTTP/2࣌୅ͷυϝΠϯγϟʔσΟϯά • Smart Shadingͷݕ౼

    • ίωΫγϣϯ࠶ར༻ͱϫΠϧυΧʔυূ໌ॻ • 421 Misdirected Requestͷར༻΍OriginϑϨʔϜͷݕ౼ • αʔόʔϓογϡͱϦόʔεϓϩΩγʔ • 103 Early Hintsͷར༻
  76. ࣮ࡍʹӡ༻͢ΔͱͳΔͱߟྀ ͢Δ͜ͱ͕͍ͬͺ͍

  77. ͕͍࣌ؒ͘Β͋ͬͯ΋ͨΓͳ ͍ͷͰࠓ೔͸Ұ୴͜͜·Ͱ

  78. ͜͜·Ͱͷ·ͱΊ • HTTP/1.1ͷϓϩτίϧΛվྑ͠ɺ͍͔ͭ͘ͷ େ͖ͳϘτϧωοΫΛղফ͢Δ͜ͱ͕Ͱ͖Δ Α͏ͳͬͨ • όΠφϦʹͳͬͨΓɺετϦʔϜ΍HPACKͳ Ͳ৽͍֓͠೦͕૿͑ͯͪΐͬͱෳࡶʹͳͬͨ

  79. PerlͰHTTP/2Λѻ͓͏

  80. PerlͰͷHTTP/2ͷରԠঢ়گ • http-perlͱProtocol::HTTP2 ͱ͍͏ϥΠϒϥ Ϧʔ͕͋Δ • http-perl͸h2-04ʢυϥϑτ4ʣͰ։ൃ͕ധ ·͍ͬͯΔ • Protocol::HTTP2

    Ұ୒
  81. https://github.com/http2/http2-spec/wiki/Implementations

  82. ΄΅શͯͷػೳ͕ ࣮૷͞Ε͍ͯΔʂʂ

  83. None
  84. Protocol::HTTP2ͷಛ௃ • TPCίωΫγϣϯͷ؅ཧ͸΍ͬͯ͘Εͳ͍ͷͰࣗ෼ Ͱ΍Δඞཁ͕͋Δ • ετϦʔϜͷ؅ཧΛ΍ͬͯ͘ΕΔ • ϑϨʔϜ΍HTTPϔομʔͷencode/decode΋΍ͬ ͯ͘ΕΔ •

    LWP΍Furl΄Ͳ؆୯Ͱ͸ͳ͍ʂ
  85. ͱ͍͏Θ͚Ͱ࣮ࡍʹ࢖ͬͯΈ ·͠ΐ͏

  86. Protocol::HTTP2Λ࢖ͬͯΈΔ • Protocol::HTTP2::ClientͰHTTP/2ͳαʔόʔʹΞΫηεͯ͠ΈΔ • Protocol::HTTP2::ServerͰαʔόʔΛͨͯΔ • ฒྻϦΫΤετΛࢼ͢ • αʔόʔϓογϡΛࢼ͢ •

    PSGIͰHTTP/2 • TLSͰૹड৴͢Δ
  87. Protocol::HTTP2::ClientͰ HTTP/2ͳαʔόʔʹΞΫηε ͯ͠ΈΔ

  88. ࠓճ͸ ͏·͘ಈ͔ͳ͔ͬͨͷͰ ࠷ॳ͔ΒHTTP/2ͩͱΘ͔ͬͯ ͍ΔͷͰUpgradeͷॲཧ͸ε Ωοϓ͠·͢

  89. HTTP/2 ClientΛࢼ͢ • ͱΓ͋͑ͣαʔόʔ͸ϩʔΧϧʹ nghttpd ͱ ͍͏΍ͭΛ —no_tls Ͱཱͯ·͢ •

    ΧϨϯτσΟϨΫτϦͷϑΝΠϧΛදࣔͯ͘͠ ΕΔͷͰద౰ʹ index.html ΛͰ্ͬͪ͛·͢ • Protocol::HTTP2::ClientͰΞΫηεͯ͠Έ·͢
  90. nghttpdΛىಈ͢Δ $ echo 'Hello, HTTP/2!!' >! index.html # index.html Λ࡞͓ͬͯ͘

    $ nghttpd —no-tls -v 8080 IPv6: listen :::8080 IPv4: listen 0.0.0.0:8080
  91. ClientΦϒδΣΫτͷ࡞੒ use Protocol::HTTP2::Client; use Protocol::HTTP2::Constant qw(constant_name); my $client = Protocol::HTTP2::Client->new(

    on_change_state => sub { my ($stream_id, $previous_state, $current_state) = @_; printf( "Stream %i changed state from %s to %s\n", $stream_id, const_name(states => $previous_state), const_name(states => $current_state), ); }, on_error => sub { my $error = shift; printf "Error occurred: %s\n", const_name(errors => $error); }, );
  92. ϦΫΤετͷ࡞੒ (͜ͷ࣌఺Ͱ͸·ͩϦΫΤετ͸ඈ͹ͳ͍) my $port = 80; my $host = ‘example.com';

    $client->request( # HTTP/2 headers ':scheme' => 'http', ':authority' => "$host:$port", ':path' => '/', ':method' => 'GET', # HTTP/1.1 headers headers => [ 'accept' => '*/*', 'user-agent' => "perl-Protocol-HTTP2/$Protocol::HTTP2::VERSION", ], on_done => sub { my ($headers, $data) = @_; use Data::Dumper; warn Dumper [ $headers, $data ]; }, );
  93. tcpίωΫγϣϯΛுΔ use AnyEvent; use AnyEvent::Socket; use AnyEvent::Handler; my $w =

    AnyEvent->condvar; tcp_connect $host, $port, sub { my ($fh) = @_ or die “connection failed: $!”; my $handle; $handle = AnyEvent::Handle->new( fh => $fh, autocork => 1, on_error => sub { $_[0]->destroy; warn "connection error\n” $w->send; }, on_eof => sub { $handle->destroy; $w->send; }, ); # ࣍ͷεϥΠυʹͭͮ͘ }; $w->recv;
  94. ϦΫΤετΛૹड৴͢Δ tcp_connect $host, $port, sub { … # ϦΫΤετΛૹ৴ while

    (my $frame = $client->next_frame) { $handle->push_write($frame); } # ϨεϙϯεΛॲཧ $handle->on_read(sub { my $handle = shift; $client->feed(delete $handle->{rbuf}); while (my $frame = $client->next_frame) { $handle->push_write($frame); } $handle->push_shutdown if $client->shutdown; }); }; $w->recv;
  95. ΰϦΰϦͷAnyEventʂʂ

  96. ࣮ߦͯ͠Έ·͢ $ perl no_tls_client.pl Stream 1 changed state from IDLE

    to HALF_CLOSED Stream 1 changed state from HALF_CLOSED to CLOSED [ [ ":status", "200", "server", "nghttpd nghttp2/1.30.0", "cache-control", "max-age=3600", "date", "Fri, 02 Mar 2018 11:03:24 GMT", "content-length", "16", "last-modified", "Fri, 02 Mar 2018 11:02:50 GMT" ], "Hello, HTTP/2!!\n" ]
  97. ͏·͍ͬͨͧ͘ʂʂʂ

  98. ϓϩάϥϜʹ౉ͬͯ͘Δϔο μʔ͸ͪΌΜͱಡΊΔײ͡Ͱ ͕͢ɺϦΫΤετத͸HPACK Ͱѹॖ͞Ε͍ͯ·͢

  99. ࣍͸ Protocol::HTTP2::ServerͰ αʔόʔΛཱͯͯΈ·͠ΐ͏

  100. αʔόʔͷ࣮૷ my $w = AnyEvent->condvar; tcp_server '127.0.0.1', 8080, sub {

    my ($fh, $peer_host, $peer_port) = @_; my $handle; $handle = AnyEvent::Handle->new( fh => $fh, autocork => 1, on_error => sub { my ($handle, $fatal, $message) = @_; $handle->destroy; say "connection error (fatal: $fatal, message: $message)"; }, on_eof => sub { $handle->destroy; }, ); # ࣍ͷεϥΠυ΁ }; $w->recv;
  101. αʔόʔͷ࣮૷ tcp_server '127.0.0.1', 8080, sub { … my $server; $server

    = Protocol::HTTP2::Server->new( on_request => sub { my ($stream_id, $headers, $data) = @_; my $message = "hello, world!"; $server->response( ':status' => 200, stream_id => $stream_id, headers => [ 'server' => 'perl-Protocol-HTTP2/1.08', 'content-length' => length($message), ], data => $message, ); }, ); # ࣍ͷεϥΠυʹଓ͘ }; $w->recv;
  102. αʔόʔͷ࣮૷ tcp_server '127.0.0.1', 8080, sub { … while (my $frame

    = $server->next_frame) { $handle->push_write($frame); } $handle->on_read(sub { my $handle = shift; $server->feed($handle->{rbuf}); $handle->{rbuf} = undef; while (my $frame = $server->next_frame) { $handle->push_write($frame); } $handle->push_shutdown if $server->shutdown; }); }; $w->recv;
  103. αʔόʔΛىಈͯ͠ ϦΫΤετૹͬͯΈΔ $ perl no_tls_server.pl $ perl no_tls_client.pl Stream 1

    changed state from IDLE to HALF_CLOSED Stream 1 changed state from HALF_CLOSED to CLOSED [ [ ":status", "200", "server", "perl-Protocol-HTTP2/1.08" ], "hello, world!" ]
  104. ΍ͬͨʔʂಈ͍ͨͧʂʂ

  105. ͯ͞

  106. HTTP/2Ͱ͸1ͭͷTCP্Ͱෳ ਺ͷετϦʔϜΛѻ͑ΔΜͰ ͨ͠

  107. ฒྻϦΫΤετΛࢼ͢ • ΫϥΠΞϯτଆͰ͸request()Λෳ਺ճൃߦ͢Δ͜ͱͰෳ਺ͷ ετϦʔϜΛੜ੒͠ɺฒྻͰϦΫΤετΛૹ৴͢Δ͜ͱ͕Մೳ ʹͳΔ • ࠓճ͸ετϦʔϜ1Ͱ”dummy.iso”ͱ͍͏ͦΕͳΓͷαΠζͷ ϑΝΠϧΛऔಘ͠ɺετϦʔϜ3ͷ΄͏͕ૣ͘Ϩεϙϯε͕ ฦͬͯ͘Δ͜ͱΛ֬ೝ͢Δ •

    ϦΫΤετͷετϦʔϜID͸ح਺ͳͷͰ1ͷ࣍͸3ʹͳΓ· ͢
  108. ฒྻϦΫΤετΛࢼ͢ ʢΫϥΠΞϯτଆൈਮʣ $client->request( # ετϦʔϜ1 # HTTP/2 headers ':scheme' =>

    'http', ':authority' => "$host:$port", ':path' => “/dummy.iso", # ڊେͳϑΝΠϧͷऔಘ ':method' => 'GET', … )->request( # ετϦʔϜ3 # HTTP/2 headers ':scheme' => 'http', ':authority' => "$host:$port", ':path' => "/", ':method' => 'GET', … );
  109. ฒྻϦΫΤετΛࢼ͢ ʢαʔόʔଆൈਮʣ on_request => sub { my ($stream_id, $headers, $data)

    = @_; my $header_map = { @$headers }; if ($header_map->{':path'} eq '/') { # path ͰॲཧΛৼΓ෼͚Δ # લͱҰॹ } elsif ($header_map->{':path'} eq '/dummy.iso') { aio_load './dummy.iso', sub { # ಡΈࠐΈͰϒϩοΫ͠ͳ͍Α͏ʹ aio_load Λ࢖༻ my ($data) = @_; $server->response( ':status' => 200, stream_id => $stream_id, headers => [ 'server' => 'perl-Protocol-HTTP2/1.08', 'content-length' => length($data), ], data => $data, ); }; } },
  110. ࣮ࡍʹࢼͯ͠ΈΔ $ perl no_tls_server_multistream.pl $ perl no_tls_client_multistream.pl Stream 1 changed

    state from IDLE to HALF_CLOSED Stream 3 changed state from IDLE to HALF_CLOSED Stream 3 changed state from HALF_CLOSED to CLOSED [ [ ":status", "200", "server", "perl-Protocol-HTTP2/1.08", "content-length", "13" ] ] Stream 1 changed state from HALF_CLOSED to CLOSED [ [ ":status", "200", "server", "perl-Protocol-HTTP2/1.08", "content-length", "102400" ] ]
  111. ؆୯Ͱ͢Ͷʢʁʣ

  112. αʔόʔ࣮૷ͷ஫ҙ఺ • αʔόʔʹؔͯ͠͸ී௨ʹHeaderΛνΣοΫͯͦ͠ΕͧΕͷॲཧΛॻ͍ ͍ͯ͘͜ͱͰWebΞϓϦέʔγϣϯΛ͍··Ͱ௨Γʹ࣮૷ग़དྷ·͢Ͷ • ͨͩ͠ɺશͯͷϦΫΤετͰϒϩοΩϯά͠ͳ͍Α͏ʹࡉ৺ͷ஫ҙΛ෷ ͏ඞཁ͕͋Δ • DB΍memcachedɺredisͳͲͷΞΫηε΍ϩάϑΝΠϧ΁ͷॻ͖ࠐ ΈͳͲ͢΂ͯAnyEvent΍CoroͳͲΛར༻ͯ͠ϒϩοΩϯά͠ͳ͍Α

    ͏ʹ͢Δ • ϛεΔͱશͯͷϦΫΤετ͕٧·Γ·͢
  113. ͸͍

  114. ੈͷதͷϒϥ΢β͸h2Ͱ͔͠ جຊతʹΞΫηεͯ͜͠ͳ͍ ΜͰͨ͠

  115. ͳͷͰTLSʹରԠ͢Δඞཁ͕ ͋Γ·͢

  116. TLSʹରԠ • ࠓճ͸Let’s EncryptͰ࡞੒ͨ͠ূ໌ॻΛར༻ • ݸਓͰ͍࣋ͬͯΔυϝΠϯΛར༻͠ɺΠϯλʔωοτʹ ެ։ʂ • αʔόʔɺΫϥΠΞϯτͱ΋ʹίωΫγϣϯΛTLSʹରԠ ͤ͞Δ

    • ͲͪΒ΋AnyEvent::HandlerΛ࢖͍ͬͯΔͱ͜ΖΛվम
  117. TLSʹରԠ ʢαʔόʔฤʣ Net::SSLeay::initialize(); tcp_server ‘127.0.0.1’, 443, sub { my ($fh,

    $peer_host, $peer_port) = @_; my $tls; eval { $tls = AnyEvent::TLS->new( method => 'TLSv1_2', cert_file => ‘/etc/letsencrypt/live/http2-test.api.moe/fullchain.pem’, key_file => ‘/etc/letsencrypt/live/http2-test.api.moe/privkey.pem’, ); # ͜͜Ͱ҉߸εΠʔτΛબ୒͢Δ # ࣍ͷεϥΠυ΁ }; if ($@) { print "Some problem with SSL CTX: $@\n"; $w->send; return; } …
  118. TLSʹରԠ ʢαʔόʔฤʣ … eval { … # ECDH curve (

    Net-SSLeay >= 1.56, openssl >= 1.0.0 ) if (exists &Net::SSLeay::CTX_set_tmp_ecdh) { my $curve = Net::SSLeay::OBJ_txt2nid('prime256v1'); my $ecdh = Net::SSLeay::EC_KEY_new_by_curve_name($curve); Net::SSLeay::CTX_set_tmp_ecdh( $tls->ctx, $ecdh ); Net::SSLeay::EC_KEY_free($ecdh); } # ALPN (Net-SSLeay > 1.55, openssl >= 1.0.2) if (exists &Net::SSLeay::CTX_set_alpn_select_cb) { Net::SSLeay::CTX_set_alpn_select_cb( $tls->ctx, [Protocol::HTTP2::ident_tls] ); } # NPN (Net-SSLeay > 1.45, openssl >= 1.0.1) elsif (exists &Net::SSLeay::CTX_set_next_protos_advertised_cb) { Net::SSLeay::CTX_set_next_protos_advertised_cb( $tls->ctx, [Protocol::HTTP2::ident_tls] ); } }; # ࣍ͷεϥΠυ΁
  119. TLSʹରԠ ʢαʔόʔฤʣ my $handle; $handle = AnyEvent::Handle->new( fh => $fh,

    tls => 'accept', tls_ctx => $tls, autocork => 1, on_error => sub { my ($handle, $fatal, $message) = @_; $handle->destroy; warn "connection error (fatal: $fatal, message: $message)"; }, on_eof => sub { $handle->destroy; }, );
  120. ΊͪΌͪ͘Ό ढจͩΒ͚Ͱ͢Ͷʂʂ

  121. Ұ୴͜ΕͰىಈͯ͠Έͯcurl ͰΞΫηεͯ͠Έ·͠ΐ͏

  122. TLSʹରԠ͔ͨ֬͠ೝ $ curl -v —http2 https://http2-test.api.moe/ தུ… * Using HTTP2,

    server supports multi-use * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x7ff59c00cc00) > GET / HTTP/2 > Host: http2-test.api.moe > User-Agent: curl/7.54.0 > Accept: */* > * Connection state changed (MAX_CONCURRENT_STREAMS updated)! < HTTP/2 200 < server: perl-Protocol-HTTP2/1.08 < content-length: 21 < cache-control: max-age=3600 < date: Fri, 02 Mar 2018 14:58:59 GMT < last-modified: Fri, 02 Mar 2018 14:58:59 GMT < * Connection #0 to host http2-test.api.moe left intact Hello, HTTP/2 World!!
  123. ͍͚ͨͬΆ͍Ͱ͢Ͷʂ

  124. ͭ͗͸ΫϥΠΞϯτଆ΋ରԠ ͠·͠ΐ͏

  125. TLSʹରԠ ʢΫϥΠΞϯτฤʣ Net::SSLeay::initialize(); tcp_connect $host, $port, sub { my ($fh)

    = @_ or die "connection failed: $!"; my $tls; eval { $tls = AnyEvent::TLS->new(method => ‘TLSv1_2’); # ALPN (Net-SSLeay > 1.55, openssl >= 1.0.2) if (exists &Net::SSLeay::CTX_set_alpn_protos) { Net::SSLeay::CTX_set_alpn_protos( $tls->ctx, [Protocol::HTTP2::ident_tls] ); } # NPN (Net-SSLeay > 1.45, openssl >= 1.0.1) elsif (exists &Net::SSLeay::CTX_set_next_proto_select_cb) { Net::SSLeay::CTX_set_next_proto_select_cb( $tls->ctx, [Protocol::HTTP2::ident_tls] ); } else { die "ALPN and NPN is not supported\n"; } }; # ࣍ͷεϥΠυ΁
  126. TLSʹରԠ ʢΫϥΠΞϯτฤʣ … my $handle; $handle = AnyEvent::Handle->new( fh =>

    $fh, tls => "connect", tls_ctx => $tls, autocork => 1, on_error => sub { $_[0]->destroy; print "connection error\n"; $w->send; }, on_eof => sub { $handle->destroy; $w->send; } ); …
  127. ΫϥΠΞϯτଆ΋΄΅αʔόʔ ͱҰॹͰ͢Ͷ

  128. ͜ΕͰΞΫηεͯ͠Έ·͢

  129. TLSʹରԠ͔ͨ֬͠ೝ $ perl tls_client.pl [/Users/shimada.yuji/misc/yapc-okinawa] Stream 1 changed state from

    IDLE to HALF_CLOSED Stream 1 changed state from HALF_CLOSED to CLOSED [ [ ":status", "200", "server", "perl-Protocol-HTTP2/1.08", "content-length", "21", "cache-control", "max-age=3600", "date", "Fri, 02 Mar 2018 15:24:03 GMT", "last-modified", "Fri, 02 Mar 2018 15:24:03 GMT" ], "Hello, HTTP/2 World!!" ]
  130. ͪΌΜͱΞΫηεͰ͖·ͨ͠ Ͷʂʂ

  131. ͜ΕͰଞͷαΠτ΋ී௨ʹ HTTP/2ͰΞΫηεͰ͖ΔΑ͏ ʹͳΓ·ͨ͠

  132. HTTP/2͔͠ରԠ͍ͯ͠ͳ͍α Πτ΋εΫϨΠϐϯά͠์୊ Ͱ͢Ͷʁ

  133. None
  134. ͜͜Ͱࣗ෼ͷ࡞ͬͨ Ϟδϡʔϧͷ঺հ

  135. Net::APNs::HTTP2

  136. Net::APNs::HTTP2 • Appleͷϓογϡ௨஌Λαʔόʔ͔ΒૹΕΔ΍ ͭ • ฒྻϦΫΤετΛ؆୯ʹߦ͏͜ͱ͕Ͱ͖Δ • ಺෦Ͱ͸Protocol::HTTP2::Clientͱ AnyEvent::TLSΛར༻

  137. ͜Μͳײ͡Ͱ࢖͑Δ(1) my $apns = Net::APNs::HTTP2->new( is_development => 1, auth_key =>

    'auth_key.p8', key_id => $key_id, team_id => $team_id, bundle_id => $bundle_id, );
  138. ͜Μͳײ͡Ͱ࢖͑Δ(2) while (1) { # ͜Ε͸ͳʹ͔͠Βͷαʔόʔͱ͔ϫʔΧʔͰӬଓతʹಈ࡞͍ͯ͠Δͱࢥ͍ͬͯͩ͘͞ $apns->prepare($device_token, { aps =>

    { alert => 'some message', badge => 1, }, }, sub { my ($header, $content) = @_; # $header = [ # ":status" => "200", # "apns-id" => "82B34E17-370A-DBF4-5046-FF56A4EA1FAF", # ]; ... }); # You can chainged $apns->prepare(...)->prepare(...)->prepare(...); # send all prepared requests in parallel $apns->send; # do something } # must call `close` when finished $apns->close;
  139. Net::APNs::HTTP2 • version 0.01͚ͩͲී௨ʹϓϩμΫγϣϯͰಈ ͍ͯ·͢ • ຖ೔਺ඦ݅Ҏ্ͷϓογϡ௨஌Λݩؾʹૹ৴த • ͥͻ࢖ͬͯΈ͍ͯͩ͘͞ʂʂ •

    ϑΟʔυόοΫ΋͓Ͷ͕͍͠·͢ʂʂ
  140. ؓ࿩ٳ୊

  141. ͦΖͦΖαʔόʔϓογϡΛ ࣮૷ͯ͠Έ·͠ΐ͏

  142. αʔόʔϓογϡΛ࣮૷͢Δ • “/push.html”ʹϦΫΤετΛߦ͏ͱ”/style.css”͕αʔ όʔϓογϡ͞ΕΔΑ͏ʹ͢Δ • มߋ͢Δ৔ॴ͸ on_request() ͷதͷΈ • push()

    ͸ response() ΑΓ΋ઌʹهड़͠ͳ͚Ε͹ͳΒͳ͍ • ChromeͰΞΫηε͠style.cssͷinitiatorʹ”Push”ͱग़ͯ ͍ͨΒ੒ޭ
  143. αʔόʔϓογϡͷ࣮૷ if ($header_map->{':path'} eq '/push.html') { $server->push( ':authority' => $host

    . ':' . $port, ':method' => 'GET', ':path' => '/style.css', ':scheme' => 'https', stream_id => $stream_id, ); aio_load './push.html', sub { my ($data) = @_; $server->response( ':status' => 200, stream_id => $stream_id, headers => [ 'server' => 'perl-Protocol-HTTP2/1.08', 'content-length' => length($data), 'content-type' => 'text/html', ], data => $data, ); }; } elsif ($header_map->{':path'} eq '/style.css') { # ࣍ͷεϥΠυ }
  144. αʔόʔϓογϡͷ࣮૷ elsif ($header_map->{':path'} eq '/style.css') { aio_load './style.css', sub {

    my ($data) = @_; $server->response( ':status' => 200, stream_id => $stream_id, headers => [ 'server' => 'perl-Protocol-HTTP2/1.08', 'content-length' => length($data), 'content-type' => 'text/css', ], data => $data, ); }; } …
  145. Time͕1msʹͳ͍ͬͯΔʂʂ ※ࠓճ͸cacheपΓͷϔομʔΛೖΕ͍ͯͳ͍ͷͰcss͕ڧ͘ Ωϟογϡ͞Εͯ͠·͏ͨΊγʔΫϨοτϞʔυਪ঑

  146. ଓ͍ͯΫϥΠΞϯτଆΛ࣮૷ ͠·͢

  147. αʔόʔϓογϡͷड৴ • Protocol::HTTP2::ClientͷΠϯελϯε࡞੒࣌ ʹ on_push() Λࢦఆ͢Δ͜ͱͰ PUSH_PROMISEΛड͚औΔ͜ͱ͕Ͱ͖Δ • ίʔϧόοΫΛฦ͢͜ͱͰσʔλΛड৴Ͱ͖Δ •

    undef Λฦͨ͠ΒΩϟϯηϧѻ͍
  148. αʔόʔϓογϡͷड৴ my $client = Protocol::HTTP2::Client->new( on_push => sub { my

    ($push_headers) = @_; print "Server want to push some resource to us\n”; return sub { my ($headers, $data) = @_; print "Received promised resource\n"; }; }, on_change_state => sub { }, on_error => sub { }, );
  149. ͨͬͨ͜Ε͚ͩʂ

  150. ࣮ࡍʹࢼͯ͠ΈΔ $ perl tls_client_server_push.pl Stream 1 changed state from IDLE

    to HALF_CLOSED Stream 2 changed state from IDLE to RESERVED Server want to push some resource to us Stream 1 changed state from HALF_CLOSED to CLOSED [ [ தུ ], "<html>\n <head>\n <title>HTTP/2 Server Push Test</title>\n <link rel=\"stylesheet\" href=\"/style.css\">\n </head>\n <body>\n <h1>Server <span class=\"push\">Push</span> Test</h1>\n </body\n</html>\n" ] Stream 2 changed state from RESERVED to HALF_CLOSED Stream 2 changed state from HALF_CLOSED to CLOSED Received promised resource $VAR1 = [ [ ':status', '200', 'server', 'perl-Protocol-HTTP2/1.08', 'content-length', '26', 'content-type', 'text/css' ], '.push { color: red; } ' ];
  151. ͪΌΜͱड৴Ͱ͖ͯ·͢Ͷʂʂ

  152. ͸͍

  153. ࠷ޙʹPSGIͰHTTP/2ʹରԠ ͢Δํ๏Λ঺հ͠·͢

  154. ͱ͍ͬͯ΋ͱͬͯ΋؆୯

  155. Protocol::HTTP2ͱಉ͡࡞ऀ ͕࡞͍ͬͯΔ”Shuvgey”Λ࢖ ͏͚ͩͰ͢

  156. Shuvgeyͷ࢖͍ํ $ shuvgey --listen :8000 --tls_key=cert.key --tls_crt=cert.crt app.psgi

  157. ͨͬͨ͜Ε͚ͩͰPSGIରԠͷ HTTP2αʔόʔ্ཱ͕͕ͪΔ ͧʂʂʂ

  158. ϦΫΤετͯ͠ΈΔ ʢࠓճ͸ —no_tls Ͱʣ $ shuvgey —listen 8080 —no_tls app.psgi

    $ perl no_tls_client.pl Stream 1 changed state from IDLE to HALF_CLOSED Stream 1 changed state from HALF_CLOSED to CLOSED [ [ ":status", "200", "content-type", "text/plain", "content-lenth", "13", "server", "Shuvgey/0.09" ], "hello, world!" ]
  159. ؆୯Ͱ͢Ͷʂʂ

  160. APIαʔόʔͱ͔ͩͬͨΒ͜ ΕΛ࢖͏ͱָͪΜͰ͢Ͷ

  161. ͜͜·Ͱͷ·ͱΊ • Protocol::HTTP2Λ࢖͑͹PerlͰ΋όϦόϦ HTTP/2Λ஻Δ͜ͱ͕Ͱ͖Δ • ͱ͸͍͑AnyEventͳͲΛར༻ͨ͠Πϕϯτۦ ಈͳϓϩάϥϛϯάεΩϧ͕ඞਢ • ShuvgeyΛ࢖͑͹؆୯ʹPSGI͕஻ΕΔ

  162. ͸͍

  163. ͓·͚: gRPCͱPerl

  164. ݁࿦

  165. ݱঢ়·ͱ΋ʹಈ࣮͘૷͸ͳ͍ ͱ͓΋ΘΕΔ

  166. None
  167. ࣮૷ࣗମ͸͋Δ • Grpc::XS • gRPCͷC++ͷόΠϯσΟϯά • Google::Protocol::Buffer::Dynamic • ϓϩτίϧόοϑΝʔͷC++ͷόΠϯσΟϯά •

    protoxs-perl • protocͰperlΛग़ྗͰ͖ΔΑ͏ʹ͢Δ΋ͷ
  168. ͔͠͠

  169. ࣮૷ࣗମ͸͋Δ • Grpc::XS • ࠷৽ͷϓϩτίϧόοϑΝʔͰϏϧυͰ͖ͳ͍ • ϏϧυͰ͖Δ؀ڥͱόʔδϣϯ͕ෆ໌ • Google::Protocol::Buffer::Dynamic •

    ࠷৽ͷϓϩτίϧόοϑΝʔͰϏϧυͰ͖ͳ͍ • ϏϧυͰ͖Δ؀ڥͱόʔδϣϯ͕ෆ໌ • protoxs-perl • ߋ৽͕10೥લ͔Β͋Δྺ࢙͋ΔϞδϡʔϧ • proto2·Ͱ͔͠ରԠ͍ͯ͠ͳ͍
  170. ͱ͍͏Θ͚Ͱ

  171. ༗ࣝऀͷํɺ࢖͍ํڭ͑ͯ͘ ͍ͩ͞ʂʂ

  172. ͨͩɺ࢓ࣄͰPerlͰgRPC࢖͏ ؾ͕͠ͳ͍

  173. None
  174. ·ͱΊ

  175. ·ͱΊ • HTTP/2͸HTTP/1.1ͷϓϩτίϧ্ͷϘτϧωοΫΛղ ফ͍͍ͯͬͯ͠Δ • ·ͩ·ͩ࠷దԽͷٞ࿦͸ଓ͍͍ͯΔ • PerlͰ΋HTTP/2͸όϦόϦ࢖͑Δ • ͨͩ͠ɺ͢΂ͯΠϕϯτۦಈͩ

    • gRPCϥΠϒϥϦʔɺGoogle͞Μग़͍ͯͩ͘͠͞
  176. ͝ਗ਼ௌ ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂʂ