passenger 3.0.7 → 3.0.8

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (439) hide show
  1. data/NEWS +27 -0
  2. data/README +1 -1
  3. data/bin/passenger-install-nginx-module +3 -1
  4. data/build/config.rb +2 -1
  5. data/build/cxx_tests.rb +7 -3
  6. data/build/documentation.rb +5 -40
  7. data/build/nginx.rb +0 -1
  8. data/build/packaging.rb +0 -6
  9. data/build/rake_extensions.rb +5 -0
  10. data/doc/Architectural overview.html +344 -77
  11. data/doc/Security of user switching support.html +338 -71
  12. data/doc/Users guide Apache with comments.html +4830 -0
  13. data/doc/Users guide Apache.html +695 -428
  14. data/doc/Users guide Apache.idmap.txt +80 -0
  15. data/doc/Users guide Apache.txt +5 -5
  16. data/doc/Users guide Nginx.html +591 -313
  17. data/doc/Users guide Nginx.txt +9 -3
  18. data/doc/Users guide Standalone.html +344 -77
  19. data/ext/boost/src/pthread/thread.cpp +1 -1
  20. data/ext/common/AccountsDatabase.h +1 -1
  21. data/ext/common/Constants.h +2 -2
  22. data/ext/common/Logging.h +2 -1
  23. data/ext/common/LoggingAgent/FilterSupport.h +107 -3
  24. data/ext/common/Session.h +1 -1
  25. data/ext/common/Utils.cpp +2 -0
  26. data/ext/common/Utils/Dechunker.h +232 -0
  27. data/ext/common/Utils/HttpHeaderBufferer.h +165 -0
  28. data/ext/common/Utils/StrIntUtils.cpp +51 -15
  29. data/ext/common/Utils/StrIntUtils.h +3 -0
  30. data/ext/common/Utils/StreamBoyerMooreHorspool.h +506 -0
  31. data/ext/nginx/Configuration.c +36 -282
  32. data/ext/nginx/ContentHandler.c +17 -0
  33. data/ext/nginx/HelperAgent.cpp +397 -39
  34. data/ext/oxt/tracable_exception.cpp +3 -1
  35. data/ext/ruby/extconf.rb +1 -0
  36. data/ext/ruby/passenger_native_support.c +3 -0
  37. data/helper-scripts/prespawn +113 -31
  38. data/lib/phusion_passenger.rb +2 -2
  39. data/lib/phusion_passenger/standalone/runtime_installer.rb +3 -2
  40. data/lib/phusion_passenger/standalone/start_command.rb +12 -12
  41. data/test/cxx/DechunkerTest.cpp +216 -0
  42. data/test/cxx/FilterSupportTest.cpp +31 -4
  43. data/test/cxx/HttpHeaderBuffererTest.cpp +203 -0
  44. data/test/cxx/UtilsTest.cpp +46 -3
  45. data/test/integration_tests/hello_world_rack_spec.rb +7 -0
  46. data/test/stub/rack/config.ru +6 -1
  47. data/test/stub/rails_apps/1.2/empty/public/dispatch.cgi +1 -1
  48. data/test/stub/rails_apps/1.2/empty/public/dispatch.fcgi +1 -1
  49. data/test/stub/rails_apps/1.2/empty/public/dispatch.rb +1 -1
  50. data/test/stub/rails_apps/2.0/empty/public/dispatch.cgi +1 -1
  51. data/test/stub/rails_apps/2.0/empty/public/dispatch.fcgi +1 -1
  52. data/test/stub/rails_apps/2.0/empty/public/dispatch.rb +1 -1
  53. data/test/stub/rails_apps/2.2/empty/public/dispatch.cgi +1 -1
  54. data/test/stub/rails_apps/2.2/empty/public/dispatch.fcgi +1 -1
  55. data/test/stub/rails_apps/2.2/empty/public/dispatch.rb +1 -1
  56. metadata +20 -403
  57. data/doc/Doxyfile +0 -241
  58. data/doc/cxxapi/AbstractSpawnManager_8h_source.html +0 -141
  59. data/doc/cxxapi/Account_8h_source.html +0 -206
  60. data/doc/cxxapi/AccountsDatabase_8h_source.html +0 -161
  61. data/doc/cxxapi/AgentBase_8h_source.html +0 -70
  62. data/doc/cxxapi/AgentsStarter_8h_source.html +0 -112
  63. data/doc/cxxapi/BCrypt_8h_source.html +0 -104
  64. data/doc/cxxapi/Blowfish_8h_source.html +0 -134
  65. data/doc/cxxapi/Bucket_8h_source.html +0 -118
  66. data/doc/cxxapi/Constants_8h_source.html +0 -79
  67. data/doc/cxxapi/ContentHandler_8h_source.html +0 -95
  68. data/doc/cxxapi/DirectoryMapper_8h_source.html +0 -311
  69. data/doc/cxxapi/EventedClient_8h_source.html +0 -733
  70. data/doc/cxxapi/EventedMessageServer_8h_source.html +0 -358
  71. data/doc/cxxapi/EventedServer_8h_source.html +0 -326
  72. data/doc/cxxapi/Exceptions_8h_source.html +0 -393
  73. data/doc/cxxapi/FileDescriptor_8h_source.html +0 -324
  74. data/doc/cxxapi/Hooks_8h_source.html +0 -76
  75. data/doc/cxxapi/HttpStatusExtractor_8h_source.html +0 -382
  76. data/doc/cxxapi/IniFile_8h_source.html +0 -527
  77. data/doc/cxxapi/Logging_8h_source.html +0 -796
  78. data/doc/cxxapi/MessageChannel_8h_source.html +0 -776
  79. data/doc/cxxapi/MessageClient_8h_source.html +0 -328
  80. data/doc/cxxapi/MessageReadersWriters_8h_source.html +0 -539
  81. data/doc/cxxapi/MessageServer_8h_source.html +0 -612
  82. data/doc/cxxapi/PoolOptions_8h_source.html +0 -549
  83. data/doc/cxxapi/Process_8h_source.html +0 -286
  84. data/doc/cxxapi/RandomGenerator_8h_source.html +0 -191
  85. data/doc/cxxapi/ResourceLocator_8h_source.html +0 -166
  86. data/doc/cxxapi/SafeLibev_8h_source.html +0 -180
  87. data/doc/cxxapi/ScgiRequestParser_8h_source.html +0 -406
  88. data/doc/cxxapi/ServerInstanceDir_8h_source.html +0 -378
  89. data/doc/cxxapi/Session_8h_source.html +0 -501
  90. data/doc/cxxapi/SpawnManager_8h_source.html +0 -647
  91. data/doc/cxxapi/StaticContentHandler_8h_source.html +0 -69
  92. data/doc/cxxapi/StaticString_8h_source.html +0 -329
  93. data/doc/cxxapi/StringListCreator_8h_source.html +0 -114
  94. data/doc/cxxapi/Utils_8h_source.html +0 -469
  95. data/doc/cxxapi/annotated.html +0 -87
  96. data/doc/cxxapi/apache2_2Configuration_8h_source.html +0 -82
  97. data/doc/cxxapi/classAgentWatcher-members.html +0 -54
  98. data/doc/cxxapi/classAgentWatcher.html +0 -419
  99. data/doc/cxxapi/classClient-members.html +0 -38
  100. data/doc/cxxapi/classClient.html +0 -123
  101. data/doc/cxxapi/classHooks-members.html +0 -40
  102. data/doc/cxxapi/classHooks.html +0 -153
  103. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager-members.html +0 -40
  104. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager.html +0 -187
  105. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager__inherit__graph.map +0 -3
  106. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager__inherit__graph.md5 +0 -1
  107. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager__inherit__graph.png +0 -0
  108. data/doc/cxxapi/classPassenger_1_1ArgumentException-members.html +0 -36
  109. data/doc/cxxapi/classPassenger_1_1ArgumentException.html +0 -56
  110. data/doc/cxxapi/classPassenger_1_1ArrayMessage-members.html +0 -37
  111. data/doc/cxxapi/classPassenger_1_1ArrayMessage.html +0 -113
  112. data/doc/cxxapi/classPassenger_1_1BufferedUpload-members.html +0 -38
  113. data/doc/cxxapi/classPassenger_1_1BufferedUpload.html +0 -112
  114. data/doc/cxxapi/classPassenger_1_1BusyException-members.html +0 -36
  115. data/doc/cxxapi/classPassenger_1_1BusyException.html +0 -54
  116. data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +0 -36
  117. data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +0 -51
  118. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +0 -41
  119. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +0 -223
  120. data/doc/cxxapi/classPassenger_1_1EOFException-members.html +0 -36
  121. data/doc/cxxapi/classPassenger_1_1EOFException.html +0 -61
  122. data/doc/cxxapi/classPassenger_1_1EOFException__inherit__graph.map +0 -3
  123. data/doc/cxxapi/classPassenger_1_1EOFException__inherit__graph.md5 +0 -1
  124. data/doc/cxxapi/classPassenger_1_1EOFException__inherit__graph.png +0 -0
  125. data/doc/cxxapi/classPassenger_1_1EventFd-members.html +0 -36
  126. data/doc/cxxapi/classPassenger_1_1EventFd.html +0 -52
  127. data/doc/cxxapi/classPassenger_1_1EventedClient-members.html +0 -59
  128. data/doc/cxxapi/classPassenger_1_1EventedClient.html +0 -531
  129. data/doc/cxxapi/classPassenger_1_1EventedMessageServer-members.html +0 -37
  130. data/doc/cxxapi/classPassenger_1_1EventedMessageServer.html +0 -59
  131. data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.map +0 -3
  132. data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.md5 +0 -1
  133. data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.png +0 -0
  134. data/doc/cxxapi/classPassenger_1_1EventedServer-members.html +0 -37
  135. data/doc/cxxapi/classPassenger_1_1EventedServer.html +0 -93
  136. data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.map +0 -3
  137. data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.md5 +0 -1
  138. data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.png +0 -0
  139. data/doc/cxxapi/classPassenger_1_1FileDescriptor-members.html +0 -41
  140. data/doc/cxxapi/classPassenger_1_1FileDescriptor.html +0 -178
  141. data/doc/cxxapi/classPassenger_1_1FileDescriptorPair-members.html +0 -36
  142. data/doc/cxxapi/classPassenger_1_1FileDescriptorPair.html +0 -52
  143. data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +0 -36
  144. data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +0 -58
  145. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.map +0 -3
  146. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.md5 +0 -1
  147. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
  148. data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +0 -41
  149. data/doc/cxxapi/classPassenger_1_1FileSystemException.html +0 -66
  150. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.map +0 -3
  151. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.md5 +0 -1
  152. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
  153. data/doc/cxxapi/classPassenger_1_1HttpStatusExtractor-members.html +0 -39
  154. data/doc/cxxapi/classPassenger_1_1HttpStatusExtractor.html +0 -128
  155. data/doc/cxxapi/classPassenger_1_1IOException-members.html +0 -36
  156. data/doc/cxxapi/classPassenger_1_1IOException.html +0 -61
  157. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.map +0 -4
  158. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.md5 +0 -1
  159. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
  160. data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +0 -57
  161. data/doc/cxxapi/classPassenger_1_1MessageChannel.html +0 -839
  162. data/doc/cxxapi/classPassenger_1_1MessageServer-members.html +0 -49
  163. data/doc/cxxapi/classPassenger_1_1MessageServer.html +0 -407
  164. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext-members.html +0 -36
  165. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext.html +0 -58
  166. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.map +0 -3
  167. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.md5 +0 -1
  168. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.png +0 -0
  169. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext-members.html +0 -41
  170. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext.html +0 -165
  171. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.map +0 -3
  172. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.md5 +0 -1
  173. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.png +0 -0
  174. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler-members.html +0 -39
  175. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler.html +0 -173
  176. data/doc/cxxapi/classPassenger_1_1Process-members.html +0 -44
  177. data/doc/cxxapi/classPassenger_1_1Process.html +0 -290
  178. data/doc/cxxapi/classPassenger_1_1RandomGenerator-members.html +0 -37
  179. data/doc/cxxapi/classPassenger_1_1RandomGenerator.html +0 -79
  180. data/doc/cxxapi/classPassenger_1_1ResourceLocator-members.html +0 -36
  181. data/doc/cxxapi/classPassenger_1_1ResourceLocator.html +0 -51
  182. data/doc/cxxapi/classPassenger_1_1RuntimeException-members.html +0 -36
  183. data/doc/cxxapi/classPassenger_1_1RuntimeException.html +0 -54
  184. data/doc/cxxapi/classPassenger_1_1SafeLibev-members.html +0 -36
  185. data/doc/cxxapi/classPassenger_1_1SafeLibev.html +0 -51
  186. data/doc/cxxapi/classPassenger_1_1ScalarMessage-members.html +0 -37
  187. data/doc/cxxapi/classPassenger_1_1ScalarMessage.html +0 -76
  188. data/doc/cxxapi/classPassenger_1_1ScgiRequestParser-members.html +0 -50
  189. data/doc/cxxapi/classPassenger_1_1ScgiRequestParser.html +0 -285
  190. data/doc/cxxapi/classPassenger_1_1SecurityException-members.html +0 -36
  191. data/doc/cxxapi/classPassenger_1_1SecurityException.html +0 -56
  192. data/doc/cxxapi/classPassenger_1_1Session-members.html +0 -53
  193. data/doc/cxxapi/classPassenger_1_1Session.html +0 -556
  194. data/doc/cxxapi/classPassenger_1_1Session__inherit__graph.map +0 -3
  195. data/doc/cxxapi/classPassenger_1_1Session__inherit__graph.md5 +0 -1
  196. data/doc/cxxapi/classPassenger_1_1Session__inherit__graph.png +0 -0
  197. data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +0 -39
  198. data/doc/cxxapi/classPassenger_1_1SpawnException.html +0 -101
  199. data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +0 -42
  200. data/doc/cxxapi/classPassenger_1_1SpawnManager.html +0 -292
  201. data/doc/cxxapi/classPassenger_1_1SpawnManager__inherit__graph.map +0 -3
  202. data/doc/cxxapi/classPassenger_1_1SpawnManager__inherit__graph.md5 +0 -1
  203. data/doc/cxxapi/classPassenger_1_1SpawnManager__inherit__graph.png +0 -0
  204. data/doc/cxxapi/classPassenger_1_1StandardSession-members.html +0 -54
  205. data/doc/cxxapi/classPassenger_1_1StandardSession.html +0 -394
  206. data/doc/cxxapi/classPassenger_1_1StandardSession__inherit__graph.map +0 -3
  207. data/doc/cxxapi/classPassenger_1_1StandardSession__inherit__graph.md5 +0 -1
  208. data/doc/cxxapi/classPassenger_1_1StandardSession__inherit__graph.png +0 -0
  209. data/doc/cxxapi/classPassenger_1_1StaticString-members.html +0 -36
  210. data/doc/cxxapi/classPassenger_1_1StaticString.html +0 -56
  211. data/doc/cxxapi/classPassenger_1_1SyntaxError-members.html +0 -36
  212. data/doc/cxxapi/classPassenger_1_1SyntaxError.html +0 -54
  213. data/doc/cxxapi/classPassenger_1_1SystemException-members.html +0 -40
  214. data/doc/cxxapi/classPassenger_1_1SystemException.html +0 -155
  215. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.map +0 -4
  216. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.md5 +0 -1
  217. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
  218. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException-members.html +0 -40
  219. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException.html +0 -61
  220. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException__inherit__graph.map +0 -3
  221. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException__inherit__graph.md5 +0 -1
  222. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException__inherit__graph.png +0 -0
  223. data/doc/cxxapi/classPassenger_1_1TimeoutException-members.html +0 -36
  224. data/doc/cxxapi/classPassenger_1_1TimeoutException.html +0 -54
  225. data/doc/cxxapi/classPassenger_1_1Uint16Message-members.html +0 -36
  226. data/doc/cxxapi/classPassenger_1_1Uint16Message.html +0 -51
  227. data/doc/cxxapi/classPassenger_1_1Uint32Message-members.html +0 -36
  228. data/doc/cxxapi/classPassenger_1_1Uint32Message.html +0 -51
  229. data/doc/cxxapi/classServer-members.html +0 -36
  230. data/doc/cxxapi/classServer.html +0 -49
  231. data/doc/cxxapi/classServerInstanceDirToucher-members.html +0 -36
  232. data/doc/cxxapi/classServerInstanceDirToucher.html +0 -47
  233. data/doc/cxxapi/classes.html +0 -52
  234. data/doc/cxxapi/definitions_8h_source.html +0 -36
  235. data/doc/cxxapi/doxygen.css +0 -532
  236. data/doc/cxxapi/doxygen.png +0 -0
  237. data/doc/cxxapi/files.html +0 -76
  238. data/doc/cxxapi/ftv2blank.png +0 -0
  239. data/doc/cxxapi/ftv2doc.png +0 -0
  240. data/doc/cxxapi/ftv2folderclosed.png +0 -0
  241. data/doc/cxxapi/ftv2folderopen.png +0 -0
  242. data/doc/cxxapi/ftv2lastnode.png +0 -0
  243. data/doc/cxxapi/ftv2link.png +0 -0
  244. data/doc/cxxapi/ftv2mlastnode.png +0 -0
  245. data/doc/cxxapi/ftv2mnode.png +0 -0
  246. data/doc/cxxapi/ftv2node.png +0 -0
  247. data/doc/cxxapi/ftv2plastnode.png +0 -0
  248. data/doc/cxxapi/ftv2pnode.png +0 -0
  249. data/doc/cxxapi/ftv2vertline.png +0 -0
  250. data/doc/cxxapi/functions.html +0 -103
  251. data/doc/cxxapi/functions_0x62.html +0 -82
  252. data/doc/cxxapi/functions_0x63.html +0 -102
  253. data/doc/cxxapi/functions_0x64.html +0 -102
  254. data/doc/cxxapi/functions_0x65.html +0 -88
  255. data/doc/cxxapi/functions_0x66.html +0 -100
  256. data/doc/cxxapi/functions_0x67.html +0 -167
  257. data/doc/cxxapi/functions_0x68.html +0 -88
  258. data/doc/cxxapi/functions_0x69.html +0 -96
  259. data/doc/cxxapi/functions_0x6b.html +0 -80
  260. data/doc/cxxapi/functions_0x6c.html +0 -88
  261. data/doc/cxxapi/functions_0x6d.html +0 -88
  262. data/doc/cxxapi/functions_0x6e.html +0 -86
  263. data/doc/cxxapi/functions_0x6f.html +0 -94
  264. data/doc/cxxapi/functions_0x70.html +0 -94
  265. data/doc/cxxapi/functions_0x72.html +0 -110
  266. data/doc/cxxapi/functions_0x73.html +0 -171
  267. data/doc/cxxapi/functions_0x74.html +0 -85
  268. data/doc/cxxapi/functions_0x75.html +0 -85
  269. data/doc/cxxapi/functions_0x77.html +0 -92
  270. data/doc/cxxapi/functions_0x7e.html +0 -79
  271. data/doc/cxxapi/functions_enum.html +0 -49
  272. data/doc/cxxapi/functions_eval.html +0 -67
  273. data/doc/cxxapi/functions_func.html +0 -531
  274. data/doc/cxxapi/functions_vars.html +0 -278
  275. data/doc/cxxapi/graph_legend.dot +0 -22
  276. data/doc/cxxapi/graph_legend.html +0 -92
  277. data/doc/cxxapi/graph_legend.png +0 -0
  278. data/doc/cxxapi/group__Core.html +0 -46
  279. data/doc/cxxapi/group__Core.map +0 -3
  280. data/doc/cxxapi/group__Core.png +0 -0
  281. data/doc/cxxapi/group__Exceptions.html +0 -53
  282. data/doc/cxxapi/group__Hooks.html +0 -42
  283. data/doc/cxxapi/group__Hooks.map +0 -3
  284. data/doc/cxxapi/group__Hooks.png +0 -0
  285. data/doc/cxxapi/group__Support.html +0 -538
  286. data/doc/cxxapi/hierarchy.html +0 -101
  287. data/doc/cxxapi/index.html +0 -16
  288. data/doc/cxxapi/inherit__graph__0.map +0 -3
  289. data/doc/cxxapi/inherit__graph__0.md5 +0 -1
  290. data/doc/cxxapi/inherit__graph__0.png +0 -0
  291. data/doc/cxxapi/inherit__graph__1.map +0 -3
  292. data/doc/cxxapi/inherit__graph__1.md5 +0 -1
  293. data/doc/cxxapi/inherit__graph__1.png +0 -0
  294. data/doc/cxxapi/inherit__graph__10.map +0 -3
  295. data/doc/cxxapi/inherit__graph__10.md5 +0 -1
  296. data/doc/cxxapi/inherit__graph__10.png +0 -0
  297. data/doc/cxxapi/inherit__graph__11.map +0 -4
  298. data/doc/cxxapi/inherit__graph__11.md5 +0 -1
  299. data/doc/cxxapi/inherit__graph__11.png +0 -0
  300. data/doc/cxxapi/inherit__graph__12.map +0 -3
  301. data/doc/cxxapi/inherit__graph__12.md5 +0 -1
  302. data/doc/cxxapi/inherit__graph__12.png +0 -0
  303. data/doc/cxxapi/inherit__graph__13.map +0 -3
  304. data/doc/cxxapi/inherit__graph__13.md5 +0 -1
  305. data/doc/cxxapi/inherit__graph__13.png +0 -0
  306. data/doc/cxxapi/inherit__graph__14.map +0 -3
  307. data/doc/cxxapi/inherit__graph__14.md5 +0 -1
  308. data/doc/cxxapi/inherit__graph__14.png +0 -0
  309. data/doc/cxxapi/inherit__graph__15.map +0 -3
  310. data/doc/cxxapi/inherit__graph__15.md5 +0 -1
  311. data/doc/cxxapi/inherit__graph__15.png +0 -0
  312. data/doc/cxxapi/inherit__graph__16.map +0 -5
  313. data/doc/cxxapi/inherit__graph__16.md5 +0 -1
  314. data/doc/cxxapi/inherit__graph__16.png +0 -0
  315. data/doc/cxxapi/inherit__graph__17.map +0 -3
  316. data/doc/cxxapi/inherit__graph__17.md5 +0 -1
  317. data/doc/cxxapi/inherit__graph__17.png +0 -0
  318. data/doc/cxxapi/inherit__graph__18.map +0 -3
  319. data/doc/cxxapi/inherit__graph__18.md5 +0 -1
  320. data/doc/cxxapi/inherit__graph__18.png +0 -0
  321. data/doc/cxxapi/inherit__graph__19.map +0 -4
  322. data/doc/cxxapi/inherit__graph__19.md5 +0 -1
  323. data/doc/cxxapi/inherit__graph__19.png +0 -0
  324. data/doc/cxxapi/inherit__graph__2.map +0 -3
  325. data/doc/cxxapi/inherit__graph__2.md5 +0 -1
  326. data/doc/cxxapi/inherit__graph__2.png +0 -0
  327. data/doc/cxxapi/inherit__graph__20.map +0 -3
  328. data/doc/cxxapi/inherit__graph__20.md5 +0 -1
  329. data/doc/cxxapi/inherit__graph__20.png +0 -0
  330. data/doc/cxxapi/inherit__graph__21.map +0 -3
  331. data/doc/cxxapi/inherit__graph__21.md5 +0 -1
  332. data/doc/cxxapi/inherit__graph__21.png +0 -0
  333. data/doc/cxxapi/inherit__graph__22.map +0 -3
  334. data/doc/cxxapi/inherit__graph__22.md5 +0 -1
  335. data/doc/cxxapi/inherit__graph__22.png +0 -0
  336. data/doc/cxxapi/inherit__graph__23.map +0 -3
  337. data/doc/cxxapi/inherit__graph__23.md5 +0 -1
  338. data/doc/cxxapi/inherit__graph__23.png +0 -0
  339. data/doc/cxxapi/inherit__graph__24.map +0 -3
  340. data/doc/cxxapi/inherit__graph__24.md5 +0 -1
  341. data/doc/cxxapi/inherit__graph__24.png +0 -0
  342. data/doc/cxxapi/inherit__graph__25.map +0 -3
  343. data/doc/cxxapi/inherit__graph__25.md5 +0 -1
  344. data/doc/cxxapi/inherit__graph__25.png +0 -0
  345. data/doc/cxxapi/inherit__graph__26.map +0 -3
  346. data/doc/cxxapi/inherit__graph__26.md5 +0 -1
  347. data/doc/cxxapi/inherit__graph__26.png +0 -0
  348. data/doc/cxxapi/inherit__graph__27.map +0 -3
  349. data/doc/cxxapi/inherit__graph__27.md5 +0 -1
  350. data/doc/cxxapi/inherit__graph__27.png +0 -0
  351. data/doc/cxxapi/inherit__graph__28.map +0 -3
  352. data/doc/cxxapi/inherit__graph__28.md5 +0 -1
  353. data/doc/cxxapi/inherit__graph__28.png +0 -0
  354. data/doc/cxxapi/inherit__graph__29.map +0 -3
  355. data/doc/cxxapi/inherit__graph__29.md5 +0 -1
  356. data/doc/cxxapi/inherit__graph__29.png +0 -0
  357. data/doc/cxxapi/inherit__graph__3.map +0 -4
  358. data/doc/cxxapi/inherit__graph__3.md5 +0 -1
  359. data/doc/cxxapi/inherit__graph__3.png +0 -0
  360. data/doc/cxxapi/inherit__graph__30.map +0 -3
  361. data/doc/cxxapi/inherit__graph__30.md5 +0 -1
  362. data/doc/cxxapi/inherit__graph__30.png +0 -0
  363. data/doc/cxxapi/inherit__graph__31.map +0 -4
  364. data/doc/cxxapi/inherit__graph__31.md5 +0 -1
  365. data/doc/cxxapi/inherit__graph__31.png +0 -0
  366. data/doc/cxxapi/inherit__graph__32.map +0 -3
  367. data/doc/cxxapi/inherit__graph__32.md5 +0 -1
  368. data/doc/cxxapi/inherit__graph__32.png +0 -0
  369. data/doc/cxxapi/inherit__graph__33.map +0 -3
  370. data/doc/cxxapi/inherit__graph__33.md5 +0 -1
  371. data/doc/cxxapi/inherit__graph__33.png +0 -0
  372. data/doc/cxxapi/inherit__graph__34.map +0 -3
  373. data/doc/cxxapi/inherit__graph__34.md5 +0 -1
  374. data/doc/cxxapi/inherit__graph__34.png +0 -0
  375. data/doc/cxxapi/inherit__graph__35.map +0 -3
  376. data/doc/cxxapi/inherit__graph__35.md5 +0 -1
  377. data/doc/cxxapi/inherit__graph__35.png +0 -0
  378. data/doc/cxxapi/inherit__graph__36.map +0 -5
  379. data/doc/cxxapi/inherit__graph__36.md5 +0 -1
  380. data/doc/cxxapi/inherit__graph__36.png +0 -0
  381. data/doc/cxxapi/inherit__graph__37.map +0 -3
  382. data/doc/cxxapi/inherit__graph__37.md5 +0 -1
  383. data/doc/cxxapi/inherit__graph__37.png +0 -0
  384. data/doc/cxxapi/inherit__graph__38.map +0 -3
  385. data/doc/cxxapi/inherit__graph__38.md5 +0 -1
  386. data/doc/cxxapi/inherit__graph__38.png +0 -0
  387. data/doc/cxxapi/inherit__graph__39.map +0 -3
  388. data/doc/cxxapi/inherit__graph__39.md5 +0 -1
  389. data/doc/cxxapi/inherit__graph__39.png +0 -0
  390. data/doc/cxxapi/inherit__graph__4.map +0 -3
  391. data/doc/cxxapi/inherit__graph__4.md5 +0 -1
  392. data/doc/cxxapi/inherit__graph__4.png +0 -0
  393. data/doc/cxxapi/inherit__graph__40.map +0 -3
  394. data/doc/cxxapi/inherit__graph__40.md5 +0 -1
  395. data/doc/cxxapi/inherit__graph__40.png +0 -0
  396. data/doc/cxxapi/inherit__graph__41.map +0 -3
  397. data/doc/cxxapi/inherit__graph__41.md5 +0 -1
  398. data/doc/cxxapi/inherit__graph__41.png +0 -0
  399. data/doc/cxxapi/inherit__graph__5.map +0 -3
  400. data/doc/cxxapi/inherit__graph__5.md5 +0 -1
  401. data/doc/cxxapi/inherit__graph__5.png +0 -0
  402. data/doc/cxxapi/inherit__graph__6.map +0 -3
  403. data/doc/cxxapi/inherit__graph__6.md5 +0 -1
  404. data/doc/cxxapi/inherit__graph__6.png +0 -0
  405. data/doc/cxxapi/inherit__graph__7.map +0 -3
  406. data/doc/cxxapi/inherit__graph__7.md5 +0 -1
  407. data/doc/cxxapi/inherit__graph__7.png +0 -0
  408. data/doc/cxxapi/inherit__graph__8.map +0 -3
  409. data/doc/cxxapi/inherit__graph__8.md5 +0 -1
  410. data/doc/cxxapi/inherit__graph__8.png +0 -0
  411. data/doc/cxxapi/inherit__graph__9.map +0 -3
  412. data/doc/cxxapi/inherit__graph__9.md5 +0 -1
  413. data/doc/cxxapi/inherit__graph__9.png +0 -0
  414. data/doc/cxxapi/inherits.html +0 -165
  415. data/doc/cxxapi/main.html +0 -28
  416. data/doc/cxxapi/modules.html +0 -36
  417. data/doc/cxxapi/namespacePassenger.html +0 -585
  418. data/doc/cxxapi/namespacemembers.html +0 -190
  419. data/doc/cxxapi/namespacemembers_enum.html +0 -48
  420. data/doc/cxxapi/namespacemembers_eval.html +0 -57
  421. data/doc/cxxapi/namespacemembers_func.html +0 -114
  422. data/doc/cxxapi/namespacemembers_type.html +0 -54
  423. data/doc/cxxapi/namespaces.html +0 -37
  424. data/doc/cxxapi/nginx_2Configuration_8h_source.html +0 -126
  425. data/doc/cxxapi/ngx__http__passenger__module_8h_source.html +0 -95
  426. data/doc/cxxapi/structPassenger_1_1MessageServer_1_1DisconnectEventBroadcastGuard-members.html +0 -36
  427. data/doc/cxxapi/structPassenger_1_1MessageServer_1_1DisconnectEventBroadcastGuard.html +0 -51
  428. data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +0 -67
  429. data/doc/cxxapi/structPassenger_1_1PoolOptions.html +0 -647
  430. data/doc/cxxapi/structPassenger_1_1StaticString_1_1Hash-members.html +0 -36
  431. data/doc/cxxapi/structPassenger_1_1StaticString_1_1Hash.html +0 -51
  432. data/doc/cxxapi/tab_b.gif +0 -0
  433. data/doc/cxxapi/tab_l.gif +0 -0
  434. data/doc/cxxapi/tab_r.gif +0 -0
  435. data/doc/cxxapi/tabs.css +0 -105
  436. data/doc/cxxapi/tree.html +0 -249
  437. data/doc/template/horo.rb +0 -613
  438. data/ext/libev/config.h +0 -122
  439. data/ext/nginx/HttpStatusExtractor.h +0 -351
