tdiary 5.5.1 → 5.6.0

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.
Files changed (175) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +2 -0
  3. data/Gemfile +2 -1
  4. data/Gemfile.lock +37 -37
  5. data/doc/UPGRADE.md +1 -1
  6. data/lib/tdiary/admin.rb +11 -13
  7. data/lib/tdiary/application.rb +2 -7
  8. data/lib/tdiary/author_only_base.rb +78 -9
  9. data/lib/tdiary/base.rb +2 -2
  10. data/lib/tdiary/cgi_adapter.rb +7 -5
  11. data/lib/tdiary/cgi_compat.rb +27 -97
  12. data/lib/tdiary/configuration.rb +4 -0
  13. data/lib/tdiary/core_ext.rb +146 -1
  14. data/lib/tdiary/dispatcher/index_main.rb +5 -23
  15. data/lib/tdiary/dispatcher/update_main.rb +2 -17
  16. data/lib/tdiary/dispatcher.rb +29 -15
  17. data/lib/tdiary/filter/default.rb +2 -2
  18. data/lib/tdiary/filter/spam.rb +2 -2
  19. data/lib/tdiary/filter.rb +1 -1
  20. data/lib/tdiary/plugin/00default.rb +18 -3
  21. data/lib/tdiary/plugin/en/00default.rb +15 -0
  22. data/lib/tdiary/plugin/ja/00default.rb +15 -0
  23. data/lib/tdiary/plugin.rb +1 -1
  24. data/lib/tdiary/rack/error_handler.rb +36 -0
  25. data/lib/tdiary/rack.rb +1 -0
  26. data/lib/tdiary/request.rb +3 -2
  27. data/lib/tdiary/server.rb +25 -3
  28. data/lib/tdiary/version.rb +1 -1
  29. data/lib/tdiary/view.rb +33 -28
  30. data/lib/tdiary/view_helper.rb +10 -2
  31. data/lib/tdiary.rb +6 -1
  32. data/misc/plugin/image.rb +1 -1
  33. data/misc/plugin/makerss.rb +3 -3
  34. data/tdiary.conf.sample +8 -0
  35. data/tdiary.conf.sample-en +8 -0
  36. data/vendor/bundle/ruby/3.4.0/cache/net-imap-0.6.6.gem +0 -0
  37. data/vendor/bundle/ruby/3.4.0/cache/net-protocol-0.3.0.gem +0 -0
  38. data/vendor/bundle/ruby/3.4.0/cache/rack-3.2.7.gem +0 -0
  39. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/cgi-0.5.2/gem_make.out +5 -5
  40. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.5.1/gem_make.out +5 -5
  41. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/Gemfile +3 -4
  42. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/README.md +1 -1
  43. data/vendor/bundle/ruby/3.4.0/gems/net-imap-0.6.6/Rakefile +24 -0
  44. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/command_data.rb +62 -92
  45. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/config/attr_accessors.rb +8 -9
  46. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/config/attr_inheritance.rb +64 -1
  47. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/config/attr_version_defaults.rb +1 -4
  48. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/config.rb +209 -35
  49. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/connection_state.rb +1 -1
  50. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/data_encoding.rb +127 -27
  51. data/vendor/bundle/ruby/3.4.0/gems/net-imap-0.6.6/lib/net/imap/errors.rb +372 -0
  52. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/esearch_result.rb +6 -0
  53. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/response_data.rb +90 -11
  54. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/response_parser/parser_utils.rb +14 -23
  55. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/response_parser.rb +41 -26
  56. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/response_reader.rb +16 -21
  57. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/scram_authenticator.rb +3 -3
  58. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/search_result.rb +11 -1
  59. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sequence_set.rb +620 -312
  60. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/uidplus_data.rb +2 -63
  61. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap.rb +279 -162
  62. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/net-imap.gemspec +1 -1
  63. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/rakelib/rdoc.rake +1 -18
  64. data/vendor/bundle/ruby/3.4.0/gems/{net-protocol-0.2.2/LICENSE.txt → net-protocol-0.3.0/BSDL} +3 -3
  65. data/vendor/bundle/ruby/3.4.0/gems/net-protocol-0.3.0/COPYING +56 -0
  66. data/vendor/bundle/ruby/3.4.0/gems/{net-protocol-0.2.2 → net-protocol-0.3.0}/lib/net/protocol.rb +58 -4
  67. data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/CHANGELOG.md +54 -1
  68. data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/utils.rb +3 -3
  69. data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/version.rb +1 -1
  70. data/vendor/bundle/ruby/3.4.0/specifications/{net-imap-0.5.15.gemspec → net-imap-0.6.6.gemspec} +4 -4
  71. data/vendor/bundle/ruby/3.4.0/specifications/{net-protocol-0.2.2.gemspec → net-protocol-0.3.0.gemspec} +5 -5
  72. data/vendor/bundle/ruby/3.4.0/specifications/{rack-3.2.6.gemspec → rack-3.2.7.gemspec} +3 -3
  73. data/views/tdiary.rconf +2 -0
  74. metadata +127 -131
  75. data/vendor/bundle/ruby/3.4.0/cache/net-imap-0.5.15.gem +0 -0
  76. data/vendor/bundle/ruby/3.4.0/cache/net-protocol-0.2.2.gem +0 -0
  77. data/vendor/bundle/ruby/3.4.0/cache/rack-3.2.6.gem +0 -0
  78. data/vendor/bundle/ruby/3.4.0/gems/net-imap-0.5.15/Rakefile +0 -13
  79. data/vendor/bundle/ruby/3.4.0/gems/net-imap-0.5.15/lib/net/imap/data_lite.rb +0 -226
  80. data/vendor/bundle/ruby/3.4.0/gems/net-imap-0.5.15/lib/net/imap/errors.rb +0 -118
  81. data/vendor/bundle/ruby/3.4.0/gems/net-protocol-0.2.2/Gemfile +0 -7
  82. data/vendor/bundle/ruby/3.4.0/gems/net-protocol-0.2.2/Rakefile +0 -10
  83. data/vendor/bundle/ruby/3.4.0/gems/net-protocol-0.2.2/bin/console +0 -14
  84. data/vendor/bundle/ruby/3.4.0/gems/net-protocol-0.2.2/bin/setup +0 -8
  85. data/vendor/bundle/ruby/3.4.0/gems/net-protocol-0.2.2/net-protocol.gemspec +0 -33
  86. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/BSDL +0 -0
  87. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/COPYING +0 -0
  88. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/LICENSE.txt +0 -0
  89. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/docs/styles.css +0 -0
  90. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/authenticators.rb +0 -0
  91. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/config/attr_type_coercion.rb +0 -0
  92. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/deprecated_client_options.rb +0 -0
  93. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/fetch_data.rb +0 -0
  94. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/flags.rb +0 -0
  95. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/anonymous_authenticator.rb +0 -0
  96. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/authentication_exchange.rb +0 -0
  97. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/authenticators.rb +0 -0
  98. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/client_adapter.rb +0 -0
  99. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/cram_md5_authenticator.rb +0 -0
  100. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/digest_md5_authenticator.rb +0 -0
  101. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/external_authenticator.rb +0 -0
  102. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/gs2_header.rb +0 -0
  103. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/login_authenticator.rb +0 -0
  104. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/oauthbearer_authenticator.rb +0 -0
  105. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/plain_authenticator.rb +0 -0
  106. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/protocol_adapters.rb +0 -0
  107. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/scram_algorithm.rb +0 -0
  108. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/stringprep.rb +0 -0
  109. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/xoauth2_authenticator.rb +0 -0
  110. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl.rb +0 -0
  111. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl_adapter.rb +0 -0
  112. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/stringprep/nameprep.rb +0 -0
  113. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/stringprep/saslprep.rb +0 -0
  114. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/stringprep/saslprep_tables.rb +0 -0
  115. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/stringprep/tables.rb +0 -0
  116. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/stringprep/trace.rb +0 -0
  117. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/stringprep.rb +0 -0
  118. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/vanished_data.rb +0 -0
  119. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/rakelib/benchmarks.rake +0 -0
  120. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/rakelib/rfcs.rake +0 -0
  121. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/rakelib/saslprep.rake +0 -0
  122. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/rakelib/string_prep_tables_generator.rb +0 -0
  123. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/sample/net-imap.rb +0 -0
  124. /data/vendor/bundle/ruby/3.4.0/gems/{net-protocol-0.2.2 → net-protocol-0.3.0}/README.md +0 -0
  125. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/CONTRIBUTING.md +0 -0
  126. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/MIT-LICENSE +0 -0
  127. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/README.md +0 -0
  128. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/SPEC.rdoc +0 -0
  129. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/auth/abstract/handler.rb +0 -0
  130. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/auth/abstract/request.rb +0 -0
  131. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/auth/basic.rb +0 -0
  132. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/bad_request.rb +0 -0
  133. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/body_proxy.rb +0 -0
  134. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/builder.rb +0 -0
  135. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/cascade.rb +0 -0
  136. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/common_logger.rb +0 -0
  137. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/conditional_get.rb +0 -0
  138. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/config.rb +0 -0
  139. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/constants.rb +0 -0
  140. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/content_length.rb +0 -0
  141. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/content_type.rb +0 -0
  142. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/deflater.rb +0 -0
  143. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/directory.rb +0 -0
  144. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/etag.rb +0 -0
  145. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/events.rb +0 -0
  146. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/files.rb +0 -0
  147. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/head.rb +0 -0
  148. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/headers.rb +0 -0
  149. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/lint.rb +0 -0
  150. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/lock.rb +0 -0
  151. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/media_type.rb +0 -0
  152. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/method_override.rb +0 -0
  153. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/mime.rb +0 -0
  154. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/mock.rb +0 -0
  155. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/mock_request.rb +0 -0
  156. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/mock_response.rb +0 -0
  157. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/multipart/generator.rb +0 -0
  158. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/multipart/parser.rb +0 -0
  159. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/multipart/uploaded_file.rb +0 -0
  160. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/multipart.rb +0 -0
  161. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/null_logger.rb +0 -0
  162. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/query_parser.rb +0 -0
  163. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/recursive.rb +0 -0
  164. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/reloader.rb +0 -0
  165. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/request.rb +0 -0
  166. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/response.rb +0 -0
  167. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/rewindable_input.rb +0 -0
  168. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/runtime.rb +0 -0
  169. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/sendfile.rb +0 -0
  170. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/show_exceptions.rb +0 -0
  171. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/show_status.rb +0 -0
  172. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/static.rb +0 -0
  173. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/tempfile_reaper.rb +0 -0
  174. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/urlmap.rb +0 -0
  175. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack.rb +0 -0
