hello_world.rb 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. # frozen_string_literal: true
  2. require 'time'
  3. # Our Rack application to be executed by rackup
  4. class HelloWorld
  5. MAX_PK = 10_000
  6. ID_RANGE = (1..10_000).freeze
  7. ALL_IDS = ID_RANGE.to_a
  8. QUERIES_MIN = 1
  9. QUERIES_MAX = 500
  10. CONTENT_TYPE = 'Content-Type'
  11. CONTENT_LENGTH = 'Content-Length'
  12. JSON_TYPE = 'application/json'
  13. HTML_TYPE = 'text/html; charset=utf-8'
  14. PLAINTEXT_TYPE = 'text/plain'
  15. DATE = 'Date'
  16. SERVER = 'Server'
  17. SERVER_STRING = "Rack"
  18. def bounded_queries(env)
  19. params = Rack::Utils.parse_query(env['QUERY_STRING'])
  20. queries = params['queries'].to_i
  21. queries.clamp(QUERIES_MIN, QUERIES_MAX)
  22. end
  23. # Return a random number between 1 and MAX_PK
  24. def rand1
  25. rand(MAX_PK).succ
  26. end
  27. def db
  28. World::BY_ID.(id: rand1)
  29. end
  30. def queries(env)
  31. ids = ALL_IDS.sample(bounded_queries(env))
  32. DB.synchronize do
  33. ids.map do |id|
  34. World::BY_ID.(id: id)
  35. end
  36. end
  37. end
  38. def fortunes
  39. fortunes = Fortune.all
  40. fortunes << Fortune.new(
  41. id: 0,
  42. message: 'Additional fortune added at request time.'
  43. )
  44. fortunes.sort_by!(&:message)
  45. html = String.new(<<~'HTML')
  46. <!DOCTYPE html>
  47. <html>
  48. <head>
  49. <title>Fortunes</title>
  50. </head>
  51. <body>
  52. <table>
  53. <tr>
  54. <th>id</th>
  55. <th>message</th>
  56. </tr>
  57. HTML
  58. fortunes.each do |fortune|
  59. html << <<~"HTML"
  60. <tr>
  61. <td>#{fortune.id}</td>
  62. <td>#{Rack::Utils.escape_html(fortune.message)}</td>
  63. </tr>
  64. HTML
  65. end
  66. html << <<~'HTML'
  67. </table>
  68. </body>
  69. </html>
  70. HTML
  71. end
  72. def updates(env)
  73. ids = ALL_IDS.sample(bounded_queries(env))
  74. DB.synchronize do
  75. worlds =
  76. ids.map do |id|
  77. world = World::BY_ID.(id: id)
  78. world[:randomnumber] = rand1
  79. world
  80. end
  81. World.batch_update(worlds)
  82. worlds
  83. end
  84. end
  85. def call(env)
  86. case env['PATH_INFO']
  87. when '/json'
  88. # Test type 1: JSON serialization
  89. respond JSON_TYPE, { message: 'Hello, World!' }.to_json
  90. when '/db'
  91. # Test type 2: Single database query
  92. respond JSON_TYPE, db.to_json
  93. when '/queries'
  94. # Test type 3: Multiple database queries
  95. respond JSON_TYPE, queries(env).to_json
  96. when '/fortunes'
  97. # Test type 4: Fortunes
  98. respond HTML_TYPE, fortunes
  99. when '/updates'
  100. # Test type 5: Database updates
  101. respond JSON_TYPE, updates(env).to_json
  102. when '/plaintext'
  103. # Test type 6: Plaintext
  104. respond PLAINTEXT_TYPE, 'Hello, World!'
  105. end
  106. end
  107. private
  108. def respond(content_type, body)
  109. [
  110. 200,
  111. headers(content_type, body),
  112. [body]
  113. ]
  114. end
  115. if defined?(Unicorn)
  116. def headers(content_type, body)
  117. {
  118. CONTENT_TYPE => content_type,
  119. SERVER => SERVER_STRING,
  120. CONTENT_LENGTH => body.bytesize.to_s
  121. }
  122. end
  123. elsif defined?(Puma)
  124. def headers(content_type, _)
  125. {
  126. CONTENT_TYPE => content_type,
  127. SERVER => SERVER_STRING,
  128. DATE => Time.now.utc.httpdate
  129. }
  130. end
  131. else
  132. def headers(content_type, _)
  133. {
  134. CONTENT_TYPE => content_type,
  135. SERVER => SERVER_STRING
  136. }
  137. end
  138. end
  139. end