@@ -41,12 +41,12 @@
41
41
 
42
42
  static ngx_str_t headers_to_hide[] = {
43
43
  /* NOTE: Do not hide the "Status" header; some broken HTTP clients
44
- * expect this header. See http://tinyurl.com/87rezm
44
+ * expect this header. http://code.google.com/p/phusion-passenger/issues/detail?id=177
45
45
  */
46
46
  ngx_string("X-Accel-Expires"),
47
47
  ngx_string("X-Accel-Redirect"),
48
48
  ngx_string("X-Accel-Limit-Rate"),
49
- ngx_string("X-Accel-Buffer"),
49
+ ngx_string("X-Accel-Buffering"),
50
50
  ngx_null_string
51
51
  };
52
52
 
@@ -261,9 +261,6 @@ passenger_create_loc_conf(ngx_conf_t *cf)
261
261
  * conf->upstream_config.location = NULL;
262
262
  * conf->upstream_config.store_lengths = NULL;
263
263
  * conf->upstream_config.store_values = NULL;
264
- *
265
- * conf->index.len = 0;
266
- * conf->index.data = NULL;
267
264
  */
268
265
 
269
266
  conf->enabled = NGX_CONF_UNSET;
@@ -319,6 +316,7 @@ passenger_create_loc_conf(ngx_conf_t *cf)
319
316
  conf->upstream_config.intercept_errors = NGX_CONF_UNSET;