@@ -1,6 +1,9 @@
1
1
  require 'emot'
2
2
 
3
3
  module TDiary
4
+ # CGI-semantics readers shared by TDiary::Request and the CGICompat
5
+ # facade (which forwards env to the request it wraps, so state memoized
6
+ # in the env is visible through either object).
4
7
  module RequestExtension
5
8
  # backward compatibility, returns NOT mobile phone always
6
9
  def mobile_agent?
@@ -11,6 +14,147 @@ module TDiary
11
14
  def smartphone?
12
15
  false
13
16
  end
17
+
18
+ # true when the endpoint runs behind a web server (CGI/FCGI hosting,
19
+ # which sets tdiary.static_assets in the env) that serves the js/ and
20
+ # theme/ directories itself; false on the Rack path, where
21
+ # TDiary::Application serves them under assets/
22
+ def static_assets?
23
+ env['tdiary.static_assets'] ? true : false
24
+ end
25
+
26
+ # params with CGI semantics, unlike Rack::Request#params: POST reads
27
+ # only the body, every value is an Array, unknown keys yield [],
28
+ # duplicated keys collect all values, broken UTF-8 input is retried
29
+ # as Shift_JIS and multipart uploads are normalized to their
30
+ # tempfiles. Memoized so the request and its CGICompat facade (which
31
+ # delegates here) share one Hash; plugins mutate it through
32
+ # @cgi.params.
33
+ def cgi_params
34
+ @cgi_params ||= build_cgi_params
35
+ end
36
+
37
+ # single-value accessor over cgi_params; nil when the key is absent
38
+ def param( key, idx = 0 )
39
+ cgi_params[key][idx]
40
+ end
41
+
42
+ def valid?( param, idx = 0 )
43
+ cgi_params[param] and cgi_params[param][idx] and cgi_params[param][idx].length > 0
44
+ end
45
+
46
+ # multi-value cookies, unlike Rack::Request#cookies: CGI::Cookie
47
+ # splits each value on '&' (the tdiary cookie carries 'name&mail')
48
+ def cgi_cookies
49
+ @cgi_cookies ||= CGI::Cookie.parse( env['HTTP_COOKIE'] )
50
+ end
51
+
52
+ # TDiaryView hides the referer for the rest of the request when the
53
+ # referer filters reject it; plugins observe nil through the @cgi
54
+ # facade too, which delegates both methods to the request
55
+ def hide_referer!
56
+ @referer_hidden = true
57
+ end
58
+
59
+ def referer
60
+ @referer_hidden ? nil : env['HTTP_REFERER']
61
+ end
62
+
63
+ def remote_addr
64
+ env['REMOTE_ADDR']
65
+ end
66
+
67
+ def remote_user
68
+ env['REMOTE_USER']
69
+ end
70
+
71
+ def https?
72
+ return true if env['HTTP_X_FORWARDED_PROTO'] == 'https'
73
+ return false if env['HTTPS'].nil? or /off/i =~ env['HTTPS'] or env['HTTPS'] == ''
74
+ true
75
+ end
76
+
77
+ # not Rack::Request#base_url (scheme and host only): the CGI flavour
78
+ # with the SCRIPT_NAME dirname and a trailing '/'
79
+ def tdiary_base_url
80
+ script_name = env['SCRIPT_NAME']
81
+ return '' unless script_name
82
+ begin
83
+ script_dirname = script_name.empty? ? '' : File::dirname( script_name )
84
+ server_name = env['SERVER_NAME']
85
+ server_port = env['SERVER_PORT'].to_i
86
+ if https?
87
+ port = (server_port == 443) ? '' : ':' + server_port.to_s
88
+ "https://#{server_name}#{port}#{script_dirname}/"
89
+ else
90
+ port = (server_port == 80) ? '' : ':' + server_port.to_s
91
+ "http://#{server_name}#{port}#{script_dirname}/"
92
+ end.sub(%r|/+$|, '/')
93
+ rescue SecurityError
94
+ ''
95
+ end
96
+ end
97
+
98
+ private
99
+
100
+ def build_cgi_params
101
+ source =
102
+ if env['REQUEST_METHOD'] == 'POST'
103
+ if %r|\Amultipart/form-data|.match?( env['CONTENT_TYPE'].to_s )
104
+ self.POST
105
+ else
106
+ # Rack's nested query parser behind Rack::Request#POST keeps
107
+ # only the last of duplicated keys; CGI collects all of them.
108
+ # CGI also splits on ';' as well as '&', and tDiary's own edit
109
+ # links (00default.rb, edit_today.rb) still use ';'
110
+ ::Rack::Utils.parse_query( read_raw_body, '&;' )
111
+ end
112
+ else
113
+ ::Rack::Utils.parse_query( env['QUERY_STRING'].to_s, '&;' )
114
+ end
115
+
116
+ params = {}
117
+ source.each do |key, value|
118
+ values = value.kind_of?( Array ) ? value : [value]
119
+ params[key] = values.map {|v| normalize_cgi_value( v ) }
120
+ end
121
+ params.default = []
122
+ params
123
+ end
124
+
125
+ def read_raw_body
126
+ input = env['rack.input']
127
+ return '' unless input
128
+ # Rack::Request#POST leaves rack.input at EOF, so rewind first in
129
+ # case the request params were already parsed
130
+ input.rewind if input.respond_to?( :rewind )
131
+ body = input.read
132
+ input.rewind if input.respond_to?( :rewind )
133
+ body || ''
134
+ end
135
+
136
+ def normalize_cgi_value( value )
137
+ if value.kind_of?( Hash ) and value[:tempfile]
138
+ # Rack multipart file upload: expose an object responding to
139
+ # read, which is all the consumers use
140
+ value[:tempfile]
141
+ else
142
+ repair_encoding( value.to_s )
143
+ end
144
+ end
145
+
146
+ # CGI/FCGI hosting retries broken UTF-8 input as Shift_JIS. The same
147
+ # fallback is applied to each value: invalid UTF-8 is converted from
148
+ # Shift_JIS when possible, otherwise scrubbed.
149
+ def repair_encoding( str )
150
+ str = str.dup.force_encoding( Encoding::UTF_8 ) unless str.encoding == Encoding::UTF_8
151
+ return str if str.valid_encoding?
152
+ begin
153
+ str.dup.force_encoding( Encoding::Shift_JIS ).encode( Encoding::UTF_8 )
154
+ rescue EncodingError
155
+ str.scrub
156
+ end
157
+ end
14
158
  end
