slidge-whatsapp 0.2.5__cp313-cp313-manylinux_2_36_aarch64.whl → 0.2.7__cp313-cp313-manylinux_2_36_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of slidge-whatsapp might be problematic. Click here for more details.

Files changed (357) hide show
  1. slidge_whatsapp/config.py +3 -0
  2. slidge_whatsapp/event.go +31 -26
  3. slidge_whatsapp/gateway.go +13 -9
  4. slidge_whatsapp/gateway.py +2 -2
  5. slidge_whatsapp/generated/_whatsapp.cpython-313-aarch64-linux-gnu.h +135 -135
  6. slidge_whatsapp/generated/_whatsapp.cpython-313-aarch64-linux-gnu.so +0 -0
  7. slidge_whatsapp/generated/build.py +108 -108
  8. slidge_whatsapp/generated/whatsapp.c +954 -954
  9. slidge_whatsapp/generated/whatsapp.go +602 -602
  10. slidge_whatsapp/generated/whatsapp.py +783 -783
  11. slidge_whatsapp/generated/whatsapp_go.h +135 -135
  12. slidge_whatsapp/go.mod +15 -12
  13. slidge_whatsapp/go.sum +35 -29
  14. slidge_whatsapp/media/media.go +21 -11
  15. slidge_whatsapp/session.go +73 -66
  16. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlfcn.go +4 -4
  17. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlfcn_darwin.go +0 -5
  18. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_libinit.go +3 -0
  19. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols.go +40 -20
  20. slidge_whatsapp/vendor/github.com/jupiterrider/ffi/CHANGELOG.md +14 -1
  21. slidge_whatsapp/vendor/github.com/jupiterrider/ffi/ffi.go +2 -2
  22. slidge_whatsapp/vendor/github.com/jupiterrider/ffi/fun.go +10 -2
  23. slidge_whatsapp/vendor/github.com/jupiterrider/ffi/lib.go +1 -1
  24. slidge_whatsapp/vendor/github.com/jupiterrider/ffi/lib_unix.go +1 -1
  25. slidge_whatsapp/vendor/github.com/jupiterrider/ffi/lib_windows.go +1 -1
  26. slidge_whatsapp/vendor/github.com/mattn/go-sqlite3/README.md +2 -7
  27. slidge_whatsapp/vendor/github.com/mattn/go-sqlite3/callback.go +2 -1
  28. slidge_whatsapp/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c +8510 -5090
  29. slidge_whatsapp/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h +344 -150
  30. slidge_whatsapp/vendor/github.com/mattn/go-sqlite3/sqlite3.go +57 -23
  31. slidge_whatsapp/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.c +4 -0
  32. slidge_whatsapp/vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.go +4 -0
  33. slidge_whatsapp/vendor/github.com/petermattis/goid/.gitignore +4 -0
  34. slidge_whatsapp/vendor/github.com/petermattis/goid/LICENSE +202 -0
  35. slidge_whatsapp/vendor/github.com/petermattis/goid/README.md +4 -0
  36. slidge_whatsapp/vendor/github.com/petermattis/goid/goid.go +35 -0
  37. slidge_whatsapp/vendor/github.com/petermattis/goid/goid_gccgo.go +26 -0
  38. slidge_whatsapp/vendor/github.com/petermattis/goid/goid_go1.3.c +23 -0
  39. slidge_whatsapp/vendor/github.com/petermattis/goid/goid_go1.3.go +22 -0
  40. slidge_whatsapp/vendor/github.com/petermattis/goid/goid_go1.4.go +35 -0
  41. slidge_whatsapp/vendor/github.com/petermattis/goid/goid_go1.4.s +18 -0
  42. slidge_whatsapp/vendor/github.com/petermattis/goid/goid_go1.5.go +28 -0
  43. slidge_whatsapp/vendor/github.com/petermattis/goid/goid_go1.5.s +44 -0
  44. slidge_whatsapp/vendor/github.com/petermattis/goid/goid_slow.go +24 -0
  45. slidge_whatsapp/vendor/github.com/petermattis/goid/runtime_gccgo_go1.8.go +17 -0
  46. slidge_whatsapp/vendor/github.com/petermattis/goid/runtime_go1.23.go +38 -0
  47. slidge_whatsapp/vendor/github.com/petermattis/goid/runtime_go1.5.go +57 -0
  48. slidge_whatsapp/vendor/github.com/petermattis/goid/runtime_go1.6.go +43 -0
  49. slidge_whatsapp/vendor/github.com/petermattis/goid/runtime_go1.9.go +37 -0
  50. slidge_whatsapp/vendor/github.com/rs/zerolog/CONTRIBUTING.md +43 -0
  51. slidge_whatsapp/vendor/github.com/rs/zerolog/README.md +31 -0
  52. slidge_whatsapp/vendor/github.com/rs/zerolog/console.go +20 -5
  53. slidge_whatsapp/vendor/github.com/rs/zerolog/log/log.go +131 -0
  54. slidge_whatsapp/vendor/github.com/rs/zerolog/log.go +1 -1
  55. slidge_whatsapp/vendor/github.com/rs/zerolog/sampler.go +4 -1
  56. slidge_whatsapp/vendor/github.com/rs/zerolog/writer.go +9 -0
  57. slidge_whatsapp/vendor/go.mau.fi/libsignal/groups/GroupCipher.go +17 -6
  58. slidge_whatsapp/vendor/go.mau.fi/libsignal/groups/GroupSessionBuilder.go +17 -7
  59. slidge_whatsapp/vendor/go.mau.fi/libsignal/groups/state/store/SenderKeyStore.go +4 -2
  60. slidge_whatsapp/vendor/go.mau.fi/libsignal/keys/chain/ChainKey.go +1 -0
  61. slidge_whatsapp/vendor/go.mau.fi/libsignal/keys/identity/IdentityKey.go +1 -0
  62. slidge_whatsapp/vendor/go.mau.fi/libsignal/logger/DefaultLogger.go +2 -2
  63. slidge_whatsapp/vendor/go.mau.fi/libsignal/serialize/FingerprintProtocol.pb.go +3 -2
  64. slidge_whatsapp/vendor/go.mau.fi/libsignal/serialize/LocalStorageProtocol.pb.go +3 -2
  65. slidge_whatsapp/vendor/go.mau.fi/libsignal/serialize/WhisperTextProtocol.pb.go +3 -2
  66. slidge_whatsapp/vendor/go.mau.fi/libsignal/session/Session.go +41 -17
  67. slidge_whatsapp/vendor/go.mau.fi/libsignal/session/SessionCipher.go +64 -30
  68. slidge_whatsapp/vendor/go.mau.fi/libsignal/state/store/IdentityKeyStore.go +5 -3
  69. slidge_whatsapp/vendor/go.mau.fi/libsignal/state/store/MessageKeyStore.go +6 -4
  70. slidge_whatsapp/vendor/go.mau.fi/libsignal/state/store/PreKeyStore.go +6 -4
  71. slidge_whatsapp/vendor/go.mau.fi/libsignal/state/store/SessionStore.go +8 -6
  72. slidge_whatsapp/vendor/go.mau.fi/libsignal/state/store/SignedPreKeyStore.go +7 -5
  73. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/connlog.go +257 -0
  74. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/database.go +309 -0
  75. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/iter.go +233 -0
  76. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/json.go +47 -0
  77. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/log.go +129 -0
  78. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/massinsert.go +164 -0
  79. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/queryhelper.go +137 -0
  80. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/reflectscan.go +30 -0
  81. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/transaction.go +180 -0
  82. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/upgrades.go +250 -0
  83. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/upgradetable.go +331 -0
  84. slidge_whatsapp/vendor/go.mau.fi/util/exerrors/dualerror.go +33 -0
  85. slidge_whatsapp/vendor/go.mau.fi/util/exerrors/must.go +23 -0
  86. slidge_whatsapp/vendor/go.mau.fi/util/exhttp/cors.go +32 -0
  87. slidge_whatsapp/vendor/go.mau.fi/util/exhttp/handleerrors.go +64 -0
  88. slidge_whatsapp/vendor/go.mau.fi/util/exhttp/json.go +36 -0
  89. slidge_whatsapp/vendor/go.mau.fi/util/exhttp/middleware.go +30 -0
  90. slidge_whatsapp/vendor/go.mau.fi/util/exhttp/networkerror.go +37 -0
  91. slidge_whatsapp/vendor/go.mau.fi/util/exstrings/stringutil.go +76 -0
  92. slidge_whatsapp/vendor/go.mau.fi/util/exsync/event.go +88 -0
  93. slidge_whatsapp/vendor/go.mau.fi/util/exsync/returnonce.go +25 -0
  94. slidge_whatsapp/vendor/go.mau.fi/util/exsync/ringbuffer.go +139 -0
  95. slidge_whatsapp/vendor/go.mau.fi/util/exsync/syncmap.go +94 -0
  96. slidge_whatsapp/vendor/go.mau.fi/util/exsync/syncset.go +136 -0
  97. slidge_whatsapp/vendor/go.mau.fi/util/exzerolog/callermarshal.go +28 -0
  98. slidge_whatsapp/vendor/go.mau.fi/util/exzerolog/defaults.go +32 -0
  99. slidge_whatsapp/vendor/go.mau.fi/util/exzerolog/generics.go +45 -0
  100. slidge_whatsapp/vendor/go.mau.fi/util/exzerolog/writer.go +81 -0
  101. slidge_whatsapp/vendor/go.mau.fi/util/ptr/ptr.go +43 -0
  102. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate/decode.go +27 -26
  103. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate/encode.go +4 -3
  104. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate/keys.go +5 -4
  105. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate.go +27 -25
  106. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/armadillomessage.go +40 -7
  107. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/binary/encoder.go +1 -1
  108. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/broadcast.go +5 -4
  109. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/call.go +1 -1
  110. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/client.go +119 -37
  111. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/connectionevents.go +29 -11
  112. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/download-to-file.go +63 -30
  113. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/download.go +74 -34
  114. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/errors.go +1 -0
  115. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/group.go +61 -31
  116. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/internals.go +188 -152
  117. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/keepalive.go +3 -2
  118. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/mediaconn.go +5 -3
  119. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/mediaretry.go +2 -1
  120. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/message.go +444 -135
  121. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/msgsecret.go +118 -31
  122. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/notification.go +78 -42
  123. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/pair-code.go +7 -4
  124. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/pair.go +42 -18
  125. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/prekeys.go +9 -5
  126. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/presence.go +2 -1
  127. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/privacysettings.go +10 -11
  128. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/extra.go +7 -0
  129. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloAddMessage/InstamadilloAddMessage.pb.go +983 -0
  130. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloAddMessage/InstamadilloAddMessage.proto +85 -0
  131. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloAddMessage/extra.go +3 -0
  132. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeActionLog/InstamadilloCoreTypeActionLog.pb.go +197 -0
  133. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeActionLog/InstamadilloCoreTypeActionLog.proto +13 -0
  134. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeAdminMessage/InstamadilloCoreTypeAdminMessage.pb.go +279 -0
  135. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeAdminMessage/InstamadilloCoreTypeAdminMessage.proto +21 -0
  136. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeCollection/InstamadilloCoreTypeCollection.pb.go +137 -0
  137. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeCollection/InstamadilloCoreTypeCollection.proto +10 -0
  138. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeLink/InstamadilloCoreTypeLink.pb.go +313 -0
  139. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeLink/InstamadilloCoreTypeLink.proto +27 -0
  140. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeMedia/InstamadilloCoreTypeMedia.pb.go +1299 -0
  141. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeMedia/InstamadilloCoreTypeMedia.proto +112 -0
  142. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeText/InstamadilloCoreTypeText.pb.go +514 -0
  143. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeText/InstamadilloCoreTypeText.proto +47 -0
  144. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloDeleteMessage/InstamadilloDeleteMessage.pb.go +123 -0
  145. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloDeleteMessage/InstamadilloDeleteMessage.proto +7 -0
  146. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloDeleteMessage/extra.go +3 -0
  147. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloSupplementMessage/InstamadilloSupplementMessage.pb.go +720 -0
  148. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloSupplementMessage/InstamadilloSupplementMessage.proto +59 -0
  149. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloSupplementMessage/extra.go +3 -0
  150. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloTransportPayload/InstamadilloTransportPayload.pb.go +365 -0
  151. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloTransportPayload/InstamadilloTransportPayload.proto +33 -0
  152. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloXmaContentRef/InstamadilloXmaContentRef.pb.go +1238 -0
  153. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloXmaContentRef/InstamadilloXmaContentRef.proto +105 -0
  154. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waAdv/WAAdv.pb.go +39 -9
  155. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waArmadilloApplication/WAArmadilloApplication.pb.go +354 -175
  156. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waArmadilloApplication/WAArmadilloApplication.proto +5 -5
  157. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waArmadilloXMA/WAArmadilloXMA.pb.go +170 -15
  158. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waArmadilloXMA/WAArmadilloXMA.proto +4 -0
  159. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waCert/WACert.pb.go +29 -9
  160. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waChatLockSettings/WAProtobufsChatLockSettings.pb.go +13 -9
  161. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waCommon/WACommon.pb.go +344 -31
  162. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waCommon/WACommon.proto +26 -0
  163. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waCompanionReg/{WAWebProtobufsCompanionReg.pb.go → WACompanionReg.pb.go} +184 -89
  164. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waCompanionReg/{WAWebProtobufsCompanionReg.proto → WACompanionReg.proto} +2 -1
  165. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waConsumerApplication/WAConsumerApplication.pb.go +173 -9
  166. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waDeviceCapabilities/WAProtobufsDeviceCapabilities.pb.go +78 -16
  167. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waDeviceCapabilities/WAProtobufsDeviceCapabilities.proto +5 -0
  168. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.pb.go +7428 -2151
  169. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.proto +373 -44
  170. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waHistorySync/WAWebProtobufsHistorySync.pb.go +456 -135
  171. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waHistorySync/WAWebProtobufsHistorySync.proto +14 -0
  172. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waLidMigrationSyncPayload/WAWebProtobufLidMigrationSyncPayload.pb.go +198 -0
  173. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waLidMigrationSyncPayload/WAWebProtobufLidMigrationSyncPayload.proto +14 -0
  174. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMediaTransport/WAMediaTransport.pb.go +162 -9
  175. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMediaTransport/WAMediaTransport.proto +1 -0
  176. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMmsRetry/WAMmsRetry.pb.go +32 -9
  177. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMmsRetry/WAMmsRetry.proto +1 -0
  178. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMsgApplication/WAMsgApplication.pb.go +192 -52
  179. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMsgApplication/WAMsgApplication.proto +8 -0
  180. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMsgTransport/WAMsgTransport.pb.go +60 -9
  181. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMsgTransport/extra.go +7 -6
  182. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMultiDevice/WAMultiDevice.pb.go +39 -9
  183. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waServerSync/WAServerSync.pb.go +61 -9
  184. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waStatusAttributions/WAStatusAttributions.pb.go +800 -0
  185. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waStatusAttributions/WAStatusAttributions.proto +72 -0
  186. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.pb.go +1344 -438
  187. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.proto +52 -0
  188. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waUserPassword/WAProtobufsUserPassword.pb.go +27 -9
  189. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waVnameCert/WAWebProtobufsVnameCert.pb.go +59 -9
  190. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWa6/WAWebProtobufsWa6.pb.go +382 -78
  191. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWa6/WAWebProtobufsWa6.proto +8 -0
  192. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.pb.go +563 -9
  193. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.proto +4 -0
  194. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/receipt.go +25 -9
  195. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/reportingfields.json +1 -0
  196. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/reportingtoken.go +176 -0
  197. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/retry.go +39 -21
  198. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/send.go +261 -75
  199. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/sendfb.go +28 -16
  200. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/clientpayload.go +3 -1
  201. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/noop.go +85 -43
  202. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/signal.go +75 -88
  203. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/container.go +86 -65
  204. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/lidmap.go +186 -0
  205. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/store.go +291 -167
  206. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/00-latest-schema.sql +155 -0
  207. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/03-message-secrets.sql +11 -0
  208. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/04-privacy-tokens.sql +8 -0
  209. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/05-account-jid-format.sql +2 -0
  210. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/06-facebook-uuid.sql +2 -0
  211. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/07-account-lid.sql +2 -0
  212. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/08-lid-mapping.sql +5 -0
  213. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/09-decryption-buffer.sql +10 -0
  214. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/10-chat-db-lid-migration-ts.sql +2 -0
  215. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/upgrades.go +22 -0
  216. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/store.go +107 -56
  217. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/botmap.go +210 -0
  218. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/events/events.go +13 -2
  219. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/group.go +15 -6
  220. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/jid.go +7 -8
  221. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/message.go +18 -0
  222. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/update.go +3 -2
  223. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/upload.go +1 -1
  224. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/user.go +47 -29
  225. slidge_whatsapp/vendor/golang.org/x/exp/LICENSE +27 -0
  226. slidge_whatsapp/vendor/golang.org/x/exp/PATENTS +22 -0
  227. slidge_whatsapp/vendor/golang.org/x/exp/constraints/constraints.go +54 -0
  228. slidge_whatsapp/vendor/golang.org/x/net/http/httpguts/guts.go +50 -0
  229. slidge_whatsapp/vendor/golang.org/x/net/http/httpguts/httplex.go +347 -0
  230. slidge_whatsapp/vendor/golang.org/x/net/http2/.gitignore +2 -0
  231. slidge_whatsapp/vendor/golang.org/x/net/http2/ascii.go +53 -0
  232. slidge_whatsapp/vendor/golang.org/x/net/http2/ciphers.go +641 -0
  233. slidge_whatsapp/vendor/golang.org/x/net/http2/client_conn_pool.go +311 -0
  234. slidge_whatsapp/vendor/golang.org/x/net/http2/config.go +122 -0
  235. slidge_whatsapp/vendor/golang.org/x/net/http2/config_go124.go +61 -0
  236. slidge_whatsapp/vendor/golang.org/x/net/http2/config_pre_go124.go +16 -0
  237. slidge_whatsapp/vendor/golang.org/x/net/http2/databuffer.go +149 -0
  238. slidge_whatsapp/vendor/golang.org/x/net/http2/errors.go +145 -0
  239. slidge_whatsapp/vendor/golang.org/x/net/http2/flow.go +120 -0
  240. slidge_whatsapp/vendor/golang.org/x/net/http2/frame.go +1702 -0
  241. slidge_whatsapp/vendor/golang.org/x/net/http2/gotrack.go +170 -0
  242. slidge_whatsapp/vendor/golang.org/x/net/http2/hpack/encode.go +245 -0
  243. slidge_whatsapp/vendor/golang.org/x/net/http2/hpack/hpack.go +523 -0
  244. slidge_whatsapp/vendor/golang.org/x/net/http2/hpack/huffman.go +226 -0
  245. slidge_whatsapp/vendor/golang.org/x/net/http2/hpack/static_table.go +188 -0
  246. slidge_whatsapp/vendor/golang.org/x/net/http2/hpack/tables.go +403 -0
  247. slidge_whatsapp/vendor/golang.org/x/net/http2/http2.go +432 -0
  248. slidge_whatsapp/vendor/golang.org/x/net/http2/pipe.go +184 -0
  249. slidge_whatsapp/vendor/golang.org/x/net/http2/server.go +3350 -0
  250. slidge_whatsapp/vendor/golang.org/x/net/http2/timer.go +20 -0
  251. slidge_whatsapp/vendor/golang.org/x/net/http2/transport.go +3287 -0
  252. slidge_whatsapp/vendor/golang.org/x/net/http2/unencrypted.go +32 -0
  253. slidge_whatsapp/vendor/golang.org/x/net/http2/write.go +381 -0
  254. slidge_whatsapp/vendor/golang.org/x/net/http2/writesched.go +251 -0
  255. slidge_whatsapp/vendor/golang.org/x/net/http2/writesched_priority.go +451 -0
  256. slidge_whatsapp/vendor/golang.org/x/net/http2/writesched_random.go +77 -0
  257. slidge_whatsapp/vendor/golang.org/x/net/http2/writesched_roundrobin.go +119 -0
  258. slidge_whatsapp/vendor/golang.org/x/net/idna/go118.go +13 -0
  259. slidge_whatsapp/vendor/golang.org/x/net/idna/idna10.0.0.go +769 -0
  260. slidge_whatsapp/vendor/golang.org/x/net/idna/idna9.0.0.go +717 -0
  261. slidge_whatsapp/vendor/golang.org/x/net/idna/pre_go118.go +11 -0
  262. slidge_whatsapp/vendor/golang.org/x/net/idna/punycode.go +217 -0
  263. slidge_whatsapp/vendor/golang.org/x/net/idna/tables10.0.0.go +4559 -0
  264. slidge_whatsapp/vendor/golang.org/x/net/idna/tables11.0.0.go +4653 -0
  265. slidge_whatsapp/vendor/golang.org/x/net/idna/tables12.0.0.go +4733 -0
  266. slidge_whatsapp/vendor/golang.org/x/net/idna/tables13.0.0.go +4959 -0
  267. slidge_whatsapp/vendor/golang.org/x/net/idna/tables15.0.0.go +5144 -0
  268. slidge_whatsapp/vendor/golang.org/x/net/idna/tables9.0.0.go +4486 -0
  269. slidge_whatsapp/vendor/golang.org/x/net/idna/trie.go +51 -0
  270. slidge_whatsapp/vendor/golang.org/x/net/idna/trie12.0.0.go +30 -0
  271. slidge_whatsapp/vendor/golang.org/x/net/idna/trie13.0.0.go +30 -0
  272. slidge_whatsapp/vendor/golang.org/x/net/idna/trieval.go +119 -0
  273. slidge_whatsapp/vendor/golang.org/x/net/internal/httpcommon/ascii.go +53 -0
  274. slidge_whatsapp/vendor/golang.org/x/net/internal/httpcommon/headermap.go +115 -0
  275. slidge_whatsapp/vendor/golang.org/x/net/internal/httpcommon/request.go +467 -0
  276. slidge_whatsapp/vendor/golang.org/x/sys/unix/syscall_darwin.go +148 -1
  277. slidge_whatsapp/vendor/golang.org/x/sys/unix/syscall_linux.go +16 -26
  278. slidge_whatsapp/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +84 -0
  279. slidge_whatsapp/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s +20 -0
  280. slidge_whatsapp/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +84 -0
  281. slidge_whatsapp/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s +20 -0
  282. slidge_whatsapp/vendor/golang.org/x/sys/windows/security_windows.go +44 -5
  283. slidge_whatsapp/vendor/golang.org/x/sys/windows/syscall_windows.go +4 -2
  284. slidge_whatsapp/vendor/golang.org/x/sys/windows/types_windows.go +239 -0
  285. slidge_whatsapp/vendor/golang.org/x/sys/windows/zsyscall_windows.go +9 -0
  286. slidge_whatsapp/vendor/golang.org/x/text/LICENSE +27 -0
  287. slidge_whatsapp/vendor/golang.org/x/text/PATENTS +22 -0
  288. slidge_whatsapp/vendor/golang.org/x/text/secure/bidirule/bidirule.go +336 -0
  289. slidge_whatsapp/vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go +11 -0
  290. slidge_whatsapp/vendor/golang.org/x/text/secure/bidirule/bidirule9.0.0.go +14 -0
  291. slidge_whatsapp/vendor/golang.org/x/text/transform/transform.go +709 -0
  292. slidge_whatsapp/vendor/golang.org/x/text/unicode/bidi/bidi.go +359 -0
  293. slidge_whatsapp/vendor/golang.org/x/text/unicode/bidi/bracket.go +335 -0
  294. slidge_whatsapp/vendor/golang.org/x/text/unicode/bidi/core.go +1071 -0
  295. slidge_whatsapp/vendor/golang.org/x/text/unicode/bidi/prop.go +206 -0
  296. slidge_whatsapp/vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go +1815 -0
  297. slidge_whatsapp/vendor/golang.org/x/text/unicode/bidi/tables11.0.0.go +1887 -0
  298. slidge_whatsapp/vendor/golang.org/x/text/unicode/bidi/tables12.0.0.go +1923 -0
  299. slidge_whatsapp/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go +1955 -0
  300. slidge_whatsapp/vendor/golang.org/x/text/unicode/bidi/tables15.0.0.go +2042 -0
  301. slidge_whatsapp/vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go +1781 -0
  302. slidge_whatsapp/vendor/golang.org/x/text/unicode/bidi/trieval.go +48 -0
  303. slidge_whatsapp/vendor/golang.org/x/text/unicode/norm/composition.go +512 -0
  304. slidge_whatsapp/vendor/golang.org/x/text/unicode/norm/forminfo.go +279 -0
  305. slidge_whatsapp/vendor/golang.org/x/text/unicode/norm/input.go +109 -0
  306. slidge_whatsapp/vendor/golang.org/x/text/unicode/norm/iter.go +458 -0
  307. slidge_whatsapp/vendor/golang.org/x/text/unicode/norm/normalize.go +610 -0
  308. slidge_whatsapp/vendor/golang.org/x/text/unicode/norm/readwriter.go +125 -0
  309. slidge_whatsapp/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go +7657 -0
  310. slidge_whatsapp/vendor/golang.org/x/text/unicode/norm/tables11.0.0.go +7693 -0
  311. slidge_whatsapp/vendor/golang.org/x/text/unicode/norm/tables12.0.0.go +7710 -0
  312. slidge_whatsapp/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go +7760 -0
  313. slidge_whatsapp/vendor/golang.org/x/text/unicode/norm/tables15.0.0.go +7907 -0
  314. slidge_whatsapp/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go +7637 -0
  315. slidge_whatsapp/vendor/golang.org/x/text/unicode/norm/transform.go +88 -0
  316. slidge_whatsapp/vendor/golang.org/x/text/unicode/norm/trie.go +54 -0
  317. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb +0 -0
  318. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/filedesc/editions.go +3 -0
  319. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go +16 -0
  320. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/strs/{strings_unsafe_go121.go → strings_unsafe.go} +0 -2
  321. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/version/version.go +1 -1
  322. slidge_whatsapp/vendor/google.golang.org/protobuf/proto/merge.go +6 -0
  323. slidge_whatsapp/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go +2 -0
  324. slidge_whatsapp/vendor/google.golang.org/protobuf/reflect/protoreflect/{value_unsafe_go121.go → value_unsafe.go} +0 -2
  325. slidge_whatsapp/vendor/modules.txt +52 -13
  326. {slidge_whatsapp-0.2.5.dist-info → slidge_whatsapp-0.2.7.dist-info}/METADATA +1 -1
  327. {slidge_whatsapp-0.2.5.dist-info → slidge_whatsapp-0.2.7.dist-info}/RECORD +330 -184
  328. {slidge_whatsapp-0.2.5.dist-info → slidge_whatsapp-0.2.7.dist-info}/WHEEL +1 -1
  329. slidge_whatsapp/vendor/github.com/rs/zerolog/CNAME +0 -1
  330. slidge_whatsapp/vendor/github.com/rs/zerolog/_config.yml +0 -1
  331. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waAdv/WAAdv.pb.raw +0 -0
  332. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waArmadilloApplication/WAArmadilloApplication.pb.raw +0 -0
  333. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waArmadilloXMA/WAArmadilloXMA.pb.raw +0 -0
  334. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waCert/WACert.pb.raw +0 -23
  335. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waChatLockSettings/WAProtobufsChatLockSettings.pb.raw +0 -7
  336. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waCommon/WACommon.pb.raw +0 -0
  337. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waCompanionReg/WAWebProtobufsCompanionReg.pb.raw +0 -0
  338. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waConsumerApplication/WAConsumerApplication.pb.raw +0 -0
  339. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waDeviceCapabilities/WAProtobufsDeviceCapabilities.pb.raw +0 -0
  340. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.pb.raw +0 -0
  341. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waHistorySync/WAWebProtobufsHistorySync.pb.raw +0 -0
  342. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMediaTransport/WAMediaTransport.pb.raw +0 -0
  343. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMmsRetry/WAMmsRetry.pb.raw +0 -0
  344. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMsgApplication/WAMsgApplication.pb.raw +0 -0
  345. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMsgTransport/WAMsgTransport.pb.raw +0 -0
  346. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMultiDevice/WAMultiDevice.pb.raw +0 -0
  347. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waServerSync/WAServerSync.pb.raw +0 -0
  348. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.pb.raw +0 -0
  349. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waUserPassword/WAProtobufsUserPassword.pb.raw +0 -0
  350. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waVnameCert/WAWebProtobufsVnameCert.pb.raw +0 -0
  351. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWa6/WAWebProtobufsWa6.pb.raw +0 -0
  352. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.pb.raw +0 -0
  353. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrade.go +0 -296
  354. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/strs/strings_unsafe_go120.go +0 -94
  355. slidge_whatsapp/vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe_go120.go +0 -98
  356. {slidge_whatsapp-0.2.5.dist-info → slidge_whatsapp-0.2.7.dist-info}/LICENSE +0 -0
  357. {slidge_whatsapp-0.2.5.dist-info → slidge_whatsapp-0.2.7.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,1702 @@
1
+ // Copyright 2014 The Go Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style
3
+ // license that can be found in the LICENSE file.
4
+
5
+ package http2
6
+
7
+ import (
8
+ "bytes"
9
+ "encoding/binary"
10
+ "errors"
11
+ "fmt"
12
+ "io"
13
+ "log"
14
+ "strings"
15
+ "sync"
16
+
17
+ "golang.org/x/net/http/httpguts"
18
+ "golang.org/x/net/http2/hpack"
19
+ )
20
+
21
+ const frameHeaderLen = 9
22
+
23
+ var padZeros = make([]byte, 255) // zeros for padding
24
+
25
+ // A FrameType is a registered frame type as defined in
26
+ // https://httpwg.org/specs/rfc7540.html#rfc.section.11.2
27
+ type FrameType uint8
28
+
29
+ const (
30
+ FrameData FrameType = 0x0
31
+ FrameHeaders FrameType = 0x1
32
+ FramePriority FrameType = 0x2
33
+ FrameRSTStream FrameType = 0x3
34
+ FrameSettings FrameType = 0x4
35
+ FramePushPromise FrameType = 0x5
36
+ FramePing FrameType = 0x6
37
+ FrameGoAway FrameType = 0x7
38
+ FrameWindowUpdate FrameType = 0x8
39
+ FrameContinuation FrameType = 0x9
40
+ )
41
+
42
+ var frameNames = [...]string{
43
+ FrameData: "DATA",
44
+ FrameHeaders: "HEADERS",
45
+ FramePriority: "PRIORITY",
46
+ FrameRSTStream: "RST_STREAM",
47
+ FrameSettings: "SETTINGS",
48
+ FramePushPromise: "PUSH_PROMISE",
49
+ FramePing: "PING",
50
+ FrameGoAway: "GOAWAY",
51
+ FrameWindowUpdate: "WINDOW_UPDATE",
52
+ FrameContinuation: "CONTINUATION",
53
+ }
54
+
55
+ func (t FrameType) String() string {
56
+ if int(t) < len(frameNames) {
57
+ return frameNames[t]
58
+ }
59
+ return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", t)
60
+ }
61
+
62
+ // Flags is a bitmask of HTTP/2 flags.
63
+ // The meaning of flags varies depending on the frame type.
64
+ type Flags uint8
65
+
66
+ // Has reports whether f contains all (0 or more) flags in v.
67
+ func (f Flags) Has(v Flags) bool {
68
+ return (f & v) == v
69
+ }
70
+
71
+ // Frame-specific FrameHeader flag bits.
72
+ const (
73
+ // Data Frame
74
+ FlagDataEndStream Flags = 0x1
75
+ FlagDataPadded Flags = 0x8
76
+
77
+ // Headers Frame
78
+ FlagHeadersEndStream Flags = 0x1
79
+ FlagHeadersEndHeaders Flags = 0x4
80
+ FlagHeadersPadded Flags = 0x8
81
+ FlagHeadersPriority Flags = 0x20
82
+
83
+ // Settings Frame
84
+ FlagSettingsAck Flags = 0x1
85
+
86
+ // Ping Frame
87
+ FlagPingAck Flags = 0x1
88
+
89
+ // Continuation Frame
90
+ FlagContinuationEndHeaders Flags = 0x4
91
+
92
+ FlagPushPromiseEndHeaders Flags = 0x4
93
+ FlagPushPromisePadded Flags = 0x8
94
+ )
95
+
96
+ var flagName = map[FrameType]map[Flags]string{
97
+ FrameData: {
98
+ FlagDataEndStream: "END_STREAM",
99
+ FlagDataPadded: "PADDED",
100
+ },
101
+ FrameHeaders: {
102
+ FlagHeadersEndStream: "END_STREAM",
103
+ FlagHeadersEndHeaders: "END_HEADERS",
104
+ FlagHeadersPadded: "PADDED",
105
+ FlagHeadersPriority: "PRIORITY",
106
+ },
107
+ FrameSettings: {
108
+ FlagSettingsAck: "ACK",
109
+ },
110
+ FramePing: {
111
+ FlagPingAck: "ACK",
112
+ },
113
+ FrameContinuation: {
114
+ FlagContinuationEndHeaders: "END_HEADERS",
115
+ },
116
+ FramePushPromise: {
117
+ FlagPushPromiseEndHeaders: "END_HEADERS",
118
+ FlagPushPromisePadded: "PADDED",
119
+ },
120
+ }
121
+
122
+ // a frameParser parses a frame given its FrameHeader and payload
123
+ // bytes. The length of payload will always equal fh.Length (which
124
+ // might be 0).
125
+ type frameParser func(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error)
126
+
127
+ var frameParsers = [...]frameParser{
128
+ FrameData: parseDataFrame,
129
+ FrameHeaders: parseHeadersFrame,
130
+ FramePriority: parsePriorityFrame,
131
+ FrameRSTStream: parseRSTStreamFrame,
132
+ FrameSettings: parseSettingsFrame,
133
+ FramePushPromise: parsePushPromise,
134
+ FramePing: parsePingFrame,
135
+ FrameGoAway: parseGoAwayFrame,
136
+ FrameWindowUpdate: parseWindowUpdateFrame,
137
+ FrameContinuation: parseContinuationFrame,
138
+ }
139
+
140
+ func typeFrameParser(t FrameType) frameParser {
141
+ if int(t) < len(frameParsers) {
142
+ return frameParsers[t]
143
+ }
144
+ return parseUnknownFrame
145
+ }
146
+
147
+ // A FrameHeader is the 9 byte header of all HTTP/2 frames.
148
+ //
149
+ // See https://httpwg.org/specs/rfc7540.html#FrameHeader
150
+ type FrameHeader struct {
151
+ valid bool // caller can access []byte fields in the Frame
152
+
153
+ // Type is the 1 byte frame type. There are ten standard frame
154
+ // types, but extension frame types may be written by WriteRawFrame
155
+ // and will be returned by ReadFrame (as UnknownFrame).
156
+ Type FrameType
157
+
158
+ // Flags are the 1 byte of 8 potential bit flags per frame.
159
+ // They are specific to the frame type.
160
+ Flags Flags
161
+
162
+ // Length is the length of the frame, not including the 9 byte header.
163
+ // The maximum size is one byte less than 16MB (uint24), but only
164
+ // frames up to 16KB are allowed without peer agreement.
165
+ Length uint32
166
+
167
+ // StreamID is which stream this frame is for. Certain frames
168
+ // are not stream-specific, in which case this field is 0.
169
+ StreamID uint32
170
+ }
171
+
172
+ // Header returns h. It exists so FrameHeaders can be embedded in other
173
+ // specific frame types and implement the Frame interface.
174
+ func (h FrameHeader) Header() FrameHeader { return h }
175
+
176
+ func (h FrameHeader) String() string {
177
+ var buf bytes.Buffer
178
+ buf.WriteString("[FrameHeader ")
179
+ h.writeDebug(&buf)
180
+ buf.WriteByte(']')
181
+ return buf.String()
182
+ }
183
+
184
+ func (h FrameHeader) writeDebug(buf *bytes.Buffer) {
185
+ buf.WriteString(h.Type.String())
186
+ if h.Flags != 0 {
187
+ buf.WriteString(" flags=")
188
+ set := 0
189
+ for i := uint8(0); i < 8; i++ {
190
+ if h.Flags&(1<<i) == 0 {
191
+ continue
192
+ }
193
+ set++
194
+ if set > 1 {
195
+ buf.WriteByte('|')
196
+ }
197
+ name := flagName[h.Type][Flags(1<<i)]
198
+ if name != "" {
199
+ buf.WriteString(name)
200
+ } else {
201
+ fmt.Fprintf(buf, "0x%x", 1<<i)
202
+ }
203
+ }
204
+ }
205
+ if h.StreamID != 0 {
206
+ fmt.Fprintf(buf, " stream=%d", h.StreamID)
207
+ }
208
+ fmt.Fprintf(buf, " len=%d", h.Length)
209
+ }
210
+
211
+ func (h *FrameHeader) checkValid() {
212
+ if !h.valid {
213
+ panic("Frame accessor called on non-owned Frame")
214
+ }
215
+ }
216
+
217
+ func (h *FrameHeader) invalidate() { h.valid = false }
218
+
219
+ // frame header bytes.
220
+ // Used only by ReadFrameHeader.
221
+ var fhBytes = sync.Pool{
222
+ New: func() interface{} {
223
+ buf := make([]byte, frameHeaderLen)
224
+ return &buf
225
+ },
226
+ }
227
+
228
+ func invalidHTTP1LookingFrameHeader() FrameHeader {
229
+ fh, _ := readFrameHeader(make([]byte, frameHeaderLen), strings.NewReader("HTTP/1.1 "))
230
+ return fh
231
+ }
232
+
233
+ // ReadFrameHeader reads 9 bytes from r and returns a FrameHeader.
234
+ // Most users should use Framer.ReadFrame instead.
235
+ func ReadFrameHeader(r io.Reader) (FrameHeader, error) {
236
+ bufp := fhBytes.Get().(*[]byte)
237
+ defer fhBytes.Put(bufp)
238
+ return readFrameHeader(*bufp, r)
239
+ }
240
+
241
+ func readFrameHeader(buf []byte, r io.Reader) (FrameHeader, error) {
242
+ _, err := io.ReadFull(r, buf[:frameHeaderLen])
243
+ if err != nil {
244
+ return FrameHeader{}, err
245
+ }
246
+ return FrameHeader{
247
+ Length: (uint32(buf[0])<<16 | uint32(buf[1])<<8 | uint32(buf[2])),
248
+ Type: FrameType(buf[3]),
249
+ Flags: Flags(buf[4]),
250
+ StreamID: binary.BigEndian.Uint32(buf[5:]) & (1<<31 - 1),
251
+ valid: true,
252
+ }, nil
253
+ }
254
+
255
+ // A Frame is the base interface implemented by all frame types.
256
+ // Callers will generally type-assert the specific frame type:
257
+ // *HeadersFrame, *SettingsFrame, *WindowUpdateFrame, etc.
258
+ //
259
+ // Frames are only valid until the next call to Framer.ReadFrame.
260
+ type Frame interface {
261
+ Header() FrameHeader
262
+
263
+ // invalidate is called by Framer.ReadFrame to make this
264
+ // frame's buffers as being invalid, since the subsequent
265
+ // frame will reuse them.
266
+ invalidate()
267
+ }
268
+
269
+ // A Framer reads and writes Frames.
270
+ type Framer struct {
271
+ r io.Reader
272
+ lastFrame Frame
273
+ errDetail error
274
+
275
+ // countError is a non-nil func that's called on a frame parse
276
+ // error with some unique error path token. It's initialized
277
+ // from Transport.CountError or Server.CountError.
278
+ countError func(errToken string)
279
+
280
+ // lastHeaderStream is non-zero if the last frame was an
281
+ // unfinished HEADERS/CONTINUATION.
282
+ lastHeaderStream uint32
283
+
284
+ maxReadSize uint32
285
+ headerBuf [frameHeaderLen]byte
286
+
287
+ // TODO: let getReadBuf be configurable, and use a less memory-pinning
288
+ // allocator in server.go to minimize memory pinned for many idle conns.
289
+ // Will probably also need to make frame invalidation have a hook too.
290
+ getReadBuf func(size uint32) []byte
291
+ readBuf []byte // cache for default getReadBuf
292
+
293
+ maxWriteSize uint32 // zero means unlimited; TODO: implement
294
+
295
+ w io.Writer
296
+ wbuf []byte
297
+
298
+ // AllowIllegalWrites permits the Framer's Write methods to
299
+ // write frames that do not conform to the HTTP/2 spec. This
300
+ // permits using the Framer to test other HTTP/2
301
+ // implementations' conformance to the spec.
302
+ // If false, the Write methods will prefer to return an error
303
+ // rather than comply.
304
+ AllowIllegalWrites bool
305
+
306
+ // AllowIllegalReads permits the Framer's ReadFrame method
307
+ // to return non-compliant frames or frame orders.
308
+ // This is for testing and permits using the Framer to test
309
+ // other HTTP/2 implementations' conformance to the spec.
310
+ // It is not compatible with ReadMetaHeaders.
311
+ AllowIllegalReads bool
312
+
313
+ // ReadMetaHeaders if non-nil causes ReadFrame to merge
314
+ // HEADERS and CONTINUATION frames together and return
315
+ // MetaHeadersFrame instead.
316
+ ReadMetaHeaders *hpack.Decoder
317
+
318
+ // MaxHeaderListSize is the http2 MAX_HEADER_LIST_SIZE.
319
+ // It's used only if ReadMetaHeaders is set; 0 means a sane default
320
+ // (currently 16MB)
321
+ // If the limit is hit, MetaHeadersFrame.Truncated is set true.
322
+ MaxHeaderListSize uint32
323
+
324
+ // TODO: track which type of frame & with which flags was sent
325
+ // last. Then return an error (unless AllowIllegalWrites) if
326
+ // we're in the middle of a header block and a
327
+ // non-Continuation or Continuation on a different stream is
328
+ // attempted to be written.
329
+
330
+ logReads, logWrites bool
331
+
332
+ debugFramer *Framer // only use for logging written writes
333
+ debugFramerBuf *bytes.Buffer
334
+ debugReadLoggerf func(string, ...interface{})
335
+ debugWriteLoggerf func(string, ...interface{})
336
+
337
+ frameCache *frameCache // nil if frames aren't reused (default)
338
+ }
339
+
340
+ func (fr *Framer) maxHeaderListSize() uint32 {
341
+ if fr.MaxHeaderListSize == 0 {
342
+ return 16 << 20 // sane default, per docs
343
+ }
344
+ return fr.MaxHeaderListSize
345
+ }
346
+
347
+ func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) {
348
+ // Write the FrameHeader.
349
+ f.wbuf = append(f.wbuf[:0],
350
+ 0, // 3 bytes of length, filled in in endWrite
351
+ 0,
352
+ 0,
353
+ byte(ftype),
354
+ byte(flags),
355
+ byte(streamID>>24),
356
+ byte(streamID>>16),
357
+ byte(streamID>>8),
358
+ byte(streamID))
359
+ }
360
+
361
+ func (f *Framer) endWrite() error {
362
+ // Now that we know the final size, fill in the FrameHeader in
363
+ // the space previously reserved for it. Abuse append.
364
+ length := len(f.wbuf) - frameHeaderLen
365
+ if length >= (1 << 24) {
366
+ return ErrFrameTooLarge
367
+ }
368
+ _ = append(f.wbuf[:0],
369
+ byte(length>>16),
370
+ byte(length>>8),
371
+ byte(length))
372
+ if f.logWrites {
373
+ f.logWrite()
374
+ }
375
+
376
+ n, err := f.w.Write(f.wbuf)
377
+ if err == nil && n != len(f.wbuf) {
378
+ err = io.ErrShortWrite
379
+ }
380
+ return err
381
+ }
382
+
383
+ func (f *Framer) logWrite() {
384
+ if f.debugFramer == nil {
385
+ f.debugFramerBuf = new(bytes.Buffer)
386
+ f.debugFramer = NewFramer(nil, f.debugFramerBuf)
387
+ f.debugFramer.logReads = false // we log it ourselves, saying "wrote" below
388
+ // Let us read anything, even if we accidentally wrote it
389
+ // in the wrong order:
390
+ f.debugFramer.AllowIllegalReads = true
391
+ }
392
+ f.debugFramerBuf.Write(f.wbuf)
393
+ fr, err := f.debugFramer.ReadFrame()
394
+ if err != nil {
395
+ f.debugWriteLoggerf("http2: Framer %p: failed to decode just-written frame", f)
396
+ return
397
+ }
398
+ f.debugWriteLoggerf("http2: Framer %p: wrote %v", f, summarizeFrame(fr))
399
+ }
400
+
401
+ func (f *Framer) writeByte(v byte) { f.wbuf = append(f.wbuf, v) }
402
+ func (f *Framer) writeBytes(v []byte) { f.wbuf = append(f.wbuf, v...) }
403
+ func (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) }
404
+ func (f *Framer) writeUint32(v uint32) {
405
+ f.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
406
+ }
407
+
408
+ const (
409
+ minMaxFrameSize = 1 << 14
410
+ maxFrameSize = 1<<24 - 1
411
+ )
412
+
413
+ // SetReuseFrames allows the Framer to reuse Frames.
414
+ // If called on a Framer, Frames returned by calls to ReadFrame are only
415
+ // valid until the next call to ReadFrame.
416
+ func (fr *Framer) SetReuseFrames() {
417
+ if fr.frameCache != nil {
418
+ return
419
+ }
420
+ fr.frameCache = &frameCache{}
421
+ }
422
+
423
+ type frameCache struct {
424
+ dataFrame DataFrame
425
+ }
426
+
427
+ func (fc *frameCache) getDataFrame() *DataFrame {
428
+ if fc == nil {
429
+ return &DataFrame{}
430
+ }
431
+ return &fc.dataFrame
432
+ }
433
+
434
+ // NewFramer returns a Framer that writes frames to w and reads them from r.
435
+ func NewFramer(w io.Writer, r io.Reader) *Framer {
436
+ fr := &Framer{
437
+ w: w,
438
+ r: r,
439
+ countError: func(string) {},
440
+ logReads: logFrameReads,
441
+ logWrites: logFrameWrites,
442
+ debugReadLoggerf: log.Printf,
443
+ debugWriteLoggerf: log.Printf,
444
+ }
445
+ fr.getReadBuf = func(size uint32) []byte {
446
+ if cap(fr.readBuf) >= int(size) {
447
+ return fr.readBuf[:size]
448
+ }
449
+ fr.readBuf = make([]byte, size)
450
+ return fr.readBuf
451
+ }
452
+ fr.SetMaxReadFrameSize(maxFrameSize)
453
+ return fr
454
+ }
455
+
456
+ // SetMaxReadFrameSize sets the maximum size of a frame
457
+ // that will be read by a subsequent call to ReadFrame.
458
+ // It is the caller's responsibility to advertise this
459
+ // limit with a SETTINGS frame.
460
+ func (fr *Framer) SetMaxReadFrameSize(v uint32) {
461
+ if v > maxFrameSize {
462
+ v = maxFrameSize
463
+ }
464
+ fr.maxReadSize = v
465
+ }
466
+
467
+ // ErrorDetail returns a more detailed error of the last error
468
+ // returned by Framer.ReadFrame. For instance, if ReadFrame
469
+ // returns a StreamError with code PROTOCOL_ERROR, ErrorDetail
470
+ // will say exactly what was invalid. ErrorDetail is not guaranteed
471
+ // to return a non-nil value and like the rest of the http2 package,
472
+ // its return value is not protected by an API compatibility promise.
473
+ // ErrorDetail is reset after the next call to ReadFrame.
474
+ func (fr *Framer) ErrorDetail() error {
475
+ return fr.errDetail
476
+ }
477
+
478
+ // ErrFrameTooLarge is returned from Framer.ReadFrame when the peer
479
+ // sends a frame that is larger than declared with SetMaxReadFrameSize.
480
+ var ErrFrameTooLarge = errors.New("http2: frame too large")
481
+
482
+ // terminalReadFrameError reports whether err is an unrecoverable
483
+ // error from ReadFrame and no other frames should be read.
484
+ func terminalReadFrameError(err error) bool {
485
+ if _, ok := err.(StreamError); ok {
486
+ return false
487
+ }
488
+ return err != nil
489
+ }
490
+
491
+ // ReadFrame reads a single frame. The returned Frame is only valid
492
+ // until the next call to ReadFrame.
493
+ //
494
+ // If the frame is larger than previously set with SetMaxReadFrameSize, the
495
+ // returned error is ErrFrameTooLarge. Other errors may be of type
496
+ // ConnectionError, StreamError, or anything else from the underlying
497
+ // reader.
498
+ //
499
+ // If ReadFrame returns an error and a non-nil Frame, the Frame's StreamID
500
+ // indicates the stream responsible for the error.
501
+ func (fr *Framer) ReadFrame() (Frame, error) {
502
+ fr.errDetail = nil
503
+ if fr.lastFrame != nil {
504
+ fr.lastFrame.invalidate()
505
+ }
506
+ fh, err := readFrameHeader(fr.headerBuf[:], fr.r)
507
+ if err != nil {
508
+ return nil, err
509
+ }
510
+ if fh.Length > fr.maxReadSize {
511
+ if fh == invalidHTTP1LookingFrameHeader() {
512
+ return nil, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", ErrFrameTooLarge)
513
+ }
514
+ return nil, ErrFrameTooLarge
515
+ }
516
+ payload := fr.getReadBuf(fh.Length)
517
+ if _, err := io.ReadFull(fr.r, payload); err != nil {
518
+ if fh == invalidHTTP1LookingFrameHeader() {
519
+ return nil, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", err)
520
+ }
521
+ return nil, err
522
+ }
523
+ f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, fr.countError, payload)
524
+ if err != nil {
525
+ if ce, ok := err.(connError); ok {
526
+ return nil, fr.connError(ce.Code, ce.Reason)
527
+ }
528
+ return nil, err
529
+ }
530
+ if err := fr.checkFrameOrder(f); err != nil {
531
+ return nil, err
532
+ }
533
+ if fr.logReads {
534
+ fr.debugReadLoggerf("http2: Framer %p: read %v", fr, summarizeFrame(f))
535
+ }
536
+ if fh.Type == FrameHeaders && fr.ReadMetaHeaders != nil {
537
+ return fr.readMetaFrame(f.(*HeadersFrame))
538
+ }
539
+ return f, nil
540
+ }
541
+
542
+ // connError returns ConnectionError(code) but first
543
+ // stashes away a public reason to the caller can optionally relay it
544
+ // to the peer before hanging up on them. This might help others debug
545
+ // their implementations.
546
+ func (fr *Framer) connError(code ErrCode, reason string) error {
547
+ fr.errDetail = errors.New(reason)
548
+ return ConnectionError(code)
549
+ }
550
+
551
+ // checkFrameOrder reports an error if f is an invalid frame to return
552
+ // next from ReadFrame. Mostly it checks whether HEADERS and
553
+ // CONTINUATION frames are contiguous.
554
+ func (fr *Framer) checkFrameOrder(f Frame) error {
555
+ last := fr.lastFrame
556
+ fr.lastFrame = f
557
+ if fr.AllowIllegalReads {
558
+ return nil
559
+ }
560
+
561
+ fh := f.Header()
562
+ if fr.lastHeaderStream != 0 {
563
+ if fh.Type != FrameContinuation {
564
+ return fr.connError(ErrCodeProtocol,
565
+ fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d",
566
+ fh.Type, fh.StreamID,
567
+ last.Header().Type, fr.lastHeaderStream))
568
+ }
569
+ if fh.StreamID != fr.lastHeaderStream {
570
+ return fr.connError(ErrCodeProtocol,
571
+ fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d",
572
+ fh.StreamID, fr.lastHeaderStream))
573
+ }
574
+ } else if fh.Type == FrameContinuation {
575
+ return fr.connError(ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID))
576
+ }
577
+
578
+ switch fh.Type {
579
+ case FrameHeaders, FrameContinuation:
580
+ if fh.Flags.Has(FlagHeadersEndHeaders) {
581
+ fr.lastHeaderStream = 0
582
+ } else {
583
+ fr.lastHeaderStream = fh.StreamID
584
+ }
585
+ }
586
+
587
+ return nil
588
+ }
589
+
590
+ // A DataFrame conveys arbitrary, variable-length sequences of octets
591
+ // associated with a stream.
592
+ // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1
593
+ type DataFrame struct {
594
+ FrameHeader
595
+ data []byte
596
+ }
597
+
598
+ func (f *DataFrame) StreamEnded() bool {
599
+ return f.FrameHeader.Flags.Has(FlagDataEndStream)
600
+ }
601
+
602
+ // Data returns the frame's data octets, not including any padding
603
+ // size byte or padding suffix bytes.
604
+ // The caller must not retain the returned memory past the next
605
+ // call to ReadFrame.
606
+ func (f *DataFrame) Data() []byte {
607
+ f.checkValid()
608
+ return f.data
609
+ }
610
+
611
+ func parseDataFrame(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
612
+ if fh.StreamID == 0 {
613
+ // DATA frames MUST be associated with a stream. If a
614
+ // DATA frame is received whose stream identifier
615
+ // field is 0x0, the recipient MUST respond with a
616
+ // connection error (Section 5.4.1) of type
617
+ // PROTOCOL_ERROR.
618
+ countError("frame_data_stream_0")
619
+ return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"}
620
+ }
621
+ f := fc.getDataFrame()
622
+ f.FrameHeader = fh
623
+
624
+ var padSize byte
625
+ if fh.Flags.Has(FlagDataPadded) {
626
+ var err error
627
+ payload, padSize, err = readByte(payload)
628
+ if err != nil {
629
+ countError("frame_data_pad_byte_short")
630
+ return nil, err
631
+ }
632
+ }
633
+ if int(padSize) > len(payload) {
634
+ // If the length of the padding is greater than the
635
+ // length of the frame payload, the recipient MUST
636
+ // treat this as a connection error.
637
+ // Filed: https://github.com/http2/http2-spec/issues/610
638
+ countError("frame_data_pad_too_big")
639
+ return nil, connError{ErrCodeProtocol, "pad size larger than data payload"}
640
+ }
641
+ f.data = payload[:len(payload)-int(padSize)]
642
+ return f, nil
643
+ }
644
+
645
+ var (
646
+ errStreamID = errors.New("invalid stream ID")
647
+ errDepStreamID = errors.New("invalid dependent stream ID")
648
+ errPadLength = errors.New("pad length too large")
649
+ errPadBytes = errors.New("padding bytes must all be zeros unless AllowIllegalWrites is enabled")
650
+ )
651
+
652
+ func validStreamIDOrZero(streamID uint32) bool {
653
+ return streamID&(1<<31) == 0
654
+ }
655
+
656
+ func validStreamID(streamID uint32) bool {
657
+ return streamID != 0 && streamID&(1<<31) == 0
658
+ }
659
+
660
+ // WriteData writes a DATA frame.
661
+ //
662
+ // It will perform exactly one Write to the underlying Writer.
663
+ // It is the caller's responsibility not to violate the maximum frame size
664
+ // and to not call other Write methods concurrently.
665
+ func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error {
666
+ return f.WriteDataPadded(streamID, endStream, data, nil)
667
+ }
668
+
669
+ // WriteDataPadded writes a DATA frame with optional padding.
670
+ //
671
+ // If pad is nil, the padding bit is not sent.
672
+ // The length of pad must not exceed 255 bytes.
673
+ // The bytes of pad must all be zero, unless f.AllowIllegalWrites is set.
674
+ //
675
+ // It will perform exactly one Write to the underlying Writer.
676
+ // It is the caller's responsibility not to violate the maximum frame size
677
+ // and to not call other Write methods concurrently.
678
+ func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {
679
+ if err := f.startWriteDataPadded(streamID, endStream, data, pad); err != nil {
680
+ return err
681
+ }
682
+ return f.endWrite()
683
+ }
684
+
685
+ // startWriteDataPadded is WriteDataPadded, but only writes the frame to the Framer's internal buffer.
686
+ // The caller should call endWrite to flush the frame to the underlying writer.
687
+ func (f *Framer) startWriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {
688
+ if !validStreamID(streamID) && !f.AllowIllegalWrites {
689
+ return errStreamID
690
+ }
691
+ if len(pad) > 0 {
692
+ if len(pad) > 255 {
693
+ return errPadLength
694
+ }
695
+ if !f.AllowIllegalWrites {
696
+ for _, b := range pad {
697
+ if b != 0 {
698
+ // "Padding octets MUST be set to zero when sending."
699
+ return errPadBytes
700
+ }
701
+ }
702
+ }
703
+ }
704
+ var flags Flags
705
+ if endStream {
706
+ flags |= FlagDataEndStream
707
+ }
708
+ if pad != nil {
709
+ flags |= FlagDataPadded
710
+ }
711
+ f.startWrite(FrameData, flags, streamID)
712
+ if pad != nil {
713
+ f.wbuf = append(f.wbuf, byte(len(pad)))
714
+ }
715
+ f.wbuf = append(f.wbuf, data...)
716
+ f.wbuf = append(f.wbuf, pad...)
717
+ return nil
718
+ }
719
+
720
+ // A SettingsFrame conveys configuration parameters that affect how
721
+ // endpoints communicate, such as preferences and constraints on peer
722
+ // behavior.
723
+ //
724
+ // See https://httpwg.org/specs/rfc7540.html#SETTINGS
725
+ type SettingsFrame struct {
726
+ FrameHeader
727
+ p []byte
728
+ }
729
+
730
+ func parseSettingsFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
731
+ if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 {
732
+ // When this (ACK 0x1) bit is set, the payload of the
733
+ // SETTINGS frame MUST be empty. Receipt of a
734
+ // SETTINGS frame with the ACK flag set and a length
735
+ // field value other than 0 MUST be treated as a
736
+ // connection error (Section 5.4.1) of type
737
+ // FRAME_SIZE_ERROR.
738
+ countError("frame_settings_ack_with_length")
739
+ return nil, ConnectionError(ErrCodeFrameSize)
740
+ }
741
+ if fh.StreamID != 0 {
742
+ // SETTINGS frames always apply to a connection,
743
+ // never a single stream. The stream identifier for a
744
+ // SETTINGS frame MUST be zero (0x0). If an endpoint
745
+ // receives a SETTINGS frame whose stream identifier
746
+ // field is anything other than 0x0, the endpoint MUST
747
+ // respond with a connection error (Section 5.4.1) of
748
+ // type PROTOCOL_ERROR.
749
+ countError("frame_settings_has_stream")
750
+ return nil, ConnectionError(ErrCodeProtocol)
751
+ }
752
+ if len(p)%6 != 0 {
753
+ countError("frame_settings_mod_6")
754
+ // Expecting even number of 6 byte settings.
755
+ return nil, ConnectionError(ErrCodeFrameSize)
756
+ }
757
+ f := &SettingsFrame{FrameHeader: fh, p: p}
758
+ if v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 {
759
+ countError("frame_settings_window_size_too_big")
760
+ // Values above the maximum flow control window size of 2^31 - 1 MUST
761
+ // be treated as a connection error (Section 5.4.1) of type
762
+ // FLOW_CONTROL_ERROR.
763
+ return nil, ConnectionError(ErrCodeFlowControl)
764
+ }
765
+ return f, nil
766
+ }
767
+
768
+ func (f *SettingsFrame) IsAck() bool {
769
+ return f.FrameHeader.Flags.Has(FlagSettingsAck)
770
+ }
771
+
772
+ func (f *SettingsFrame) Value(id SettingID) (v uint32, ok bool) {
773
+ f.checkValid()
774
+ for i := 0; i < f.NumSettings(); i++ {
775
+ if s := f.Setting(i); s.ID == id {
776
+ return s.Val, true
777
+ }
778
+ }
779
+ return 0, false
780
+ }
781
+
782
+ // Setting returns the setting from the frame at the given 0-based index.
783
+ // The index must be >= 0 and less than f.NumSettings().
784
+ func (f *SettingsFrame) Setting(i int) Setting {
785
+ buf := f.p
786
+ return Setting{
787
+ ID: SettingID(binary.BigEndian.Uint16(buf[i*6 : i*6+2])),
788
+ Val: binary.BigEndian.Uint32(buf[i*6+2 : i*6+6]),
789
+ }
790
+ }
791
+
792
+ func (f *SettingsFrame) NumSettings() int { return len(f.p) / 6 }
793
+
794
+ // HasDuplicates reports whether f contains any duplicate setting IDs.
795
+ func (f *SettingsFrame) HasDuplicates() bool {
796
+ num := f.NumSettings()
797
+ if num == 0 {
798
+ return false
799
+ }
800
+ // If it's small enough (the common case), just do the n^2
801
+ // thing and avoid a map allocation.
802
+ if num < 10 {
803
+ for i := 0; i < num; i++ {
804
+ idi := f.Setting(i).ID
805
+ for j := i + 1; j < num; j++ {
806
+ idj := f.Setting(j).ID
807
+ if idi == idj {
808
+ return true
809
+ }
810
+ }
811
+ }
812
+ return false
813
+ }
814
+ seen := map[SettingID]bool{}
815
+ for i := 0; i < num; i++ {
816
+ id := f.Setting(i).ID
817
+ if seen[id] {
818
+ return true
819
+ }
820
+ seen[id] = true
821
+ }
822
+ return false
823
+ }
824
+
825
+ // ForeachSetting runs fn for each setting.
826
+ // It stops and returns the first error.
827
+ func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error {
828
+ f.checkValid()
829
+ for i := 0; i < f.NumSettings(); i++ {
830
+ if err := fn(f.Setting(i)); err != nil {
831
+ return err
832
+ }
833
+ }
834
+ return nil
835
+ }
836
+
837
+ // WriteSettings writes a SETTINGS frame with zero or more settings
838
+ // specified and the ACK bit not set.
839
+ //
840
+ // It will perform exactly one Write to the underlying Writer.
841
+ // It is the caller's responsibility to not call other Write methods concurrently.
842
+ func (f *Framer) WriteSettings(settings ...Setting) error {
843
+ f.startWrite(FrameSettings, 0, 0)
844
+ for _, s := range settings {
845
+ f.writeUint16(uint16(s.ID))
846
+ f.writeUint32(s.Val)
847
+ }
848
+ return f.endWrite()
849
+ }
850
+
851
+ // WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set.
852
+ //
853
+ // It will perform exactly one Write to the underlying Writer.
854
+ // It is the caller's responsibility to not call other Write methods concurrently.
855
+ func (f *Framer) WriteSettingsAck() error {
856
+ f.startWrite(FrameSettings, FlagSettingsAck, 0)
857
+ return f.endWrite()
858
+ }
859
+
860
+ // A PingFrame is a mechanism for measuring a minimal round trip time
861
+ // from the sender, as well as determining whether an idle connection
862
+ // is still functional.
863
+ // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7
864
+ type PingFrame struct {
865
+ FrameHeader
866
+ Data [8]byte
867
+ }
868
+
869
+ func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) }
870
+
871
+ func parsePingFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
872
+ if len(payload) != 8 {
873
+ countError("frame_ping_length")
874
+ return nil, ConnectionError(ErrCodeFrameSize)
875
+ }
876
+ if fh.StreamID != 0 {
877
+ countError("frame_ping_has_stream")
878
+ return nil, ConnectionError(ErrCodeProtocol)
879
+ }
880
+ f := &PingFrame{FrameHeader: fh}
881
+ copy(f.Data[:], payload)
882
+ return f, nil
883
+ }
884
+
885
+ func (f *Framer) WritePing(ack bool, data [8]byte) error {
886
+ var flags Flags
887
+ if ack {
888
+ flags = FlagPingAck
889
+ }
890
+ f.startWrite(FramePing, flags, 0)
891
+ f.writeBytes(data[:])
892
+ return f.endWrite()
893
+ }
894
+
895
+ // A GoAwayFrame informs the remote peer to stop creating streams on this connection.
896
+ // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8
897
+ type GoAwayFrame struct {
898
+ FrameHeader
899
+ LastStreamID uint32
900
+ ErrCode ErrCode
901
+ debugData []byte
902
+ }
903
+
904
+ // DebugData returns any debug data in the GOAWAY frame. Its contents
905
+ // are not defined.
906
+ // The caller must not retain the returned memory past the next
907
+ // call to ReadFrame.
908
+ func (f *GoAwayFrame) DebugData() []byte {
909
+ f.checkValid()
910
+ return f.debugData
911
+ }
912
+
913
+ func parseGoAwayFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
914
+ if fh.StreamID != 0 {
915
+ countError("frame_goaway_has_stream")
916
+ return nil, ConnectionError(ErrCodeProtocol)
917
+ }
918
+ if len(p) < 8 {
919
+ countError("frame_goaway_short")
920
+ return nil, ConnectionError(ErrCodeFrameSize)
921
+ }
922
+ return &GoAwayFrame{
923
+ FrameHeader: fh,
924
+ LastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1),
925
+ ErrCode: ErrCode(binary.BigEndian.Uint32(p[4:8])),
926
+ debugData: p[8:],
927
+ }, nil
928
+ }
929
+
930
+ func (f *Framer) WriteGoAway(maxStreamID uint32, code ErrCode, debugData []byte) error {
931
+ f.startWrite(FrameGoAway, 0, 0)
932
+ f.writeUint32(maxStreamID & (1<<31 - 1))
933
+ f.writeUint32(uint32(code))
934
+ f.writeBytes(debugData)
935
+ return f.endWrite()
936
+ }
937
+
938
+ // An UnknownFrame is the frame type returned when the frame type is unknown
939
+ // or no specific frame type parser exists.
940
+ type UnknownFrame struct {
941
+ FrameHeader
942
+ p []byte
943
+ }
944
+
945
+ // Payload returns the frame's payload (after the header). It is not
946
+ // valid to call this method after a subsequent call to
947
+ // Framer.ReadFrame, nor is it valid to retain the returned slice.
948
+ // The memory is owned by the Framer and is invalidated when the next
949
+ // frame is read.
950
+ func (f *UnknownFrame) Payload() []byte {
951
+ f.checkValid()
952
+ return f.p
953
+ }
954
+
955
+ func parseUnknownFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
956
+ return &UnknownFrame{fh, p}, nil
957
+ }
958
+
959
+ // A WindowUpdateFrame is used to implement flow control.
960
+ // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9
961
+ type WindowUpdateFrame struct {
962
+ FrameHeader
963
+ Increment uint32 // never read with high bit set
964
+ }
965
+
966
+ func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
967
+ if len(p) != 4 {
968
+ countError("frame_windowupdate_bad_len")
969
+ return nil, ConnectionError(ErrCodeFrameSize)
970
+ }
971
+ inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit
972
+ if inc == 0 {
973
+ // A receiver MUST treat the receipt of a
974
+ // WINDOW_UPDATE frame with an flow control window
975
+ // increment of 0 as a stream error (Section 5.4.2) of
976
+ // type PROTOCOL_ERROR; errors on the connection flow
977
+ // control window MUST be treated as a connection
978
+ // error (Section 5.4.1).
979
+ if fh.StreamID == 0 {
980
+ countError("frame_windowupdate_zero_inc_conn")
981
+ return nil, ConnectionError(ErrCodeProtocol)
982
+ }
983
+ countError("frame_windowupdate_zero_inc_stream")
984
+ return nil, streamError(fh.StreamID, ErrCodeProtocol)
985
+ }
986
+ return &WindowUpdateFrame{
987
+ FrameHeader: fh,
988
+ Increment: inc,
989
+ }, nil
990
+ }
991
+
992
+ // WriteWindowUpdate writes a WINDOW_UPDATE frame.
993
+ // The increment value must be between 1 and 2,147,483,647, inclusive.
994
+ // If the Stream ID is zero, the window update applies to the
995
+ // connection as a whole.
996
+ func (f *Framer) WriteWindowUpdate(streamID, incr uint32) error {
997
+ // "The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets."
998
+ if (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites {
999
+ return errors.New("illegal window increment value")
1000
+ }
1001
+ f.startWrite(FrameWindowUpdate, 0, streamID)
1002
+ f.writeUint32(incr)
1003
+ return f.endWrite()
1004
+ }
1005
+
1006
+ // A HeadersFrame is used to open a stream and additionally carries a
1007
+ // header block fragment.
1008
+ type HeadersFrame struct {
1009
+ FrameHeader
1010
+
1011
+ // Priority is set if FlagHeadersPriority is set in the FrameHeader.
1012
+ Priority PriorityParam
1013
+
1014
+ headerFragBuf []byte // not owned
1015
+ }
1016
+
1017
+ func (f *HeadersFrame) HeaderBlockFragment() []byte {
1018
+ f.checkValid()
1019
+ return f.headerFragBuf
1020
+ }
1021
+
1022
+ func (f *HeadersFrame) HeadersEnded() bool {
1023
+ return f.FrameHeader.Flags.Has(FlagHeadersEndHeaders)
1024
+ }
1025
+
1026
+ func (f *HeadersFrame) StreamEnded() bool {
1027
+ return f.FrameHeader.Flags.Has(FlagHeadersEndStream)
1028
+ }
1029
+
1030
+ func (f *HeadersFrame) HasPriority() bool {
1031
+ return f.FrameHeader.Flags.Has(FlagHeadersPriority)
1032
+ }
1033
+
1034
+ func parseHeadersFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) {
1035
+ hf := &HeadersFrame{
1036
+ FrameHeader: fh,
1037
+ }
1038
+ if fh.StreamID == 0 {
1039
+ // HEADERS frames MUST be associated with a stream. If a HEADERS frame
1040
+ // is received whose stream identifier field is 0x0, the recipient MUST
1041
+ // respond with a connection error (Section 5.4.1) of type
1042
+ // PROTOCOL_ERROR.
1043
+ countError("frame_headers_zero_stream")
1044
+ return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"}
1045
+ }
1046
+ var padLength uint8
1047
+ if fh.Flags.Has(FlagHeadersPadded) {
1048
+ if p, padLength, err = readByte(p); err != nil {
1049
+ countError("frame_headers_pad_short")
1050
+ return
1051
+ }
1052
+ }
1053
+ if fh.Flags.Has(FlagHeadersPriority) {
1054
+ var v uint32
1055
+ p, v, err = readUint32(p)
1056
+ if err != nil {
1057
+ countError("frame_headers_prio_short")
1058
+ return nil, err
1059
+ }
1060
+ hf.Priority.StreamDep = v & 0x7fffffff
1061
+ hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set
1062
+ p, hf.Priority.Weight, err = readByte(p)
1063
+ if err != nil {
1064
+ countError("frame_headers_prio_weight_short")
1065
+ return nil, err
1066
+ }
1067
+ }
1068
+ if len(p)-int(padLength) < 0 {
1069
+ countError("frame_headers_pad_too_big")
1070
+ return nil, streamError(fh.StreamID, ErrCodeProtocol)
1071
+ }
1072
+ hf.headerFragBuf = p[:len(p)-int(padLength)]
1073
+ return hf, nil
1074
+ }
1075
+
1076
+ // HeadersFrameParam are the parameters for writing a HEADERS frame.
1077
+ type HeadersFrameParam struct {
1078
+ // StreamID is the required Stream ID to initiate.
1079
+ StreamID uint32
1080
+ // BlockFragment is part (or all) of a Header Block.
1081
+ BlockFragment []byte
1082
+
1083
+ // EndStream indicates that the header block is the last that
1084
+ // the endpoint will send for the identified stream. Setting
1085
+ // this flag causes the stream to enter one of "half closed"
1086
+ // states.
1087
+ EndStream bool
1088
+
1089
+ // EndHeaders indicates that this frame contains an entire
1090
+ // header block and is not followed by any
1091
+ // CONTINUATION frames.
1092
+ EndHeaders bool
1093
+
1094
+ // PadLength is the optional number of bytes of zeros to add
1095
+ // to this frame.
1096
+ PadLength uint8
1097
+
1098
+ // Priority, if non-zero, includes stream priority information
1099
+ // in the HEADER frame.
1100
+ Priority PriorityParam
1101
+ }
1102
+
1103
+ // WriteHeaders writes a single HEADERS frame.
1104
+ //
1105
+ // This is a low-level header writing method. Encoding headers and
1106
+ // splitting them into any necessary CONTINUATION frames is handled
1107
+ // elsewhere.
1108
+ //
1109
+ // It will perform exactly one Write to the underlying Writer.
1110
+ // It is the caller's responsibility to not call other Write methods concurrently.
1111
+ func (f *Framer) WriteHeaders(p HeadersFrameParam) error {
1112
+ if !validStreamID(p.StreamID) && !f.AllowIllegalWrites {
1113
+ return errStreamID
1114
+ }
1115
+ var flags Flags
1116
+ if p.PadLength != 0 {
1117
+ flags |= FlagHeadersPadded
1118
+ }
1119
+ if p.EndStream {
1120
+ flags |= FlagHeadersEndStream
1121
+ }
1122
+ if p.EndHeaders {
1123
+ flags |= FlagHeadersEndHeaders
1124
+ }
1125
+ if !p.Priority.IsZero() {
1126
+ flags |= FlagHeadersPriority
1127
+ }
1128
+ f.startWrite(FrameHeaders, flags, p.StreamID)
1129
+ if p.PadLength != 0 {
1130
+ f.writeByte(p.PadLength)
1131
+ }
1132
+ if !p.Priority.IsZero() {
1133
+ v := p.Priority.StreamDep
1134
+ if !validStreamIDOrZero(v) && !f.AllowIllegalWrites {
1135
+ return errDepStreamID
1136
+ }
1137
+ if p.Priority.Exclusive {
1138
+ v |= 1 << 31
1139
+ }
1140
+ f.writeUint32(v)
1141
+ f.writeByte(p.Priority.Weight)
1142
+ }
1143
+ f.wbuf = append(f.wbuf, p.BlockFragment...)
1144
+ f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)
1145
+ return f.endWrite()
1146
+ }
1147
+
1148
+ // A PriorityFrame specifies the sender-advised priority of a stream.
1149
+ // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3
1150
+ type PriorityFrame struct {
1151
+ FrameHeader
1152
+ PriorityParam
1153
+ }
1154
+
1155
+ // PriorityParam are the stream prioritzation parameters.
1156
+ type PriorityParam struct {
1157
+ // StreamDep is a 31-bit stream identifier for the
1158
+ // stream that this stream depends on. Zero means no
1159
+ // dependency.
1160
+ StreamDep uint32
1161
+
1162
+ // Exclusive is whether the dependency is exclusive.
1163
+ Exclusive bool
1164
+
1165
+ // Weight is the stream's zero-indexed weight. It should be
1166
+ // set together with StreamDep, or neither should be set. Per
1167
+ // the spec, "Add one to the value to obtain a weight between
1168
+ // 1 and 256."
1169
+ Weight uint8
1170
+ }
1171
+
1172
+ func (p PriorityParam) IsZero() bool {
1173
+ return p == PriorityParam{}
1174
+ }
1175
+
1176
+ func parsePriorityFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
1177
+ if fh.StreamID == 0 {
1178
+ countError("frame_priority_zero_stream")
1179
+ return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
1180
+ }
1181
+ if len(payload) != 5 {
1182
+ countError("frame_priority_bad_length")
1183
+ return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))}
1184
+ }
1185
+ v := binary.BigEndian.Uint32(payload[:4])
1186
+ streamID := v & 0x7fffffff // mask off high bit
1187
+ return &PriorityFrame{
1188
+ FrameHeader: fh,
1189
+ PriorityParam: PriorityParam{
1190
+ Weight: payload[4],
1191
+ StreamDep: streamID,
1192
+ Exclusive: streamID != v, // was high bit set?
1193
+ },
1194
+ }, nil
1195
+ }
1196
+
1197
+ // WritePriority writes a PRIORITY frame.
1198
+ //
1199
+ // It will perform exactly one Write to the underlying Writer.
1200
+ // It is the caller's responsibility to not call other Write methods concurrently.
1201
+ func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error {
1202
+ if !validStreamID(streamID) && !f.AllowIllegalWrites {
1203
+ return errStreamID
1204
+ }
1205
+ if !validStreamIDOrZero(p.StreamDep) {
1206
+ return errDepStreamID
1207
+ }
1208
+ f.startWrite(FramePriority, 0, streamID)
1209
+ v := p.StreamDep
1210
+ if p.Exclusive {
1211
+ v |= 1 << 31
1212
+ }
1213
+ f.writeUint32(v)
1214
+ f.writeByte(p.Weight)
1215
+ return f.endWrite()
1216
+ }
1217
+
1218
+ // A RSTStreamFrame allows for abnormal termination of a stream.
1219
+ // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4
1220
+ type RSTStreamFrame struct {
1221
+ FrameHeader
1222
+ ErrCode ErrCode
1223
+ }
1224
+
1225
+ func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
1226
+ if len(p) != 4 {
1227
+ countError("frame_rststream_bad_len")
1228
+ return nil, ConnectionError(ErrCodeFrameSize)
1229
+ }
1230
+ if fh.StreamID == 0 {
1231
+ countError("frame_rststream_zero_stream")
1232
+ return nil, ConnectionError(ErrCodeProtocol)
1233
+ }
1234
+ return &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil
1235
+ }
1236
+
1237
+ // WriteRSTStream writes a RST_STREAM frame.
1238
+ //
1239
+ // It will perform exactly one Write to the underlying Writer.
1240
+ // It is the caller's responsibility to not call other Write methods concurrently.
1241
+ func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error {
1242
+ if !validStreamID(streamID) && !f.AllowIllegalWrites {
1243
+ return errStreamID
1244
+ }
1245
+ f.startWrite(FrameRSTStream, 0, streamID)
1246
+ f.writeUint32(uint32(code))
1247
+ return f.endWrite()
1248
+ }
1249
+
1250
+ // A ContinuationFrame is used to continue a sequence of header block fragments.
1251
+ // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10
1252
+ type ContinuationFrame struct {
1253
+ FrameHeader
1254
+ headerFragBuf []byte
1255
+ }
1256
+
1257
+ func parseContinuationFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
1258
+ if fh.StreamID == 0 {
1259
+ countError("frame_continuation_zero_stream")
1260
+ return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"}
1261
+ }
1262
+ return &ContinuationFrame{fh, p}, nil
1263
+ }
1264
+
1265
+ func (f *ContinuationFrame) HeaderBlockFragment() []byte {
1266
+ f.checkValid()
1267
+ return f.headerFragBuf
1268
+ }
1269
+
1270
+ func (f *ContinuationFrame) HeadersEnded() bool {
1271
+ return f.FrameHeader.Flags.Has(FlagContinuationEndHeaders)
1272
+ }
1273
+
1274
+ // WriteContinuation writes a CONTINUATION frame.
1275
+ //
1276
+ // It will perform exactly one Write to the underlying Writer.
1277
+ // It is the caller's responsibility to not call other Write methods concurrently.
1278
+ func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error {
1279
+ if !validStreamID(streamID) && !f.AllowIllegalWrites {
1280
+ return errStreamID
1281
+ }
1282
+ var flags Flags
1283
+ if endHeaders {
1284
+ flags |= FlagContinuationEndHeaders
1285
+ }
1286
+ f.startWrite(FrameContinuation, flags, streamID)
1287
+ f.wbuf = append(f.wbuf, headerBlockFragment...)
1288
+ return f.endWrite()
1289
+ }
1290
+
1291
+ // A PushPromiseFrame is used to initiate a server stream.
1292
+ // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6
1293
+ type PushPromiseFrame struct {
1294
+ FrameHeader
1295
+ PromiseID uint32
1296
+ headerFragBuf []byte // not owned
1297
+ }
1298
+
1299
+ func (f *PushPromiseFrame) HeaderBlockFragment() []byte {
1300
+ f.checkValid()
1301
+ return f.headerFragBuf
1302
+ }
1303
+
1304
+ func (f *PushPromiseFrame) HeadersEnded() bool {
1305
+ return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders)
1306
+ }
1307
+
1308
+ func parsePushPromise(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) {
1309
+ pp := &PushPromiseFrame{
1310
+ FrameHeader: fh,
1311
+ }
1312
+ if pp.StreamID == 0 {
1313
+ // PUSH_PROMISE frames MUST be associated with an existing,
1314
+ // peer-initiated stream. The stream identifier of a
1315
+ // PUSH_PROMISE frame indicates the stream it is associated
1316
+ // with. If the stream identifier field specifies the value
1317
+ // 0x0, a recipient MUST respond with a connection error
1318
+ // (Section 5.4.1) of type PROTOCOL_ERROR.
1319
+ countError("frame_pushpromise_zero_stream")
1320
+ return nil, ConnectionError(ErrCodeProtocol)
1321
+ }
1322
+ // The PUSH_PROMISE frame includes optional padding.
1323
+ // Padding fields and flags are identical to those defined for DATA frames
1324
+ var padLength uint8
1325
+ if fh.Flags.Has(FlagPushPromisePadded) {
1326
+ if p, padLength, err = readByte(p); err != nil {
1327
+ countError("frame_pushpromise_pad_short")
1328
+ return
1329
+ }
1330
+ }
1331
+
1332
+ p, pp.PromiseID, err = readUint32(p)
1333
+ if err != nil {
1334
+ countError("frame_pushpromise_promiseid_short")
1335
+ return
1336
+ }
1337
+ pp.PromiseID = pp.PromiseID & (1<<31 - 1)
1338
+
1339
+ if int(padLength) > len(p) {
1340
+ // like the DATA frame, error out if padding is longer than the body.
1341
+ countError("frame_pushpromise_pad_too_big")
1342
+ return nil, ConnectionError(ErrCodeProtocol)
1343
+ }
1344
+ pp.headerFragBuf = p[:len(p)-int(padLength)]
1345
+ return pp, nil
1346
+ }
1347
+
1348
+ // PushPromiseParam are the parameters for writing a PUSH_PROMISE frame.
1349
+ type PushPromiseParam struct {
1350
+ // StreamID is the required Stream ID to initiate.
1351
+ StreamID uint32
1352
+
1353
+ // PromiseID is the required Stream ID which this
1354
+ // Push Promises
1355
+ PromiseID uint32
1356
+
1357
+ // BlockFragment is part (or all) of a Header Block.
1358
+ BlockFragment []byte
1359
+
1360
+ // EndHeaders indicates that this frame contains an entire
1361
+ // header block and is not followed by any
1362
+ // CONTINUATION frames.
1363
+ EndHeaders bool
1364
+
1365
+ // PadLength is the optional number of bytes of zeros to add
1366
+ // to this frame.
1367
+ PadLength uint8
1368
+ }
1369
+
1370
+ // WritePushPromise writes a single PushPromise Frame.
1371
+ //
1372
+ // As with Header Frames, This is the low level call for writing
1373
+ // individual frames. Continuation frames are handled elsewhere.
1374
+ //
1375
+ // It will perform exactly one Write to the underlying Writer.
1376
+ // It is the caller's responsibility to not call other Write methods concurrently.
1377
+ func (f *Framer) WritePushPromise(p PushPromiseParam) error {
1378
+ if !validStreamID(p.StreamID) && !f.AllowIllegalWrites {
1379
+ return errStreamID
1380
+ }
1381
+ var flags Flags
1382
+ if p.PadLength != 0 {
1383
+ flags |= FlagPushPromisePadded
1384
+ }
1385
+ if p.EndHeaders {
1386
+ flags |= FlagPushPromiseEndHeaders
1387
+ }
1388
+ f.startWrite(FramePushPromise, flags, p.StreamID)
1389
+ if p.PadLength != 0 {
1390
+ f.writeByte(p.PadLength)
1391
+ }
1392
+ if !validStreamID(p.PromiseID) && !f.AllowIllegalWrites {
1393
+ return errStreamID
1394
+ }
1395
+ f.writeUint32(p.PromiseID)
1396
+ f.wbuf = append(f.wbuf, p.BlockFragment...)
1397
+ f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)
1398
+ return f.endWrite()
1399
+ }
1400
+
1401
+ // WriteRawFrame writes a raw frame. This can be used to write
1402
+ // extension frames unknown to this package.
1403
+ func (f *Framer) WriteRawFrame(t FrameType, flags Flags, streamID uint32, payload []byte) error {
1404
+ f.startWrite(t, flags, streamID)
1405
+ f.writeBytes(payload)
1406
+ return f.endWrite()
1407
+ }
1408
+
1409
+ func readByte(p []byte) (remain []byte, b byte, err error) {
1410
+ if len(p) == 0 {
1411
+ return nil, 0, io.ErrUnexpectedEOF
1412
+ }
1413
+ return p[1:], p[0], nil
1414
+ }
1415
+
1416
+ func readUint32(p []byte) (remain []byte, v uint32, err error) {
1417
+ if len(p) < 4 {
1418
+ return nil, 0, io.ErrUnexpectedEOF
1419
+ }
1420
+ return p[4:], binary.BigEndian.Uint32(p[:4]), nil
1421
+ }
1422
+
1423
+ type streamEnder interface {
1424
+ StreamEnded() bool
1425
+ }
1426
+
1427
+ type headersEnder interface {
1428
+ HeadersEnded() bool
1429
+ }
1430
+
1431
+ type headersOrContinuation interface {
1432
+ headersEnder
1433
+ HeaderBlockFragment() []byte
1434
+ }
1435
+
1436
+ // A MetaHeadersFrame is the representation of one HEADERS frame and
1437
+ // zero or more contiguous CONTINUATION frames and the decoding of
1438
+ // their HPACK-encoded contents.
1439
+ //
1440
+ // This type of frame does not appear on the wire and is only returned
1441
+ // by the Framer when Framer.ReadMetaHeaders is set.
1442
+ type MetaHeadersFrame struct {
1443
+ *HeadersFrame
1444
+
1445
+ // Fields are the fields contained in the HEADERS and
1446
+ // CONTINUATION frames. The underlying slice is owned by the
1447
+ // Framer and must not be retained after the next call to
1448
+ // ReadFrame.
1449
+ //
1450
+ // Fields are guaranteed to be in the correct http2 order and
1451
+ // not have unknown pseudo header fields or invalid header
1452
+ // field names or values. Required pseudo header fields may be
1453
+ // missing, however. Use the MetaHeadersFrame.Pseudo accessor
1454
+ // method access pseudo headers.
1455
+ Fields []hpack.HeaderField
1456
+
1457
+ // Truncated is whether the max header list size limit was hit
1458
+ // and Fields is incomplete. The hpack decoder state is still
1459
+ // valid, however.
1460
+ Truncated bool
1461
+ }
1462
+
1463
+ // PseudoValue returns the given pseudo header field's value.
1464
+ // The provided pseudo field should not contain the leading colon.
1465
+ func (mh *MetaHeadersFrame) PseudoValue(pseudo string) string {
1466
+ for _, hf := range mh.Fields {
1467
+ if !hf.IsPseudo() {
1468
+ return ""
1469
+ }
1470
+ if hf.Name[1:] == pseudo {
1471
+ return hf.Value
1472
+ }
1473
+ }
1474
+ return ""
1475
+ }
1476
+
1477
+ // RegularFields returns the regular (non-pseudo) header fields of mh.
1478
+ // The caller does not own the returned slice.
1479
+ func (mh *MetaHeadersFrame) RegularFields() []hpack.HeaderField {
1480
+ for i, hf := range mh.Fields {
1481
+ if !hf.IsPseudo() {
1482
+ return mh.Fields[i:]
1483
+ }
1484
+ }
1485
+ return nil
1486
+ }
1487
+
1488
+ // PseudoFields returns the pseudo header fields of mh.
1489
+ // The caller does not own the returned slice.
1490
+ func (mh *MetaHeadersFrame) PseudoFields() []hpack.HeaderField {
1491
+ for i, hf := range mh.Fields {
1492
+ if !hf.IsPseudo() {
1493
+ return mh.Fields[:i]
1494
+ }
1495
+ }
1496
+ return mh.Fields
1497
+ }
1498
+
1499
+ func (mh *MetaHeadersFrame) checkPseudos() error {
1500
+ var isRequest, isResponse bool
1501
+ pf := mh.PseudoFields()
1502
+ for i, hf := range pf {
1503
+ switch hf.Name {
1504
+ case ":method", ":path", ":scheme", ":authority", ":protocol":
1505
+ isRequest = true
1506
+ case ":status":
1507
+ isResponse = true
1508
+ default:
1509
+ return pseudoHeaderError(hf.Name)
1510
+ }
1511
+ // Check for duplicates.
1512
+ // This would be a bad algorithm, but N is 5.
1513
+ // And this doesn't allocate.
1514
+ for _, hf2 := range pf[:i] {
1515
+ if hf.Name == hf2.Name {
1516
+ return duplicatePseudoHeaderError(hf.Name)
1517
+ }
1518
+ }
1519
+ }
1520
+ if isRequest && isResponse {
1521
+ return errMixPseudoHeaderTypes
1522
+ }
1523
+ return nil
1524
+ }
1525
+
1526
+ func (fr *Framer) maxHeaderStringLen() int {
1527
+ v := int(fr.maxHeaderListSize())
1528
+ if v < 0 {
1529
+ // If maxHeaderListSize overflows an int, use no limit (0).
1530
+ return 0
1531
+ }
1532
+ return v
1533
+ }
1534
+
1535
+ // readMetaFrame returns 0 or more CONTINUATION frames from fr and
1536
+ // merge them into the provided hf and returns a MetaHeadersFrame
1537
+ // with the decoded hpack values.
1538
+ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (Frame, error) {
1539
+ if fr.AllowIllegalReads {
1540
+ return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders")
1541
+ }
1542
+ mh := &MetaHeadersFrame{
1543
+ HeadersFrame: hf,
1544
+ }
1545
+ var remainSize = fr.maxHeaderListSize()
1546
+ var sawRegular bool
1547
+
1548
+ var invalid error // pseudo header field errors
1549
+ hdec := fr.ReadMetaHeaders
1550
+ hdec.SetEmitEnabled(true)
1551
+ hdec.SetMaxStringLength(fr.maxHeaderStringLen())
1552
+ hdec.SetEmitFunc(func(hf hpack.HeaderField) {
1553
+ if VerboseLogs && fr.logReads {
1554
+ fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
1555
+ }
1556
+ if !httpguts.ValidHeaderFieldValue(hf.Value) {
1557
+ // Don't include the value in the error, because it may be sensitive.
1558
+ invalid = headerFieldValueError(hf.Name)
1559
+ }
1560
+ isPseudo := strings.HasPrefix(hf.Name, ":")
1561
+ if isPseudo {
1562
+ if sawRegular {
1563
+ invalid = errPseudoAfterRegular
1564
+ }
1565
+ } else {
1566
+ sawRegular = true
1567
+ if !validWireHeaderFieldName(hf.Name) {
1568
+ invalid = headerFieldNameError(hf.Name)
1569
+ }
1570
+ }
1571
+
1572
+ if invalid != nil {
1573
+ hdec.SetEmitEnabled(false)
1574
+ return
1575
+ }
1576
+
1577
+ size := hf.Size()
1578
+ if size > remainSize {
1579
+ hdec.SetEmitEnabled(false)
1580
+ mh.Truncated = true
1581
+ remainSize = 0
1582
+ return
1583
+ }
1584
+ remainSize -= size
1585
+
1586
+ mh.Fields = append(mh.Fields, hf)
1587
+ })
1588
+ // Lose reference to MetaHeadersFrame:
1589
+ defer hdec.SetEmitFunc(func(hf hpack.HeaderField) {})
1590
+
1591
+ var hc headersOrContinuation = hf
1592
+ for {
1593
+ frag := hc.HeaderBlockFragment()
1594
+
1595
+ // Avoid parsing large amounts of headers that we will then discard.
1596
+ // If the sender exceeds the max header list size by too much,
1597
+ // skip parsing the fragment and close the connection.
1598
+ //
1599
+ // "Too much" is either any CONTINUATION frame after we've already
1600
+ // exceeded the max header list size (in which case remainSize is 0),
1601
+ // or a frame whose encoded size is more than twice the remaining
1602
+ // header list bytes we're willing to accept.
1603
+ if int64(len(frag)) > int64(2*remainSize) {
1604
+ if VerboseLogs {
1605
+ log.Printf("http2: header list too large")
1606
+ }
1607
+ // It would be nice to send a RST_STREAM before sending the GOAWAY,
1608
+ // but the structure of the server's frame writer makes this difficult.
1609
+ return mh, ConnectionError(ErrCodeProtocol)
1610
+ }
1611
+
1612
+ // Also close the connection after any CONTINUATION frame following an
1613
+ // invalid header, since we stop tracking the size of the headers after
1614
+ // an invalid one.
1615
+ if invalid != nil {
1616
+ if VerboseLogs {
1617
+ log.Printf("http2: invalid header: %v", invalid)
1618
+ }
1619
+ // It would be nice to send a RST_STREAM before sending the GOAWAY,
1620
+ // but the structure of the server's frame writer makes this difficult.
1621
+ return mh, ConnectionError(ErrCodeProtocol)
1622
+ }
1623
+
1624
+ if _, err := hdec.Write(frag); err != nil {
1625
+ return mh, ConnectionError(ErrCodeCompression)
1626
+ }
1627
+
1628
+ if hc.HeadersEnded() {
1629
+ break
1630
+ }
1631
+ if f, err := fr.ReadFrame(); err != nil {
1632
+ return nil, err
1633
+ } else {
1634
+ hc = f.(*ContinuationFrame) // guaranteed by checkFrameOrder
1635
+ }
1636
+ }
1637
+
1638
+ mh.HeadersFrame.headerFragBuf = nil
1639
+ mh.HeadersFrame.invalidate()
1640
+
1641
+ if err := hdec.Close(); err != nil {
1642
+ return mh, ConnectionError(ErrCodeCompression)
1643
+ }
1644
+ if invalid != nil {
1645
+ fr.errDetail = invalid
1646
+ if VerboseLogs {
1647
+ log.Printf("http2: invalid header: %v", invalid)
1648
+ }
1649
+ return nil, StreamError{mh.StreamID, ErrCodeProtocol, invalid}
1650
+ }
1651
+ if err := mh.checkPseudos(); err != nil {
1652
+ fr.errDetail = err
1653
+ if VerboseLogs {
1654
+ log.Printf("http2: invalid pseudo headers: %v", err)
1655
+ }
1656
+ return nil, StreamError{mh.StreamID, ErrCodeProtocol, err}
1657
+ }
1658
+ return mh, nil
1659
+ }
1660
+
1661
+ func summarizeFrame(f Frame) string {
1662
+ var buf bytes.Buffer
1663
+ f.Header().writeDebug(&buf)
1664
+ switch f := f.(type) {
1665
+ case *SettingsFrame:
1666
+ n := 0
1667
+ f.ForeachSetting(func(s Setting) error {
1668
+ n++
1669
+ if n == 1 {
1670
+ buf.WriteString(", settings:")
1671
+ }
1672
+ fmt.Fprintf(&buf, " %v=%v,", s.ID, s.Val)
1673
+ return nil
1674
+ })
1675
+ if n > 0 {
1676
+ buf.Truncate(buf.Len() - 1) // remove trailing comma
1677
+ }
1678
+ case *DataFrame:
1679
+ data := f.Data()
1680
+ const max = 256
1681
+ if len(data) > max {
1682
+ data = data[:max]
1683
+ }
1684
+ fmt.Fprintf(&buf, " data=%q", data)
1685
+ if len(f.Data()) > max {
1686
+ fmt.Fprintf(&buf, " (%d bytes omitted)", len(f.Data())-max)
1687
+ }
1688
+ case *WindowUpdateFrame:
1689
+ if f.StreamID == 0 {
1690
+ buf.WriteString(" (conn)")
1691
+ }
1692
+ fmt.Fprintf(&buf, " incr=%v", f.Increment)
1693
+ case *PingFrame:
1694
+ fmt.Fprintf(&buf, " ping=%q", f.Data[:])
1695
+ case *GoAwayFrame:
1696
+ fmt.Fprintf(&buf, " LastStreamID=%v ErrCode=%v Debug=%q",
1697
+ f.LastStreamID, f.ErrCode, f.debugData)
1698
+ case *RSTStreamFrame:
1699
+ fmt.Fprintf(&buf, " ErrCode=%v", f.ErrCode)
1700
+ }
1701
+ return buf.String()
1702
+ }