320
317
 
321
318
  conf->upstream_config.cyclic_temp_file = 0;
319
+ conf->upstream_config.change_buffering = 1;
322
320
 
323
321
  #define DEFINE_VAR_TO_PASS(header_name, var_name) \
324
322
  kv = ngx_array_push(conf->vars_source); \
@@ -341,7 +339,6 @@ passenger_create_loc_conf(ngx_conf_t *cf)
341
339
  DEFINE_VAR_TO_PASS("REMOTE_PORT", "$remote_port");
342
340
  DEFINE_VAR_TO_PASS("SERVER_ADDR", "$server_addr");
343
341
  DEFINE_VAR_TO_PASS("SERVER_PORT", "$server_port");
344
- DEFINE_VAR_TO_PASS("SERVER_NAME", "$server_name");
345
342
 
346
343
  return conf;
347
344
  }
@@ -463,7 +460,7 @@ passenger_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
463
460
 
464
461
  if (conf->upstream_config.bufs.num < 2) {
465
462
  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
466
- "there must be at least 2 \"scgi_buffers\"");
463
+ "there must be at least 2 \"passenger_buffers\"");
467
464
  return NGX_CONF_ERROR;
468
465
  }
469
466
 
@@ -487,9 +484,9 @@ passenger_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
487
484
 