15
159
  end
16
160
 
@@ -54,7 +198,8 @@ end
54
198
  require 'tdiary/cgi_compat'
55
199
 
56
200
  # the @cgi facade for Rack-hosted requests. Kept as a toplevel constant
57
- # because plugins switch behaviour with @cgi.is_a?(RackCGI).
201
+ # only for third-party plugins that switch behaviour with
202
+ # @cgi.is_a?(RackCGI); in-repo code reads static_assets? instead.
58
203
  class RackCGI < TDiary::CGICompat; end
59
204
 
60
205
  # Local Variables:
@@ -16,20 +16,18 @@ module TDiary
16
16
 
17
17
  def run
18
18
  begin
19
- status = nil
20
19
  @tdiary = create_tdiary
21
20
 
22
21
  begin
22
+ status = 200
23
23
  head = {
24
24
  'content-type' => 'text/html; charset=UTF-8',
25
25
  'vary' => 'User-Agent'
26
26
  }
27
- head['status'] = status if status
28
27
  body = ''
29
- head['Last-Modified'] = CGI::rfc1123_date( tdiary.last_modified )
28
+ head['last-modified'] = tdiary.last_modified.httpdate
30
29
 
31
30
  if request.head?
32
- head['pragma'] = 'no-cache'
33
31
  head['cache-control'] = 'no-cache'
34
32
  return TDiary::Response.new( '', 200, head )
35
33
  else
@@ -37,15 +35,12 @@ module TDiary
37
35
  body = tdiary.eval_rhtml
38
36
  head['etag'] = %Q["#{OpenSSL::Digest::SHA256.hexdigest( body )}"]
39
37
  if request.env['HTTP_IF_NONE_MATCH'] == head['etag'] and request.get? then
40
- head['status'] = CGI::HTTP_STATUS['NOT_MODIFIED']
38
+ status = 304
41
39
  else
42
- head['charset'] = conf.encoding
43
40
  head['content-length'] = body.bytesize.to_s
44
41
  end
45
- head['pragma'] = 'no-cache'
46
42
  head['cache-control'] = 'no-cache'
47
- head['x-frame-options'] = conf.x_frame_options if conf.x_frame_options
48
- res = TDiary::Response.new( body, ::TDiary::Dispatcher.extract_status_for_legacy_tdiary( head ), head )
43
+ res = TDiary::Response.new( body, status, head )
49
44
  res.set_header('Set-Cookie', tdiary.cookies.map(&:to_s)) if tdiary && tdiary.cookies.size > 0
50
45
  res
51
46
  end
@@ -56,20 +51,7 @@ module TDiary
56
51
  TDiary::Response.new( body, 404, { 'content-type' => 'text/html' } )