488
485
  if (conf->upstream_config.busy_buffers_size < size) {
489
486
  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
490
- "\"scgi_busy_buffers_size\" must be equal or bigger than "
491
- "maximum of the value of \"scgi_buffer_size\" and "
492
- "one of the \"scgi_buffers\"");
487
+ "\"passenger_busy_buffers_size\" must be equal or bigger than "
488
+ "maximum of the value of \"passenger_buffer_size\" and "
489
+ "one of the \"passenger_buffers\"");
493
490
 
494
491
  return NGX_CONF_ERROR;
495
492
  }
@@ -498,8 +495,8 @@ passenger_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
498
495
  > (conf->upstream_config.bufs.num - 1) * conf->upstream_config.bufs.size)
499
496
  {
500
497
  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
501
- "\"scgi_busy_buffers_size\" must be less than "
502
- "the size of all \"scgi_buffers\" minus one buffer");
498
+ "\"passenger_busy_buffers_size\" must be less than "
499
+ "the size of all \"passenger_buffers\" minus one buffer");
503
500
 
504
501
  return NGX_CONF_ERROR;
505
502
  }
@@ -518,9 +515,9 @@ passenger_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
518
515
 
519
516
  if (conf->upstream_config.temp_file_write_size < size) {
520
517
  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
521
- "\"scgi_temp_file_write_size\" must be equal or bigger than "
522
- "maximum of the value of \"scgi_buffer_size\" and "
523
- "one of the \"scgi_buffers\"");
518
+ "\"passenger_temp_file_write_size\" must be equal or bigger than "
519
+ "maximum of the value of \"passenger_buffer_size\" and "
520
+ "one of the \"passenger_buffers\"");
524
521
 