57
52
  end
58
53
  rescue TDiary::ForceRedirect
59
- head = {
60
- #'Location' => $!.path
61
- 'content-type' => 'text/html',
62
- }
63
- body = %Q[
64
- <html>
65
- <head>
66
- <meta http-equiv="refresh" content="1;url=#{$!.path}">
67
- <title>moving...</title>
68
- </head>
69
- <body>Wait or <a href="#{$!.path}">Click here!</a></body>
70
- </html>]
71
- # TODO return code should be 302? (current behaviour returns 200)
72
- res = TDiary::Response.new( body, 200, head )
54
+ res = TDiary::Response.new( '', 303, { 'location' => $!.path } )
73
55
  res.set_header('Set-Cookie', tdiary.cookies.map(&:to_s)) if tdiary && tdiary.cookies.size > 0
74
56
  res
75
57
  end
@@ -21,28 +21,13 @@ module TDiary
21
21
  body = tdiary.eval_rhtml
22
22
  head = {
23
23
  'content-type' => 'text/html; charset=UTF-8',
24
- 'charset' => conf.encoding,
25
24
  'content-length' => body.bytesize.to_s,
26
- 'vary' => 'User-Agent',
27
- 'x-frame-options' => 'SAMEORIGIN'
25
+ 'vary' => 'User-Agent'
28
26
  }
29
27
  body = ( request.head? ? '' : body )
30
28
  TDiary::Response.new( body, 200, head )
31
29
  rescue TDiary::ForceRedirect
32
- head = {
33
- #'Location' => $!.path
34
- 'content-type' => 'text/html',
35
- }
36
- body = %Q[
37
- <html>
38
- <head>
39
- <meta http-equiv="refresh" content="1;url=#{$!.path}">
40
- <title>moving...</title>
41
- </head>
42
- <body>Wait or <a href="#{$!.path}">Click here!</a></body>
43
- </html>]
44
- # TODO return code should be 302? (current behaviour returns 200)
45
- res = TDiary::Response.new( body, 200, head )
30
+ res = TDiary::Response.new( '', 303, { 'location' => $!.path } )
46
31
  res.set_header('Set-Cookie', tdiary.cookies.map(&:to_s)) if tdiary && tdiary.cookies.size > 0
47
32
  res
48
33
  end
@@ -17,24 +17,13 @@ module TDiary
17
17
 
18
18
  def call( env )
19
19
  request = adopt_rack_request_to_plain_old_tdiary_style( env )
20
- result = @target.run( request )
21
- result.headers.reject!{|k,v| k.to_s.downcase == "status" }
22
- result.to_a
20
+ main = @target.new( request )
21
+ response = main.run
22
+ apply_security_headers( response, request, main.conf )
23
+ response.to_a
23
24
  end
24
25
 
25
26
  class << self
26
- # FIXME temporary method during (scratch) refactoring
27
- def extract_status_for_legacy_tdiary( head )
28
- status_str = head.delete('status')
29
- return 200 if !status_str || status_str.empty?
30
-
31
- if m = status_str.match(/(\d+)\s(.+)\Z/)
32
- m[1].to_i
33
- else
34
- 200
35
- end
36
- end
37
-
38
27
  def index
39
28
  new( :index )
40
29
  end
@@ -48,6 +37,31 @@ module TDiary
48
37
 
49
38
  private
50
39
 
40
+ def apply_security_headers( response, request, conf )
41
+ response.set_header( 'x-content-type-options', 'nosniff' )
42
+ apply_frame_restrictions( response, conf )
43
+ response.set_header( 'referrer-policy', conf.referrer_policy ) if conf.referrer_policy
44
+ response.set_header( 'strict-transport-security', conf.hsts ) if conf.hsts && request.ssl?
45
+ end
46
+
47
+ # The update target is an authenticated admin UI and always forbids
48
+ # cross-origin framing; the index target follows conf.x_frame_options.
49
+ # CSP frame-ancestors is the standard control, X-Frame-Options is kept
50
+ # alongside for legacy user agents.
51
+ def apply_frame_restrictions( response, conf )
52
+ if @target == UpdateMain
53
+ response.set_header( 'content-security-policy', "frame-ancestors 'self'" )
54
+ response.set_header( 'x-frame-options', 'SAMEORIGIN' )
55
+ elsif conf.x_frame_options
56
+ ancestors = case conf.x_frame_options.upcase
57
+ when 'SAMEORIGIN' then "'self'"
58
+ when 'DENY' then "'none'"
59
+ end
60
+ response.set_header( 'content-security-policy', "frame-ancestors #{ancestors}" ) if ancestors
61
+ response.set_header( 'x-frame-options', conf.x_frame_options )
62
+ end
63
+ end
64
+
51
65
  def adopt_rack_request_to_plain_old_tdiary_style( env )
52
66
  # rebuffer rack.input into a rewindable StringIO; both
53
67
  # Rack::Request and CGICompat read the body from it
@@ -9,7 +9,7 @@ module TDiary
9
9
  module Filter
10
10
  class DefaultFilter < Filter
11
11
  def comment_filter( diary, comment )
12
- if 'POST' != @cgi.request_method then
12
+ if 'POST' != @request.request_method then
13
13
  return false
14
14
  end
15
15
  if comment.name.strip.empty? or comment.body.strip.empty? then
@@ -29,7 +29,7 @@ module TDiary
29
29
  false
30
30
  #elsif /[\x00-\x20\x7f-\xff]/ =~ referer then
31
31
  # false
32
- elsif @conf.bot =~ @cgi.user_agent
32
+ elsif @conf.bot =~ @request.user_agent
33
33
  false
34
34
  elsif %r|^https?://|i =~ referer