525
522
  return NGX_CONF_ERROR;
526
523
  }
@@ -541,10 +538,10 @@ passenger_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
541
538
  && conf->upstream_config.max_temp_file_size < size)
542
539
  {
543
540
  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
544
- "\"scgi_max_temp_file_size\" must be equal to zero to disable "
541
+ "\"passenger_max_temp_file_size\" must be equal to zero to disable "
545
542
  "the temporary files usage or must be equal or bigger than "
546
- "maximum of the value of \"scgi_buffer_size\" and "
547
- "one of the \"scgi_buffers\"");
543
+ "maximum of the value of \"passenger_buffer_size\" and "
544
+ "one of the \"passenger_buffers\"");
548
545
 
549
546
  return NGX_CONF_ERROR;
550
547
  }
@@ -576,8 +573,6 @@ passenger_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
576
573
 
577
574
 
578
575
 
579
- ngx_conf_merge_str_value(conf->index, prev->index, "");
580
-
581
576
  if (conf->upstream_config.hide_headers == NULL
582
577
  && conf->upstream_config.pass_headers == NULL)
583
578
  {
@@ -951,131 +946,6 @@ set_null_terminated_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
951
946
  return NGX_CONF_OK;
952
947
  }
953
948
 
954
- #if 0
955
- static char *
956
- ngx_http_scgi_lowat_check(ngx_conf_t *cf, void *post, void *data)
957
- {
958
- #if (NGX_FREEBSD)
959
- ssize_t *np = data;
960
-
961
- if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
962
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
963
- "\"scgi_send_lowat\" must be less than %d "
964
- "(sysctl net.inet.tcp.sendspace)",
965
- ngx_freebsd_net_inet_tcp_sendspace);
966
-
967
- return NGX_CONF_ERROR;
968
- }
969
-
970
- #elif !(NGX_HAVE_SO_SNDLOWAT)
971
- ssize_t *np = data;
972
-
973
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
974
- "\"scgi_send_lowat\" is not supported, ignored");
975
-
976
- *np = 0;
977
-
978
- #endif
979
-
980
- return NGX_CONF_OK;
981
- }
982
-
983
- static char *
984
- ngx_http_scgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
985
- {
986
- passenger_loc_conf_t *slcf = conf;
987
-
988
- ngx_str_t *value;
989
- ngx_http_script_compile_t sc;
990
-
991
- if (slcf->upstream.store != NGX_CONF_UNSET || slcf->upstream.store_lengths)
992
- {
993
- return "is duplicate";
994
- }
995
-
996
- value = cf->args->elts;
997
-
998
- if (ngx_strcmp(value[1].data, "on") == 0) {
999
- slcf->upstream.store = 1;
1000
- return NGX_CONF_OK;
1001
- }
1002
-
1003
- if (ngx_strcmp(value[1].data, "off") == 0) {
1004
- slcf->upstream.store = 0;
1005
- return NGX_CONF_OK;
1006
- }
1007
-
1008
- /* include the terminating '\0' into script */
1009
- value[1].len++;
1010
-
1011
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
1012
-
1013
- sc.cf = cf;
1014
- sc.source = &value[1];
1015
- sc.lengths = &slcf->upstream.store_lengths;
1016
- sc.values = &slcf->upstream.store_values;
1017
- sc.variables = ngx_http_script_variables_count(&value[1]);
1018
- sc.complete_lengths = 1;
1019
- sc.complete_values = 1;
1020
-
1021
- if (ngx_http_script_compile(&sc) != NGX_OK) {
1022
- return NGX_CONF_ERROR;
1023
- }
1024
-
1025
- return NGX_CONF_OK;
1026
- }
1027
-
1028
- char *
1029
- ngx_scgi_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1030
- {
1031
- /*
1032
- * Like ngx_conf_set_keyval_slot but keeps the \0 at the end of
1033
- * the strings.
1034
- */
1035
-
1036
- char *p = conf;
1037
-
1038
- ngx_str_t *value;
1039
- ngx_array_t **a;
1040
- ngx_keyval_t *kv;
1041
- ngx_conf_post_t *post;
1042
-
1043
- a = (ngx_array_t **) (p + cmd->offset);
1044
-
1045
- if (*a == NULL) {
1046
- *a = ngx_array_create(cf->pool, 4, sizeof(ngx_keyval_t));
1047
- if (*a == NULL) {
1048
- return NGX_CONF_ERROR;
1049
- }
1050
- }
1051
-
1052
- kv = ngx_array_push(*a);
1053
- if (kv == NULL) {
1054
- return NGX_CONF_ERROR;
1055
- }
1056
-
1057
- value = cf->args->elts;
1058
-
1059
- /* strings are null terminated */
1060
- value[1].len += 1;
1061
- value[2].len += 1;
1062
-
1063
- kv->key = value[1];
1064
- kv->value = value[2];
1065
-
1066
- if (cmd->post) {
1067
- post = cmd->post;
1068
- return post->post_handler(cf, post, kv);
1069
- }
1070
-
1071
- return NGX_CONF_OK;
1072
- }
1073
-
1074
-
1075
- static ngx_conf_post_t ngx_http_scgi_lowat_post =
1076
- { ngx_http_scgi_lowat_check };
1077
-
1078
- #endif /* 0 */
1079
949
 
1080
950
  const ngx_command_t passenger_commands[] = {
1081
951
 
@@ -1331,6 +1201,27 @@ const ngx_command_t passenger_commands[] = {
1331
1201
  offsetof(passenger_loc_conf_t, upstream_config.buffering),
1332
1202
  NULL },
1333
1203
 
1204
+ { ngx_string("passenger_buffer_size"),
1205
+ NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
1206
+ ngx_conf_set_size_slot,
1207
+ NGX_HTTP_LOC_CONF_OFFSET,
1208
+ offsetof(passenger_loc_conf_t, upstream_config.buffer_size),
1209
+ NULL },
1210
+
1211
+ { ngx_string("passenger_buffers"),
1212
+ NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE2,
1213
+ ngx_conf_set_bufs_slot,
1214
+ NGX_HTTP_LOC_CONF_OFFSET,
1215
+ offsetof(passenger_loc_conf_t, upstream_config.bufs),
1216
+ NULL },
1217
+
1218
+ { ngx_string("passenger_busy_buffers_size"),
1219
+ NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
1220
+ ngx_conf_set_size_slot,
1221
+ NGX_HTTP_LOC_CONF_OFFSET,
1222
+ offsetof(passenger_loc_conf_t, upstream_config.busy_buffers_size_conf),
1223
+ NULL },
1224
+
1334
1225
  { ngx_string("passenger_spawn_method"),
1335
1226
  NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_TAKE1,
1336
1227
  ngx_conf_set_str_slot,
@@ -1385,143 +1276,6 @@ const ngx_command_t passenger_commands[] = {
1385
1276
  offsetof(passenger_loc_conf_t, spawn_method),
1386
1277
  NULL },
1387
1278
 
1388
- /*
1389
-
1390
- { ngx_string("scgi_index"),
1391
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
1392
- ngx_conf_set_str_slot,
1393
- NGX_HTTP_LOC_CONF_OFFSET,
1394
- offsetof(passenger_loc_conf_t, index),
1395
- NULL },
1396
-
1397
- { ngx_string("scgi_store"),
1398
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
1399
- ngx_http_scgi_store,
1400
- NGX_HTTP_LOC_CONF_OFFSET,
1401
- 0,
1402
- NULL },
1403
-
1404
- { ngx_string("scgi_store_access"),
1405
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
1406
- ngx_conf_set_access_slot,
1407
- NGX_HTTP_LOC_CONF_OFFSET,
1408
- offsetof(passenger_loc_conf_t, upstream.store_access),
1409
- NULL },
1410
-
1411
- { ngx_string("scgi_ignore_client_abort"),
1412
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
1413
- ngx_conf_set_flag_slot,
1414
- NGX_HTTP_LOC_CONF_OFFSET,
1415
- offsetof(passenger_loc_conf_t, upstream.ignore_client_abort),
1416
- NULL },
1417
-
1418
- { ngx_string("scgi_connect_timeout"),
1419
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
1420
- ngx_conf_set_msec_slot,
1421
- NGX_HTTP_LOC_CONF_OFFSET,
1422
- offsetof(passenger_loc_conf_t, upstream.connect_timeout),
1423
- NULL },
1424
-
1425
- { ngx_string("scgi_send_timeout"),
1426
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
1427
- ngx_conf_set_msec_slot,
1428
- NGX_HTTP_LOC_CONF_OFFSET,
1429
- offsetof(passenger_loc_conf_t, upstream.send_timeout),
1430
- NULL },
1431
-
1432
- { ngx_string("scgi_send_lowat"),
1433
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
1434
- ngx_conf_set_size_slot,
1435
- NGX_HTTP_LOC_CONF_OFFSET,
1436
- offsetof(passenger_loc_conf_t, upstream.send_lowat),
1437
- &ngx_http_scgi_lowat_post },
1438
-
1439
- { ngx_string("scgi_buffer_size"),
1440
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
1441
- ngx_conf_set_size_slot,
1442
- NGX_HTTP_LOC_CONF_OFFSET,
1443
- offsetof(passenger_loc_conf_t, upstream.buffer_size),
1444
- NULL },
1445
-
1446
- { ngx_string("scgi_pass_request_headers"),
1447
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
1448
- ngx_conf_set_flag_slot,
1449
- NGX_HTTP_LOC_CONF_OFFSET,
1450
- offsetof(passenger_loc_conf_t, upstream.pass_request_headers),
1451
- NULL },
1452
-
1453
- { ngx_string("scgi_pass_request_body"),
1454
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
1455
- ngx_conf_set_flag_slot,
1456
- NGX_HTTP_LOC_CONF_OFFSET,
1457
- offsetof(passenger_loc_conf_t, upstream.pass_request_body),
1458
- NULL },
1459
-
1460
- { ngx_string("scgi_intercept_errors"),
1461
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
1462
- ngx_conf_set_flag_slot,
1463
- NGX_HTTP_LOC_CONF_OFFSET,
1464
- offsetof(passenger_loc_conf_t, upstream.intercept_errors),
1465
- NULL },
1466
-
1467
- { ngx_string("scgi_read_timeout"),
1468
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
1469
- ngx_conf_set_msec_slot,
1470
- NGX_HTTP_LOC_CONF_OFFSET,
1471
- offsetof(passenger_loc_conf_t, upstream.read_timeout),
1472
- NULL },
1473
-
1474
- { ngx_string("scgi_buffers"),
1475
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
1476
- ngx_conf_set_bufs_slot,
1477
- NGX_HTTP_LOC_CONF_OFFSET,
1478
- offsetof(passenger_loc_conf_t, upstream.bufs),
1479
- NULL },
1480
-
1481
- { ngx_string("scgi_busy_buffers_size"),
1482
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
1483
- ngx_conf_set_size_slot,
1484
- NGX_HTTP_LOC_CONF_OFFSET,
1485
- offsetof(passenger_loc_conf_t, upstream.busy_buffers_size_conf),
1486
- NULL },
1487
-
1488
- { ngx_string("scgi_temp_path"),
1489
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
1490
- ngx_conf_set_path_slot,
1491
- NGX_HTTP_LOC_CONF_OFFSET,
1492
- offsetof(passenger_loc_conf_t, upstream.temp_path),
1493
- (void *) ngx_garbage_collector_temp_handler },
1494
-
1495
- { ngx_string("scgi_max_temp_file_size"),
1496
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
1497
- ngx_conf_set_size_slot,
1498
- NGX_HTTP_LOC_CONF_OFFSET,
1499
- offsetof(passenger_loc_conf_t, upstream.max_temp_file_size_conf),
1500
- NULL },
1501
-
1502
- { ngx_string("scgi_temp_file_write_size"),
1503
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
1504
- ngx_conf_set_size_slot,
1505
- NGX_HTTP_LOC_CONF_OFFSET,
1506
- offsetof(passenger_loc_conf_t, upstream.temp_file_write_size_conf),
1507
- NULL },
1508
-
1509
- { ngx_string("scgi_var"),
1510
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
1511
- ngx_scgi_set_keyval_slot,
1512
- NGX_HTTP_LOC_CONF_OFFSET,
1513
- offsetof(passenger_loc_conf_t, vars_source),
1514
- NULL },
1515
-
1516
- { ngx_string("scgi_hide_header"),
1517
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
1518
- ngx_conf_set_str_array_slot,
1519
- NGX_HTTP_LOC_CONF_OFFSET,
1520
- offsetof(passenger_loc_conf_t, upstream.hide_headers),
1521
- NULL },
1522
-
1523
- */
1524
-
1525
1279
  ngx_null_command
1526
1280
  };
1527
1281
 
@@ -321,12 +321,14 @@ create_request(ngx_http_request_t *r)
321
321
  size_t len, size, key_len, val_len, content_length;
322
322
  const u_char *app_type_string;
323
323
  size_t app_type_string_len;
324
+ int server_name_len;
324
325
  ngx_str_t escaped_uri;
325
326
  ngx_str_t *union_station_filters = NULL;
326
327
  u_char min_instances_string[12];
327
328
  u_char framework_spawner_idle_time_string[12];
328
329
  u_char app_spawner_idle_time_string[12];
329
330
  u_char *end;
331
+ void *tmp;
330
332
  ngx_uint_t i, n;
331
333
  ngx_buf_t *b;
332
334
  ngx_chain_t *cl, *body;
@@ -412,6 +414,15 @@ create_request(ngx_http_request_t *r)
412
414
  len += 1 + r->args.len;
413
415
  }
414
416
 
417
+ /* SERVER_NAME; must be equal to HTTP_HOST without the port part */
418
+ tmp = memchr(r->headers_in.host->value.data, ':', r->headers_in.host->value.len);
419
+ if (tmp == NULL) {
420
+ server_name_len = r->headers_in.host->value.len;
421
+ } else {
422
+ server_name_len = (int) ((const u_char *) tmp - r->headers_in.host->value.data);
423
+ }
424
+ len += sizeof("SERVER_NAME") + server_name_len + 1;
425
+
415
426
  /* Various other HTTP headers. */
416
427
  if (r->headers_in.content_type != NULL
417
428
  && r->headers_in.content_type->value.len > 0) {
@@ -637,6 +648,12 @@ create_request(ngx_http_request_t *r)
637
648
  }
638
649
  b->last = ngx_copy(b->last, "", 1);
639
650
 
651
+ /* SERVER_NAME */
652
+ b->last = ngx_copy(b->last, "SERVER_NAME", sizeof("SERVER_NAME"));
653
+ b->last = ngx_copy(b->last, r->headers_in.host->value.data,
654
+ server_name_len);
655
+ b->last = ngx_copy(b->last, "", 1);
656
+
640
657
  /* Various other HTTP headers. */