35
35
  ref = CGI::unescape( referer.sub( /#.*$/, '' ).sub( /\?\d{8}$/, '' ) ).force_encoding('ASCII-8BIT')
@@ -228,8 +228,8 @@ module TDiary
228
228
  return @filter_mode
229
229
  end
230
230
 
231
- if @bad_ips.detect {|p| p =~ @cgi.remote_addr}
232
- debug( "ip address blacklisted: /#{p}/ =~ #{@cgi.remote_addr}" )
231
+ if @bad_ips.detect {|p| p =~ @request.remote_addr}
232
+ debug( "ip address blacklisted: /#{p}/ =~ #{@request.remote_addr}" )
233
233
  comment.show = false
234
234
  return @filter_mode
235
235
  end
data/lib/tdiary/filter.rb CHANGED
@@ -35,7 +35,7 @@ module TDiary
35
35
  return if @debug_mode == DEBUG_NONE
36
36
  return if @debug_mode == DEBUG_SPAM and level == DEBUG_FULL
37
37
 
38
- TDiary.logger.info("#{@cgi.remote_addr}->#{(@cgi.params['date'][0] || 'no date').dump}: #{msg}")
38
+ TDiary.logger.info("#{@request.remote_addr}->#{(@request.param('date') || 'no date').dump}: #{msg}")
39
39
  end
40
40
  end
41
41
  end
@@ -372,8 +372,18 @@ def script_tag_query_string
372
372
  "?#{TDIARY_VERSION}#{Time::now.strftime('%Y%m%d')}"
373
373
  end
374
374
 
375
+ # base URL the static assets are served from, when specified in
376
+ # tdiary.conf: @options['assets_url'] = 'https://assets.example.org/tdiary'
377
+ # It expects the merged layout the Rack assets/ mount serves (js files and
378
+ # theme directories under one root) and wins over the hosting default on
379
+ # every path (Rack, CGI and FCGI).
380
+ def configured_assets_url
381
+ url = @conf['assets_url']
382
+ url && !url.empty? ? url.chomp('/') : nil
383
+ end
384
+
375
385
  def js_url
376
- @cgi.is_a?(RackCGI) ? 'assets' : 'js'
386
+ configured_assets_url || (@cgi.static_assets? ? 'js' : 'assets')
377
387
  end
378
388
 
379
389
  def script_tag
@@ -396,7 +406,7 @@ def script_tag
396
406
  end
397
407
 
398
408
  def theme_url
399
- @cgi.is_a?(RackCGI) ? 'assets' : 'theme'
409
+ configured_assets_url || (@cgi.static_assets? ? 'theme' : 'assets')
400
410
  end
401
411
 
402
412
  def css_tag
@@ -748,6 +758,10 @@ def saveconf_default
748
758
  @conf['base_url'] = @cgi.params['base_url'][0]
749
759
  @conf.x_frame_options = @cgi.params['x_frame_options'][0]
750
760
  @conf.x_frame_options = nil if @conf.x_frame_options.empty?
761
+ @conf.referrer_policy = @cgi.params['referrer_policy'][0]
762
+ @conf.referrer_policy = nil if @conf.referrer_policy.empty?
763
+ @conf.hsts = @cgi.params['hsts'][0]
764
+ @conf.hsts = nil if @conf.hsts.empty?
751
765
  end
752
766
  end
753
767
 
@@ -887,7 +901,8 @@ def saveconf_csrf_protection
887
901
  if (check_method & 2 == 2 &&
888
902
  (old_method & 2 == 0 || old_key != check_key))
889
903
  @conf.save
890
- raise ForceRedirect, "#{h @conf.update}?conf=csrf_protection#{@cgi.referer ? '&amp;referer_exists=true' : ''}"
904
+ # the path is sent as a Location header now, so no HTML escaping
905
+ raise ForceRedirect, "#{@conf.update}?conf=csrf_protection#{@cgi.referer ? '&referer_exists=true' : ''}"
891
906
  end
892
907
  end
893
908
  err
@@ -169,6 +169,21 @@ add_conf_proc( 'default', 'Site information', 'basic' ) do
169
169
  <option value="SAMEORIGIN"#{" selected" if @conf.x_frame_options == 'SAMEORIGIN'}>Permit in same domain</option>
170
170
  <option value="DENY"#{" selected" if @conf.x_frame_options == 'DENY'}>Deny</option>
171
171
  </select></p>
172
+
173
+ <h3 class="subtitle">Referrer Policy</h3>
174
+ <p>Controls how much referrer information the browser sends when following links from your diary to other sites. The default matches the browser's standard behavior.</p>
175
+ <p><select name="referrer_policy">
176
+ <option value="strict-origin-when-cross-origin"#{" selected" if @conf.referrer_policy == 'strict-origin-when-cross-origin'}>Send origin only to other sites (default)</option>
177
+ <option value="same-origin"#{" selected" if @conf.referrer_policy == 'same-origin'}>Do not send to other sites</option>
178
+ <option value="no-referrer"#{" selected" if @conf.referrer_policy == 'no-referrer'}>Never send</option>
179
+ </select></p>
180
+
181
+ <h3 class="subtitle">Force HTTPS (HSTS)</h3>
182
+ <p>Sends the Strict-Transport-Security header on HTTPS responses so browsers keep using HTTPS afterwards. Leave disabled if your site is served over HTTP.</p>
183
+ <p><select name="hsts">
184
+ <option value=""#{" selected" unless @conf.hsts}>Disabled</option>
185
+ <option value="max-age=31536000"#{" selected" if @conf.hsts == 'max-age=31536000'}>Enabled (1 year)</option>
186
+ </select></p>
172
187
  HTML
173
188
  end
174
189
 
@@ -196,6 +196,21 @@ add_conf_proc( 'default', 'サイトの情報', 'basic' ) do
196
196
  <option value="SAMEORIGIN"#{" selected" if @conf.x_frame_options == 'SAMEORIGIN'}>同一ドメインなら許可する</option>
197
197
  <option value="DENY"#{" selected" if @conf.x_frame_options == 'DENY'}>禁止する</option>
198
198
  </select></p>
199
+
200
+ <h3 class="subtitle">Referrerポリシー</h3>
201
+ <p>日記内のリンクをたどって他のサイトへ移動するときに、ブラウザが送信するReferrerの範囲を指定します。標準の設定はブラウザの既定動作と同じです。</p>
202
+ <p><select name="referrer_policy">
203
+ <option value="strict-origin-when-cross-origin"#{" selected" if @conf.referrer_policy == 'strict-origin-when-cross-origin'}>他サイトへはURLの先頭部分のみ送信する(標準)</option>
204
+ <option value="same-origin"#{" selected" if @conf.referrer_policy == 'same-origin'}>他サイトへは送信しない</option>
205
+ <option value="no-referrer"#{" selected" if @conf.referrer_policy == 'no-referrer'}>常に送信しない</option>
206
+ </select></p>
207
+
208
+ <h3 class="subtitle">HTTPSの強制(HSTS)</h3>
209
+ <p>HTTPSでアクセスされたときに、以後もHTTPSの使用をブラウザに強制するStrict-Transport-Securityヘッダを送出します。HTTPで運用しているサイトでは無効のままにしてください。</p>
210
+ <p><select name="hsts">
211
+ <option value=""#{" selected" unless @conf.hsts}>無効</option>
212
+ <option value="max-age=31536000"#{" selected" if @conf.hsts == 'max-age=31536000'}>有効(期間1年)</option>
213
+ </select></p>
199
214
  HTML
200
215
  end
201
216
 
data/lib/tdiary/plugin.rb CHANGED
@@ -349,7 +349,7 @@ module TDiary
349
349
  end
350
350
 
351
351
  def conf_current_style( key )
352
- if key == @cgi.params['conf'][0] then
352
+ if key == @request.param('conf') then
353
353
  'selected'
354
354
  else
355
355
  'other'
@@ -0,0 +1,36 @@
1
+ module TDiary
2
+ module Rack
3
+ #
4
+ # class ErrorHandler
5
+ # catches exceptions leaked from the downstream app, reports the
6
+ # class, message and backtrace to rack.errors, and replaces the
7
+ # response with a plain 500 that does not expose the details to
8
+ # the client.
9
+ #
10
+ class ErrorHandler
11
+ def initialize( app )
12
+ @app = app
13
+ end
14
+
15
+ def call( env )
16
+ @app.call( env )
17
+ rescue Exception => e
18
+ self.class.report( env['rack.errors'], e )
19
+ [500, { 'content-type' => 'text/plain' }, ["500 Internal Server Error\n"]]
20
+ end
21
+
22
+ def self.report( errors, e )
23
+ errors.puts "#{e.class}: #{e.message}"
24
+ ( e.backtrace || [] ).each {|line| errors.puts "\t#{line}" }
25
+ errors.flush
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ # Local Variables:
32
+ # mode: ruby
33
+ # indent-tabs-mode: t
34
+ # tab-width: 3
35
+ # ruby-indent-level: 3
36
+ # End:
data/lib/tdiary/rack.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  module TDiary
2
2
  module Rack
3
+ autoload :ErrorHandler, 'tdiary/rack/error_handler'
3
4
  autoload :HtmlAnchor, 'tdiary/rack/html_anchor'
4
5
  autoload :ValidRequestPath, 'tdiary/rack/valid_request_path'
5
6
  autoload :Session, 'tdiary/rack/session'
@@ -5,8 +5,9 @@ module TDiary
5
5
 
6
6
  # the @cgi object handed to plugins: a facade over this request.
7
7
  # Endpoints behind a web server (CGI/FCGI) set tdiary.static_assets in
8
- # the env to get the base CGICompat, so @cgi.is_a?(RackCGI) is false and
9
- # plugins keep the static js/theme URLs served by the web server.
8
+ # the env to get the base CGICompat. The RackCGI/CGICompat split only
9
+ # serves third-party plugins that check @cgi.is_a?(RackCGI); in-repo
10
+ # code reads the flag through RequestExtension#static_assets?.
10
11
  def cgi_compat
11
12
  @cgi_compat ||=
12
13
  if env['tdiary.static_assets']
data/lib/tdiary/server.rb CHANGED
@@ -12,6 +12,28 @@ module TDiary
12
12
  require 'webrick/accesslog'
13
13
  require 'tempfile'
14
14
 
15
+ # WEBrick's CGI runner clears the environment of the CGI child process
16
+ # before exec'ing it, so the child cannot find the gems the server itself
17
+ # runs with. Hand the RubyGems and Bundler locations back to it.
18
+ module CGIEnvironment
19
+ def meta_vars
20
+ super.merge( {
21
+ 'HOME' => ENV['HOME'],
22
+ 'GEM_HOME' => Gem.dir,
23
+ 'GEM_PATH' => Gem.path.join( File::PATH_SEPARATOR ),
24
+ 'BUNDLE_GEMFILE' => ENV['BUNDLE_GEMFILE'],
25
+ }.compact )
26
+ end
27
+ end
28
+
29
+ class CGIHandler < WEBrick::HTTPServlet::CGIHandler
30
+ def do_GET( req, res )
31
+ req.extend( CGIEnvironment )
32
+ super
33
+ end
34
+ alias do_POST do_GET
35
+ end
36
+
15
37
  class << self
16
38
  def run( option )
17
39
  @@server = new( option )
@@ -38,9 +60,9 @@ module TDiary
38
60
  CGIInterpreter: WEBrick::HTTPServlet::CGIHandler::Ruby
39
61
  )
40
62
  @server.logger.level = WEBrick::Log::DEBUG
41
- @server.mount("/", WEBrick::HTTPServlet::CGIHandler, TDiary.root + "/index.rb")
42
- @server.mount("/index.rb", WEBrick::HTTPServlet::CGIHandler, TDiary.root + '/index.rb')
43
- @server.mount("/update.rb", WEBrick::HTTPServlet::CGIHandler, TDiary.root + "/update.rb")
63
+ @server.mount("/", CGIHandler, TDiary.root + "/index.rb")
64
+ @server.mount("/index.rb", CGIHandler, TDiary.root + '/index.rb')
65
+ @server.mount("/update.rb", CGIHandler, TDiary.root + "/update.rb")
44
66
  @server.mount("/theme", WEBrick::HTTPServlet::FileHandler, TDiary.root + '/theme')
45
67
  @server.mount("/js", WEBrick::HTTPServlet::FileHandler, TDiary.root + '/js')
46
68
  end
@@ -1,3 +1,3 @@
1
1
  module TDiary
2
- VERSION = "5.5.1"
2
+ VERSION = "5.6.0"
3
3
  end