641
658
  if (r->headers_in.content_type != NULL
642
659
  && r->headers_in.content_type->value.len > 0) {
@@ -28,8 +28,9 @@
28
28
  #include <sys/stat.h>
29
29
  #include <sys/un.h>
30
30
  #include <cstring>
31
+ #include <cassert>
32
+ #include <cerrno>
31
33
  #include <unistd.h>
32
- #include <errno.h>
33
34
  #include <limits.h>
34
35
  #include <pwd.h>
35
36
  #include <grp.h>
@@ -44,7 +45,6 @@
44
45
  #include "oxt/system_calls.hpp"
45
46
 
46
47
  #include "ScgiRequestParser.h"
47
- #include "HttpStatusExtractor.h"
48
48
 
49
49
  #include "AgentBase.h"
50
50
  #include "HelperAgent/BacktracesServer.h"
@@ -60,6 +60,9 @@
60
60
  #include "Exceptions.h"
61
61
  #include "Utils.h"
62
62
  #include "Utils/Timer.h"
63
+ #include <Utils/Dechunker.h>
64
+ #include <Utils/HttpHeaderBufferer.h>
65
+ #include <Utils/StreamBoyerMooreHorspool.h>
63
66
 
64
67
  using namespace boost;
65
68
  using namespace oxt;
@@ -67,6 +70,9 @@ using namespace Passenger;
67
70
 
68
71
  #define REQUEST_SOCKET_PASSWORD_SIZE 64
69
72
 
73
+ static StreamBMH_Occ statusFinder_occ;
74
+ static StreamBMH_Occ transferEncodingFinder_occ;
75
+
70
76
  struct ClientDisconnectedException { };
71
77
 
72
78
  class ExitHandler: public MessageServer::Handler {
@@ -150,6 +156,267 @@ private:
150
156
  */
151
157
  Timer inactivityTimer;
152
158
 
159
+ int currentClient;
160
+ HttpHeaderBufferer headerBufferer;
161
+ union {
162
+ struct StreamBMH ctx;
163
+ char padding[SBMH_SIZE(sizeof("Status:") - 1)];
164
+ } statusFinder;
165
+ union {
166
+ struct StreamBMH ctx;
167
+ char padding[SBMH_SIZE(sizeof("Transfer-Encoding:") - 1)];
168
+ } transferEncodingFinder;
169
+
170
+ /** Given a substring containing the start of the header value,
171
+ * extracts the substring that contains a single header value.
172
+ *
173
+ * const char *data =
174
+ * "Status: 200 OK\r\n"
175
+ * "Foo: bar\r\n";
176
+ * extractHeaderValue(data + strlen("Status:"), strlen(data) - strlen("Status:"));
177
+ * // "200 OK"
178
+ */
179
+ static StaticString extractHeaderValue(const char *data, size_t size) {
180
+ const char *start = data;
181
+ const char *end = data + size;
182
+ const char *terminator;
183
+
184
+ while (start < end && *start == ' ') {
185
+ start++;
186
+ }
187
+
188
+ terminator = (const char *) memchr(start, '\r', end - start);
189
+ if (terminator == NULL) {
190
+ return StaticString();
191
+ } else {
192
+ return StaticString(start, terminator - start);
193
+ }
194
+ }
195
+
196
+ StaticString extractAndSanitizeHttpStatus(const StaticString &header, char buf[32]) {
197
+ StaticString status;
198
+ size_t accepted;
199
+
200
+ sbmh_reset(&statusFinder.ctx);
201
+ accepted = sbmh_feed(&statusFinder.ctx,
202
+ &statusFinder_occ,
203
+ (const unsigned char *) "Status:",
204
+ sizeof("Status:") - 1,
205
+ (const unsigned char *) header.data(),
206
+ header.size());
207
+ if (statusFinder.ctx.found) {
208
+ status = extractHeaderValue(header.data() + accepted,
209
+ header.size() - accepted);
210
+ if (status.find(' ') == string::npos) {
211
+ int code = stringToInt(status);
212
+ switch (code) {
213
+ case 100:
214
+ status = "100 Continue";
215
+ break;
216
+ case 101:
217
+ status = "101 Switching Protocols";
218
+ break;
219
+ case 102:
220
+ status = "102 Processing";
221
+ break;
222
+ case 200:
223
+ status = "200 OK";
224
+ break;
225
+ case 201:
226
+ status = "201 Created";
227
+ break;
228
+ case 202:
229
+ status = "202 Accepted";
230
+ break;
231
+ case 203:
232
+ status = "203 Non-Authoritative Information";
233
+ break;
234
+ case 204:
235
+ status = "204 No Content";
236
+ break;
237
+ case 205:
238
+ status = "205 Reset Content";
239
+ break;
240
+ case 206:
241
+ status = "206 Partial Content";
242
+ break;
243
+ case 207:
244
+ status = "207 Multi-Status";
245
+ break;
246
+ case 300:
247
+ status = "300 Multiple Choices";
248
+ break;
249
+ case 301:
250
+ status = "301 Moved Permanently";
251
+ break;
252
+ case 302:
253
+ status = "302 Found";
254
+ break;
255
+ case 303:
256
+ status = "303 See Other";
257
+ break;
258
+ case 304:
259
+ status = "304 Not Modified";
260
+ break;
261
+ case 305:
262
+ status = "305 Use Proxy";
263
+ break;
264
+ case 306:
265
+ status = "306 Switch Proxy";
266
+ break;
267
+ case 307:
268
+ status = "307 Temporary Redirect";
269
+ break;
270
+ case 308:
271
+ // Google Gears: http://code.google.com/p/gears/wiki/ResumableHttpRequestsProposal
272
+ status = "308 Resume Incomplete";
273
+ break;
274
+ case 400:
275
+ status = "400 Bad Request";
276
+ break;
277
+ case 401:
278
+ status = "401 Unauthorized";
279
+ break;
280
+ case 402:
281
+ status = "402 Payment Required";
282
+ break;
283
+ case 403:
284
+ status = "403 Forbidden";
285
+ break;
286
+ case 404:
287
+ status = "404 Not Found";
288
+ break;
289
+ case 405:
290
+ status = "405 Method Not Allowed";
291
+ break;
292
+ case 406:
293
+ status = "406 Not Acceptable";
294
+ break;
295
+ case 407:
296
+ status = "407 Proxy Authentication Required";
297
+ break;
298
+ case 408:
299
+ status = "408 Request Timeout";
300
+ break;
301
+ case 409:
302
+ status = "409 Conflict";
303
+ break;
304
+ case 410:
305
+ status = "410 Gone";
306
+ break;
307
+ case 411:
308
+ status = "411 Length Required";
309
+ break;
310
+ case 412:
311
+ status = "412 Precondition Failed";
312
+ break;
313
+ case 413:
314
+ status = "413 Request Entity Too Large";
315
+ break;
316
+ case 414:
317
+ status = "414 Request-URI Too Long";
318
+ break;
319
+ case 415:
320
+ status = "415 Unsupported Media Type";
321
+ break;
322
+ case 416:
323
+ status = "416 Requested Range Not Satisfiable";
324
+ break;
325
+ case 417:
326
+ status = "417 Expectation Failed";
327
+ break;
328
+ case 418:
329
+ status = "418 Not A Funny April Fools Joke";
330
+ break;
331
+ case 422:
332
+ status = "422 Unprocessable Entity";
333
+ break;
334
+ case 423:
335
+ status = "423 Locked";
336
+ break;
337
+ case 424:
338
+ status = "424 Unordered Collection";
339
+ break;
340
+ case 426:
341
+ status = "426 Upgrade Required";
342
+ break;
343
+ case 449:
344
+ status = "449 Retry With";
345
+ break;
346
+ case 450:
347
+ status = "450 Blocked";
348
+ break;
349
+ case 500:
350
+ status = "500 Internal Server Error";
351
+ break;
352
+ case 501:
353
+ status = "501 Not Implemented";
354
+ break;
355
+ case 502:
356
+ status = "502 Bad Gateway";
357
+ break;
358
+ case 503:
359
+ status = "503 Service Unavailable";
360
+ break;
361
+ case 504:
362
+ status = "504 Gateway Timeout";
363
+ break;
364
+ case 505:
365
+ status = "505 HTTP Version Not Supported";
366
+ break;
367
+ case 506:
368
+ status = "506 Variant Also Negotiates";
369
+ break;
370
+ case 507:
371
+ status = "507 Insufficient Storage";
372
+ break;
373
+ case 509:
374
+ status = "509 Bandwidth Limit Exceeded";
375
+ break;
376
+ case 510:
377
+ status = "510 Not Extended";
378
+ break;
379
+ default:
380
+ snprintf(buf, 32,
381
+ "%d Unknown Status Code",
382
+ code);
383
+ buf[31] = '\0';
384
+ status = buf;
385
+ }
386
+ }
387
+ } else {
388
+ status = "200 OK";
389
+ }
390
+
391
+ return status;
392
+ }
393
+
394
+ bool detectChunkedTransferEncodingAndRemoveHeader(const StaticString &header) {
395
+ size_t accepted;
396
+
397
+ sbmh_reset(&transferEncodingFinder.ctx);
398
+ accepted = sbmh_feed(&transferEncodingFinder.ctx,
399
+ &transferEncodingFinder_occ,
400
+ (const unsigned char *) "Transfer-Encoding:",
401
+ sizeof("Transfer-Encoding:") - 1,
402
+ (const unsigned char *) header.data(),
403
+ header.size());
404
+ if (transferEncodingFinder.ctx.found) {
405
+ StaticString value = extractHeaderValue(header.data() + accepted,
406
+ header.size() - accepted);
407
+ if (value == "chunked") {
408
+ // Remove Transfer-Encoding header.
409
+ char *tmp = (char *) (header.data() + accepted - 2);
410
+ *tmp = '_';
411
+ return true;
412
+ } else {
413
+ return false;
414
+ }
415
+ } else {
416
+ return false;
417
+ }
418
+ }
419
+
153
420
  /**
154
421
  * Attempts to accept a connection made by the client.
155
422
  *
@@ -317,52 +584,114 @@ private:
317
584
  const AnalyticsLogPtr &log)
318
585
  {
319
586
  TRACE_POINT();
320
- HttpStatusExtractor ex;
321
587
  int stream = session->getStream();
322
588
  int eof = false;
323
- char buf[1024 * 32];
589
+ char buf[1024 * 24];
590
+ size_t accepted;
324
591
  ssize_t size;
592
+ bool chunked = false;
593
+ Dechunker dechunker;
325
594
 
326
- /* Read data from the backend process until we're able to
327
- * extract the HTTP status line from it.
595
+ currentClient = clientFd;
596
+
597
+ /* Read data from the backend process until we
598
+ * have at least an entire response header, or
599
+ * until some error occurred.
328
600
  */
329
- while (!eof) {
601
+ headerBufferer.reset();
602
+ while (!eof && headerBufferer.acceptingInput()) {
330
603
  UPDATE_TRACE_POINT();
331
604
  size = syscalls::read(stream, buf, sizeof(buf));
332
605
  if (size == 0) {
333
606
  eof = true;
334
607
  } else if (size == -1) {
335
608
  throw SystemException("Cannot read response from backend process", errno);
336
- } else if (ex.feed(buf, size)) {
337
- /* We now have an HTTP status line. Send back
338
- * a proper HTTP response, then exit this while
339
- * loop and continue with forwarding the rest
340
- * of the response data.
341
- */
609
+ } else {
610
+ accepted = headerBufferer.feed(buf, size);
611
+ }
612
+ }
613
+
614
+ /* Now process the response header as well as whatever part of the
615
+ * response body we've already received.
616
+ */
617
+ if (!headerBufferer.acceptingInput() && !headerBufferer.hasError()) {
618
+ UPDATE_TRACE_POINT();
619
+ assert(!eof);
620
+ StaticString headerData = headerBufferer.getData();
621
+ StaticString nonHeaderData(buf + accepted, size - accepted);
622
+ StaticString status;
623
+ char statusTmp[32];
624
+
625
+ status = extractAndSanitizeHttpStatus(headerData, statusTmp);
626
+ /* Nginx's proxy_module doesn't support HTTP 1.1 chunked
627
+ * transfer encoding so we need to strip that header and
628
+ * dechunk the data before passing to Nginx.
629
+ */
630
+ chunked = detectChunkedTransferEncodingAndRemoveHeader(headerData);
631
+
632
+ if (!log->isNull()) {
342
633
  UPDATE_TRACE_POINT();
343
- try {
344
- string statusLine("HTTP/1.1 ");
345
- statusLine.append(ex.getStatusLine());
346
- UPDATE_TRACE_POINT();
347
- writeExact(clientFd, statusLine);
348
- UPDATE_TRACE_POINT();
349
- writeExact(clientFd, ex.getBuffer());
350
- if (!log->isNull()) {
351
- string partialStatusLine = ex.getStatusLine();
352
- partialStatusLine.erase(partialStatusLine.size() - 2, 2);
353
- log->message("Status: " + partialStatusLine);
354
- }
355
- break;
356
- } catch (const SystemException &e) {
357
- if (e.code() == EPIPE) {
358
- throw ClientDisconnectedException();
359
- } else {
360
- throw;
361
- }
634
+ log->message("Status: " + status);
635
+ }
636
+
637
+ UPDATE_TRACE_POINT();
638
+
639
+ StaticString parts[6];
640
+ unsigned int nparts = 0;
641
+ parts[nparts++] = "HTTP/1.1 ";
642
+ parts[nparts++] = status;
643
+ if (chunked) {
644
+ P_TRACE(2, "Chunked response detected");
645
+ // Disable Nginx response buffering.
646
+ parts[nparts++] = "\r\nX-Accel-Buffering: no\r\n";
647
+ } else {
648
+ parts[nparts++] = "\r\n";
649
+ }
650
+ parts[nparts++] = headerData;
651
+ if (!chunked) {
652
+ // If the response doesn't have the chunked transfer encoding
653
+ // then forward the beginning of the response body as-in.
654
+ // Otherwise we have to filter it through the dechunker.
655
+ parts[nparts++] = nonHeaderData;
656
+ }
657
+
658
+ try {
659
+ gatheredWrite(clientFd, parts, nparts);
660
+ } catch (const SystemException &e) {
661
+ if (e.code() == EPIPE) {
662
+ throw ClientDisconnectedException();
663
+ } else {
664
+ throw;
362
665
  }
363
666
  }
667
+
668
+ if (chunked) {
669
+ dechunker.onData = forwardResponseChunk;
670
+ dechunker.userData = this;
671
+ dechunker.feed(nonHeaderData.data(), nonHeaderData.size());
672
+ if (dechunker.hasError()) {
673
+ P_ERROR("The backend process's chunked response is not valid (" <<
674
+ dechunker.getErrorMessage() << ")");
675
+ return;
676
+ }
677
+ }
678
+
679
+ } else if (!headerBufferer.acceptingInput()) {
680
+ // Error: header too large.
681
+ assert(!eof);
682
+ assert(headerBufferer.hasError());
683
+ P_ERROR("The backend process's HTTP response header is too large. "
684
+ "For security reasons Phusion Passenger doesn't allow response "
685
+ "headers larger than 128 KB.");
686
+ return;
687
+
688
+ } else {
689
+ // Error: incomplete header.
690
+ assert(eof);
691
+ return;
364
692
  }
365
693
 
694
+ /* Forward remaining response body. */
366
695
  UPDATE_TRACE_POINT();
367
696
  while (!eof) {
368
697
  UPDATE_TRACE_POINT();
@@ -373,17 +702,35 @@ private:
373
702
  throw SystemException("Cannot read response from backend process", errno);
374
703
  } else {
375
704
  UPDATE_TRACE_POINT();
376
- try {
377
- writeExact(clientFd, buf, size);
378
- } catch (const SystemException &e) {
379
- if (e.code() == EPIPE) {
380
- throw ClientDisconnectedException();
381
- } else {
382
- throw;
705
+ if (chunked) {
706
+ dechunker.feed(buf, size);
707
+ if (dechunker.hasError()) {
708
+ P_ERROR("The backend process's chunked response is not valid (" <<
709
+ dechunker.getErrorMessage() << ")");
710
+ return;
383
711
  }
712
+ } else {
713
+ forwardResponseChunk(buf, size, this);
384
714
  }
385
715
  }
386
716
  }
717
+
718
+ if (chunked && dechunker.acceptingInput()) {
719
+ P_WARN("The backend process's chunked response lacks a terminating chunk.");
720
+ }
721
+ }
722
+
723
+ static void forwardResponseChunk(const char *data, size_t size, void *userData) {
724
+ Client *self = (Client *) userData;
725
+ try {
726
+ writeExact(self->currentClient, data, size);
727
+ } catch (const SystemException &e) {
728
+ if (e.code() == EPIPE) {
729
+ throw ClientDisconnectedException();
730
+ } else {
731
+ throw;
732
+ }
733
+ }
387
734
  }
388
735
 
389
736
  /**
@@ -640,6 +987,10 @@ public:
640
987
  this->defaultGroup = defaultGroup;
641
988
  this->serverSocket = serverSocket;
642
989
  this->analyticsLogger = logger;
990
+
991
+ sbmh_init(&statusFinder.ctx, NULL, NULL, 0);
992
+ sbmh_init(&transferEncodingFinder.ctx, NULL, NULL, 0);
993
+
643
994
  thr = new oxt::thread(
644
995
  boost::bind(&Client::threadMain, this),
645
996
  "Client thread " + toString(number),
@@ -827,6 +1178,13 @@ public:
827
1178
  feedbackChannel = MessageChannel(feedbackFd);
828
1179
  numberOfThreads = maxPoolSize * 4;
829
1180
 
1181
+ sbmh_init(NULL, &statusFinder_occ,
1182
+ (const unsigned char *) "Status:",
1183
+ strlen("Status:"));
1184
+ sbmh_init(NULL, &transferEncodingFinder_occ,
1185
+ (const unsigned char *) "Transfer-Encoding:",
1186
+ strlen("Transfer-Encoding:"));
1187
+
830
1188
  UPDATE_TRACE_POINT();
831
1189
  requestSocketPassword = Base64::decode(options.get("request_socket_password"));
832
1190
  messageSocketPassword = Base64::decode(options.get("message_socket_password"));