passenger 4.0.48 → 4.0.49

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 (218) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/.editorconfig +36 -2
  5. data/.travis.yml +1 -1
  6. data/CHANGELOG +16 -0
  7. data/Rakefile +0 -1
  8. data/build/apache2.rb +4 -4
  9. data/build/common_library.rb +18 -18
  10. data/build/cplusplus_support.rb +2 -2
  11. data/build/documentation.rb +1 -1
  12. data/build/integration_tests.rb +12 -4
  13. data/build/misc.rb +12 -7
  14. data/build/packaging.rb +14 -14
  15. data/build/preprocessor.rb +10 -10
  16. data/build/rake_extensions.rb +11 -11
  17. data/build/ruby_extension.rb +2 -2
  18. data/dev/ci/inituidgid +24 -0
  19. data/dev/ci/run_jenkins.sh +57 -0
  20. data/dev/ci/run_rpm_tests.sh +77 -0
  21. data/dev/{run_travis.sh → ci/run_travis.sh} +60 -4
  22. data/doc/Users guide Nginx.txt +2 -2
  23. data/doc/users_guide_snippets/environment_variables.txt +0 -2
  24. data/doc/users_guide_snippets/tips.txt +20 -1
  25. data/ext/apache2/Bucket.cpp +18 -18
  26. data/ext/apache2/Bucket.h +4 -4
  27. data/ext/apache2/Configuration.cpp +7 -7
  28. data/ext/apache2/Configuration.hpp +43 -43
  29. data/ext/apache2/DirectoryMapper.h +5 -5
  30. data/ext/apache2/Hooks.cpp +142 -142
  31. data/ext/apache2/MergeDirConfig.cpp +40 -40
  32. data/ext/common/Account.h +17 -17
  33. data/ext/common/AccountsDatabase.h +9 -9
  34. data/ext/common/AgentsStarter.cpp +2 -2
  35. data/ext/common/AgentsStarter.h +40 -40
  36. data/ext/common/ApplicationPool2/Common.h +10 -6
  37. data/ext/common/ApplicationPool2/ComponentInfo.h +2 -2
  38. data/ext/common/ApplicationPool2/DirectSpawner.h +17 -17
  39. data/ext/common/ApplicationPool2/DummySpawner.h +5 -5
  40. data/ext/common/ApplicationPool2/Group.h +54 -38
  41. data/ext/common/ApplicationPool2/Implementation.cpp +76 -49
  42. data/ext/common/ApplicationPool2/Options.h +98 -91
  43. data/ext/common/ApplicationPool2/Pool.h +70 -69
  44. data/ext/common/ApplicationPool2/Process.h +21 -21
  45. data/ext/common/ApplicationPool2/Session.h +11 -11
  46. data/ext/common/ApplicationPool2/SmartSpawner.h +60 -60
  47. data/ext/common/ApplicationPool2/Socket.h +19 -19
  48. data/ext/common/ApplicationPool2/Spawner.h +64 -72
  49. data/ext/common/ApplicationPool2/SpawnerFactory.h +4 -4
  50. data/ext/common/ApplicationPool2/SuperGroup.h +41 -41
  51. data/ext/common/BackgroundEventLoop.cpp +1 -1
  52. data/ext/common/BackgroundEventLoop.h +2 -2
  53. data/ext/common/Constants.h +1 -1
  54. data/ext/common/EventedBufferedInput.h +5 -5
  55. data/ext/common/EventedClient.h +51 -51
  56. data/ext/common/EventedMessageServer.h +39 -39
  57. data/ext/common/EventedServer.h +32 -32
  58. data/ext/common/Exceptions.h +23 -23
  59. data/ext/common/FileDescriptor.h +18 -18
  60. data/ext/common/Logging.cpp +1 -1
  61. data/ext/common/MessageClient.h +27 -27
  62. data/ext/common/MessageReadersWriters.h +79 -79
  63. data/ext/common/MessageServer.h +59 -59
  64. data/ext/common/RandomGenerator.h +12 -12
  65. data/ext/common/ResourceLocator.h +8 -8
  66. data/ext/common/SafeLibev.h +54 -25
  67. data/ext/common/ServerInstanceDir.h +31 -31
  68. data/ext/common/StaticString.h +50 -48
  69. data/ext/common/Utils.cpp +73 -78
  70. data/ext/common/Utils.h +6 -6
  71. data/ext/common/Utils/Base64.cpp +3 -3
  72. data/ext/common/Utils/Base64.h +7 -7
  73. data/ext/common/Utils/BlockingQueue.h +9 -9
  74. data/ext/common/Utils/BufferedIO.h +17 -17
  75. data/ext/common/Utils/CachedFileStat.hpp +16 -16
  76. data/ext/common/Utils/Dechunker.h +25 -25
  77. data/ext/common/Utils/FileChangeChecker.h +10 -10
  78. data/ext/common/Utils/MemZeroGuard.h +5 -5
  79. data/ext/common/Utils/MemoryBarrier.h +1 -1
  80. data/ext/common/Utils/MessageIO.h +61 -61
  81. data/ext/common/Utils/ProcessMetricsCollector.h +40 -40
  82. data/ext/common/Utils/ScopeGuard.h +7 -7
  83. data/ext/common/Utils/SpeedMeter.h +1 -1
  84. data/ext/common/Utils/StrIntUtils.cpp +13 -13
  85. data/ext/common/Utils/StrIntUtils.h +3 -3
  86. data/ext/common/Utils/StringScanning.h +5 -5
  87. data/ext/common/Utils/SystemMetricsCollector.h +2 -2
  88. data/ext/common/Utils/SystemTime.h +10 -10
  89. data/ext/common/Utils/Template.h +2 -2
  90. data/ext/common/Utils/Timer.h +6 -6
  91. data/ext/common/Utils/VariantMap.h +29 -29
  92. data/ext/common/agents/Base.cpp +19 -19
  93. data/ext/common/agents/HelperAgent/AgentOptions.h +1 -1
  94. data/ext/common/agents/HelperAgent/FileBackedPipe.h +6 -6
  95. data/ext/common/agents/HelperAgent/Main.cpp +44 -43
  96. data/ext/common/agents/HelperAgent/RequestHandler.cpp +4 -4
  97. data/ext/common/agents/HelperAgent/RequestHandler.h +29 -28
  98. data/ext/common/agents/HelperAgent/ScgiRequestParser.h +56 -50
  99. data/ext/common/agents/LoggingAgent/AdminController.h +8 -8
  100. data/ext/common/agents/LoggingAgent/DataStoreId.h +17 -17
  101. data/ext/common/agents/LoggingAgent/FilterSupport.h +167 -167
  102. data/ext/common/agents/LoggingAgent/LoggingServer.h +122 -122
  103. data/ext/common/agents/LoggingAgent/Main.cpp +7 -7
  104. data/ext/common/agents/LoggingAgent/RemoteSender.h +54 -54
  105. data/ext/common/agents/SpawnPreparer.cpp +4 -4
  106. data/ext/common/agents/TempDirToucher.c +2 -2
  107. data/ext/common/agents/Watchdog/AgentWatcher.cpp +47 -47
  108. data/ext/common/agents/Watchdog/HelperAgentWatcher.cpp +7 -7
  109. data/ext/common/agents/Watchdog/LoggingAgentWatcher.cpp +7 -7
  110. data/ext/common/agents/Watchdog/Main.cpp +22 -22
  111. data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +9 -9
  112. data/ext/libeio/eio.c +1 -1
  113. data/ext/nginx/Configuration.c +30 -30
  114. data/ext/nginx/Configuration.h +1 -1
  115. data/ext/nginx/ContentHandler.c +54 -54
  116. data/ext/nginx/ContentHandler.h +3 -3
  117. data/ext/nginx/StaticContentHandler.c +2 -2
  118. data/ext/nginx/ngx_http_passenger_module.c +21 -21
  119. data/ext/oxt/detail/backtrace_enabled.hpp +1 -1
  120. data/ext/oxt/detail/context.hpp +1 -1
  121. data/ext/oxt/detail/spin_lock_darwin.hpp +4 -4
  122. data/ext/oxt/detail/spin_lock_gcc_x86.hpp +3 -3
  123. data/ext/oxt/detail/spin_lock_pthreads.hpp +4 -4
  124. data/ext/oxt/detail/tracable_exception_disabled.hpp +1 -1
  125. data/ext/oxt/dynamic_thread_group.hpp +18 -18
  126. data/ext/oxt/implementation.cpp +9 -8
  127. data/ext/oxt/macros.hpp +2 -2
  128. data/ext/oxt/system_calls.cpp +11 -11
  129. data/ext/oxt/system_calls.hpp +13 -13
  130. data/ext/oxt/thread.hpp +22 -14
  131. data/ext/ruby/passenger_native_support.c +55 -55
  132. data/lib/phusion_passenger.rb +24 -24
  133. data/lib/phusion_passenger/common_library.rb +2 -0
  134. data/lib/phusion_passenger/loader_shared_helpers.rb +18 -18
  135. data/lib/phusion_passenger/packaging.rb +9 -4
  136. data/lib/phusion_passenger/platform_info/apache.rb +45 -31
  137. data/lib/phusion_passenger/platform_info/compiler.rb +11 -11
  138. data/lib/phusion_passenger/rack/thread_handler_extension.rb +1 -1
  139. data/lib/phusion_passenger/request_handler/thread_handler.rb +8 -8
  140. data/lib/phusion_passenger/standalone/app_finder.rb +16 -16
  141. data/lib/phusion_passenger/standalone/command.rb +22 -22
  142. data/packaging/rpm/LICENSE.txt +19 -0
  143. data/packaging/rpm/Makefile +13 -0
  144. data/packaging/rpm/README.md +41 -0
  145. data/packaging/rpm/Vagrantfile +38 -0
  146. data/{rpm/Vagrantfile → packaging/rpm/Vagrantfile.centos} +0 -0
  147. data/packaging/rpm/build +170 -0
  148. data/packaging/rpm/create_project +41 -0
  149. data/packaging/rpm/git_update +88 -0
  150. data/packaging/rpm/image/Dockerfile +37 -0
  151. data/packaging/rpm/image/Gemfile +3 -0
  152. data/packaging/rpm/image/Gemfile.lock +12 -0
  153. data/packaging/rpm/image/RPM-GPG-KEY-amazon-ga +19 -0
  154. data/packaging/rpm/image/amazon2014-i386.cfg +96 -0
  155. data/packaging/rpm/image/amazon2014-x86_64.cfg +96 -0
  156. data/packaging/rpm/image/site-defaults.cfg +168 -0
  157. data/packaging/rpm/internal/build_tasks.rb +238 -0
  158. data/packaging/rpm/internal/dummygpg +11 -0
  159. data/packaging/rpm/internal/exec_build +42 -0
  160. data/packaging/rpm/internal/get_distro_arch +14 -0
  161. data/packaging/rpm/internal/get_distro_id +10 -0
  162. data/packaging/rpm/internal/git_update +27 -0
  163. data/packaging/rpm/internal/inituidgid +17 -0
  164. data/packaging/rpm/internal/my_init +344 -0
  165. data/packaging/rpm/internal/python27 +3 -0
  166. data/packaging/rpm/internal/repo_update +46 -0
  167. data/packaging/rpm/internal/setuser +26 -0
  168. data/packaging/rpm/internal/tracking_helper +40 -0
  169. data/packaging/rpm/jenkins_release +99 -0
  170. data/packaging/rpm/lib/build_tasks_support.rb +402 -0
  171. data/packaging/rpm/lib/preprocessor.rb +341 -0
  172. data/packaging/rpm/nginx_spec/404.html +119 -0
  173. data/packaging/rpm/nginx_spec/50x.html +119 -0
  174. data/packaging/rpm/nginx_spec/index.html +116 -0
  175. data/packaging/rpm/nginx_spec/nginx-auto-cc-gcc.patch +13 -0
  176. data/packaging/rpm/nginx_spec/nginx-logo.png +0 -0
  177. data/packaging/rpm/nginx_spec/nginx-upgrade +13 -0
  178. data/packaging/rpm/nginx_spec/nginx-upgrade.8 +151 -0
  179. data/packaging/rpm/nginx_spec/nginx.conf +131 -0
  180. data/packaging/rpm/nginx_spec/nginx.init +144 -0
  181. data/packaging/rpm/nginx_spec/nginx.logrotate +13 -0
  182. data/packaging/rpm/nginx_spec/nginx.service +15 -0
  183. data/packaging/rpm/nginx_spec/nginx.spec.template +559 -0
  184. data/packaging/rpm/nginx_spec/nginx.sysconfig +4 -0
  185. data/packaging/rpm/nginx_spec/passenger.conf +9 -0
  186. data/packaging/rpm/nginx_spec/poweredby.png +0 -0
  187. data/{rpm → packaging/rpm/passenger_spec}/apache-passenger.conf.in +0 -0
  188. data/{rpm → packaging/rpm/passenger_spec}/config.json +0 -0
  189. data/{rpm → packaging/rpm/passenger_spec}/passenger.logrotate +0 -0
  190. data/{rpm → packaging/rpm/passenger_spec}/passenger.spec.template +58 -31
  191. data/{rpm → packaging/rpm/passenger_spec}/passenger_dynamic_thread_group.patch +0 -0
  192. data/{rpm → packaging/rpm/passenger_spec}/passenger_tests_default_config_example.patch +0 -0
  193. data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-GLIBC_HAVE_LONG_LONG.patch +0 -0
  194. data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-gcc47-include-sys_types.patch +0 -0
  195. data/packaging/rpm/repo_update +114 -0
  196. data/packaging/rpm/setup-system +60 -0
  197. data/packaging/rpm/shell +10 -0
  198. data/resources/templates/standalone/config.erb +3 -1
  199. data/test/config.json.rpm-automation +1 -1
  200. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +11 -11
  201. data/test/cxx/ApplicationPool2/OptionsTest.cpp +5 -5
  202. data/test/cxx/ApplicationPool2/PoolTest.cpp +129 -89
  203. data/test/cxx/ApplicationPool2/ProcessTest.cpp +15 -15
  204. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +22 -22
  205. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +11 -11
  206. data/test/cxx/ScgiRequestParserTest.cpp +75 -61
  207. data/test/cxx/UtilsTest.cpp +86 -85
  208. data/test/gdbinit.example +3 -0
  209. data/test/integration_tests/nginx_tests.rb +3 -3
  210. data/test/integration_tests/source_packaging_test.rb +3 -1
  211. data/test/stub/nginx/nginx.conf.erb +8 -1
  212. data/test/support/nginx_controller.rb +7 -7
  213. metadata +62 -17
  214. metadata.gz.asc +7 -7
  215. data/build/rpm.rb +0 -128
  216. data/dev/rpmtool +0 -21
  217. data/dev/test_rpm_packaging.sh +0 -28
  218. data/rpm/get_distro_id.py +0 -4
@@ -441,7 +441,7 @@ class BufferedUpload {
441
441
  public:
442
442
  /** The file handle. */
443
443
  FILE *handle;
444
-
444
+
445
445
  /**
446
446
  * Create an empty upload bufer file, and open it for reading and writing.
447
447
  *
@@ -450,19 +450,19 @@ public:
450
450
  BufferedUpload(const string &dir, const char *identifier = "temp") {
451
451
  char templ[PATH_MAX];
452
452
  int fd;
453
-
453
+
454
454
  snprintf(templ, sizeof(templ), "%s/%s.XXXXXX", dir.c_str(), identifier);
455
455
  templ[sizeof(templ) - 1] = '\0';
456
456
  fd = lfs_mkstemp(templ);
457
457
  if (fd == -1) {
458
458
  char message[1024];
459
459
  int e = errno;
460
-
460
+
461
461
  snprintf(message, sizeof(message), "Cannot create a temporary file '%s'", templ);
462
462
  message[sizeof(message) - 1] = '\0';
463
463
  throw SystemException(message, e);
464
464
  }
465
-
465
+
466
466
  /* We use a POSIX trick here: the file's permissions are set to "u=,g=,o="
467
467
  * and the file is deleted immediately from the filesystem, while we
468
468
  * keep its file handle open. The result is that no other processes
@@ -471,10 +471,10 @@ public:
471
471
  */
472
472
  fchmod(fd, 0000);
473
473
  unlink(templ);
474
-
474
+
475
475
  handle = fdopen(fd, "w+");
476
476
  }
477
-
477
+
478
478
  ~BufferedUpload() {
479
479
  fclose(handle);
480
480
  }
@@ -31,7 +31,7 @@
31
31
 
32
32
  namespace Passenger {
33
33
 
34
- static const std::string base64_chars =
34
+ static const std::string base64_chars =
35
35
  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
36
36
  "abcdefghijklmnopqrstuvwxyz"
37
37
  "0123456789+/";
@@ -54,7 +54,7 @@ Base64::encode(const unsigned char *bytes_to_encode, unsigned int in_len) {
54
54
  // + 814 bytes larger than the original. Here we reserve a little
55
55
  // more than that to avoid memory reallocations.
56
56
  ret.reserve((std::string::size_type) (in_len * 1.37) + 1024);
57
-
57
+
58
58
  while (in_len--) {
59
59
  char_array_3[i++] = *(bytes_to_encode++);
60
60
  if (i == 3) {
@@ -105,7 +105,7 @@ Base64::decode(const unsigned char *base64_data, unsigned int in_len) {
105
105
  reserved_size = in_len;
106
106
  }
107
107
  ret.reserve(reserved_size);
108
-
108
+
109
109
  while (in_len-- && ( base64_data[in_] != '=') && is_base64(base64_data[in_])) {
110
110
  char_array_4[i++] = base64_data[in_]; in_++;
111
111
  if (i == 4) {
@@ -42,7 +42,7 @@ public:
42
42
  static string encode(const StaticString &data) {
43
43
  return encode((const unsigned char *) data.data(), data.size());
44
44
  }
45
-
45
+
46
46
  /** Encode using a modified Base64 format, suitable for inclusion in URLs without
47
47
  * needing escaping.
48
48
  */
@@ -50,7 +50,7 @@ public:
50
50
  string result = encode(data);
51
51
  string::size_type i;
52
52
  int paddingSize = 0;
53
-
53
+
54
54
  for (i = 0; i < result.size(); i++) {
55
55
  char c = result[i];
56
56
  if (c == '+') {
@@ -61,20 +61,20 @@ public:
61
61
  paddingSize++;
62
62
  }
63
63
  }
64
-
64
+
65
65
  if (paddingSize > 0) {
66
66
  result.resize(result.size() - paddingSize);
67
67
  }
68
-
68
+
69
69
  return result;
70
70
  }
71
-
71
+
72
72
  static string decode(const StaticString &base64_data) {
73
73
  return decode((const unsigned char *) base64_data.data(), base64_data.size());
74
74
  }
75
-
75
+
76
76
  static string encode(const unsigned char *data, unsigned int len);
77
-
77
+
78
78
  static string decode(const unsigned char *base64_data, unsigned int len);
79
79
  };
80
80
 
@@ -42,7 +42,7 @@ private:
42
42
  boost::condition_variable_any removed;
43
43
  unsigned int max;
44
44
  std::queue<T> queue;
45
-
45
+
46
46
  bool atMaxCapacity() const {
47
47
  return max > 0 && queue.size() >= max;
48
48
  }
@@ -51,12 +51,12 @@ public:
51
51
  BlockingQueue(unsigned int max = 0) {
52
52
  this->max = max;
53
53
  }
54
-
54
+
55
55
  unsigned int size() const {
56
56
  boost::lock_guard<boost::timed_mutex> l(lock);
57
57
  return queue.size();
58
58
  }
59
-
59
+
60
60
  void add(const T &item) {
61
61
  boost::unique_lock<boost::timed_mutex> l(lock);
62
62
  while (atMaxCapacity()) {
@@ -68,7 +68,7 @@ public:
68
68
  removed.notify_one();
69
69
  }
70
70
  }
71
-
71
+
72
72
  bool tryAdd(const T &item) {
73
73
  boost::lock_guard<boost::timed_mutex> l(lock);
74
74
  if (!atMaxCapacity()) {
@@ -82,7 +82,7 @@ public:
82
82
  return false;
83
83
  }
84
84
  }
85
-
85
+
86
86
  T get() {
87
87
  boost::unique_lock<boost::timed_mutex> l(lock);
88
88
  while (queue.empty()) {
@@ -96,13 +96,13 @@ public:
96
96
  }
97
97
  return item;
98
98
  }
99
-
99
+
100
100
  bool timedGet(T &output, unsigned int timeout) {
101
101
  boost::unique_lock<boost::timed_mutex> l(lock);
102
102
  posix_time::ptime deadline = posix_time::microsec_clock::local_time() +
103
103
  posix_time::milliseconds(timeout);
104
104
  bool timedOut = false;
105
-
105
+
106
106
  while (queue.empty() && !timedOut) {
107
107
  posix_time::time_duration diff = deadline -
108
108
  posix_time::microsec_clock::local_time();
@@ -125,7 +125,7 @@ public:
125
125
  return false;
126
126
  }
127
127
  }
128
-
128
+
129
129
  bool tryGet(T &output) {
130
130
  boost::unique_lock<boost::timed_mutex> l(lock);
131
131
  if (queue.empty()) {
@@ -140,7 +140,7 @@ public:
140
140
  return true;
141
141
  }
142
142
  }
143
-
143
+
144
144
  T peek() {
145
145
  boost::unique_lock<boost::timed_mutex> l(lock);
146
146
  while (queue.empty()) {
@@ -32,7 +32,7 @@ class BufferedIO {
32
32
  private:
33
33
  FileDescriptor fd;
34
34
  string buffer;
35
-
35
+
36
36
  static pair<unsigned int, bool> nReadOrEofReached(const char *data,
37
37
  unsigned int size, void *output, unsigned int goalSize, unsigned int *alreadyRead)
38
38
  {
@@ -43,14 +43,14 @@ private:
43
43
  *alreadyRead += consumed;
44
44
  return make_pair(consumed, *alreadyRead == goalSize);
45
45
  }
46
-
46
+
47
47
  static pair<unsigned int, bool> eofReached(const char *data,
48
48
  unsigned int size, string *output)
49
49
  {
50
50
  output->append(data, size);
51
51
  return make_pair(size, false);
52
52
  }
53
-
53
+
54
54
  static pair<unsigned int, bool> newlineFound(const char *data,
55
55
  unsigned int size, string *output, unsigned int max)
56
56
  {
@@ -70,24 +70,24 @@ private:
70
70
  return make_pair(size, false);
71
71
  }
72
72
  }
73
-
73
+
74
74
  public:
75
75
  typedef boost::function< pair<unsigned int, bool>(const char *data, unsigned int size) > AcceptFunction;
76
-
76
+
77
77
  BufferedIO() { }
78
-
78
+
79
79
  BufferedIO(const FileDescriptor &_fd)
80
80
  : fd(_fd)
81
81
  { }
82
-
82
+
83
83
  FileDescriptor getFd() const {
84
84
  return fd;
85
85
  }
86
-
86
+
87
87
  const string &getBuffer() const {
88
88
  return buffer;
89
89
  }
90
-
90
+
91
91
  /**
92
92
  * This method keeps reading data in a loop, feeding each chunk to the given
93
93
  * acceptor function, until the function says that it has consumed all data
@@ -113,7 +113,7 @@ public:
113
113
  unsigned int readUntil(const AcceptFunction &acceptor, unsigned long long *timeout = NULL) {
114
114
  pair<unsigned int, bool> acceptResult;
115
115
  unsigned int totalRead = 0;
116
-
116
+
117
117
  if (!buffer.empty()) {
118
118
  acceptResult = acceptor(buffer.c_str(), buffer.size());
119
119
  if (OXT_UNLIKELY(!acceptResult.second && acceptResult.first < buffer.size())) {
@@ -127,12 +127,12 @@ public:
127
127
  return totalRead;
128
128
  }
129
129
  }
130
-
130
+
131
131
  while (true) {
132
132
  if (OXT_UNLIKELY(timeout != NULL && !waitUntilReadable(fd, timeout))) {
133
133
  throw TimeoutException("Read timeout");
134
134
  }
135
-
135
+
136
136
  char tmp[1024 * 8];
137
137
  ssize_t ret = syscalls::read(fd, tmp, sizeof(tmp));
138
138
  if (ret == 0) {
@@ -157,20 +157,20 @@ public:
157
157
  }
158
158
  }
159
159
  }
160
-
160
+
161
161
  unsigned int read(void *buf, unsigned int size, unsigned long long *timeout = NULL) {
162
162
  unsigned int counter = 0;
163
163
  return readUntil(
164
164
  boost::bind(nReadOrEofReached, _1, _2, buf, size, &counter),
165
165
  timeout);
166
166
  }
167
-
167
+
168
168
  string readAll(unsigned long long *timeout = NULL) {
169
169
  string output;
170
170
  readUntil(boost::bind(eofReached, _1, _2, &output), timeout);
171
171
  return output;
172
172
  }
173
-
173
+
174
174
  /**
175
175
  * Reads a line and returns the line including the newline character. Upon
176
176
  * encountering EOF, the empty string is returned.
@@ -189,7 +189,7 @@ public:
189
189
  readUntil(boost::bind(newlineFound, _1, _2, &output, max), timeout);
190
190
  return output;
191
191
  }
192
-
192
+
193
193
  void unread(const void *buf, unsigned int size) {
194
194
  string newBuffer;
195
195
  newBuffer.reserve(size + buffer.size());
@@ -197,7 +197,7 @@ public:
197
197
  newBuffer.append(buffer);
198
198
  buffer = newBuffer;
199
199
  }
200
-
200
+
201
201
  void unread(const StaticString &str) {
202
202
  unread(str.c_str(), str.size());
203
203
  }
@@ -65,13 +65,13 @@ public:
65
65
  private:
66
66
  /** The last return value of stat(). */
67
67
  int last_result;
68
-
68
+
69
69
  /** The errno set by the last stat() call. */
70
70
  int last_errno;
71
-
71
+
72
72
  /** The last time a stat() was performed. */
73
73
  time_t last_time;
74
-
74
+
75
75
  /**
76
76
  * Checks whether `interval` seconds have elapsed since `begin`.
77
77
  * The current time is returned via the `currentTime` argument,
@@ -87,14 +87,14 @@ public:
87
87
  currentTime = SystemTime::get();
88
88
  return (unsigned int) (currentTime - begin) >= interval;
89
89
  }
90
-
90
+
91
91
  public:
92
92
  /** The cached stat info. */
93
93
  struct stat info;
94
-
94
+
95
95
  /** This entry's filename. */
96
96
  string filename;
97
-
97
+
98
98
  /**
99
99
  * Creates a new Entry object. The file will not be
100
100
  * stat()ted until you call refresh().
@@ -109,7 +109,7 @@ public:
109
109
  last_errno = 0;
110
110
  last_time = 0;
111
111
  }
112
-
112
+
113
113
  /**
114
114
  * Re-stat() the file, if necessary. If <tt>throttleRate</tt> seconds have
115
115
  * passed since the last time stat() was called, then the file will be
@@ -140,16 +140,16 @@ public:
140
140
  }
141
141
  }
142
142
  };
143
-
143
+
144
144
  typedef boost::shared_ptr<Entry> EntryPtr;
145
145
  typedef list<EntryPtr> EntryList;
146
146
  typedef StringMap<EntryList::iterator> EntryMap;
147
-
147
+
148
148
  unsigned int maxSize;
149
149
  EntryList entries;
150
150
  EntryMap cache;
151
151
  mutable boost::mutex lock;
152
-
152
+
153
153
  /**
154
154
  * Creates a new CachedFileStat object.
155
155
  *
@@ -158,7 +158,7 @@ public:
158
158
  CachedFileStat(unsigned int maxSize = 0) {
159
159
  this->maxSize = maxSize;
160
160
  }
161
-
161
+
162
162
  /**
163
163
  * Stats the given file. If `throttleRate` seconds have passed since
164
164
  * the last time stat() was called on this file, then the file will be
@@ -182,7 +182,7 @@ public:
182
182
  EntryList::iterator it(cache.get(filename, entries.end()));
183
183
  EntryPtr entry;
184
184
  int ret;
185
-
185
+
186
186
  if (it == entries.end()) {
187
187
  // Filename not in cache.
188
188
  // If cache is full, remove the least recently used
@@ -194,7 +194,7 @@ public:
194
194
  entries.pop_back();
195
195
  cache.remove(filename2);
196
196
  }
197
-
197
+
198
198
  // Add to cache as most recently used.
199
199
  entry = boost::make_shared<Entry>(filename);
200
200
  entries.push_front(entry);
@@ -202,7 +202,7 @@ public:
202
202
  } else {
203
203
  // Cache hit.
204
204
  entry = *it;
205
-
205
+
206
206
  // Mark this cache item as most recently used.
207
207
  entries.splice(entries.begin(), entries, it);
208
208
  cache.set(filename, entries.begin());
@@ -211,7 +211,7 @@ public:
211
211
  *buf = entry->info;
212
212
  return ret;
213
213
  }
214
-
214
+
215
215
  /**
216
216
  * Change the maximum size of the cache. If the new size is larger
217
217
  * than the old size, then the oldest entries in the cache are
@@ -231,7 +231,7 @@ public:
231
231
  }
232
232
  this->maxSize = maxSize;
233
233
  }
234
-
234
+
235
235
  /**
236
236
  * Returns whether `filename` is in the cache.
237
237
  */
@@ -29,16 +29,16 @@ class Dechunker {
29
29
  public:
30
30
  typedef void (*DataCallback)(const char *data, size_t size, void *userData);
31
31
  typedef void (*Callback)(void *userData);
32
-
32
+
33
33
  private:
34
34
  static const char CR = '\x0D';
35
35
  static const char LF = '\x0A';
36
-
36
+
37
37
  char sizeBuffer[10];
38
38
  unsigned int sizeBufferLen;
39
39
  unsigned int remainingDataSize;
40
40
  const char *errorMessage;
41
-
41
+
42
42
  enum {
43
43
  EXPECTING_SIZE,
44
44
  EXPECTING_CHUNK_EXTENSION,
@@ -51,22 +51,22 @@ private:
51
51
  DONE,
52
52
  ERROR
53
53
  } state;
54
-
54
+
55
55
  void setError(const char *message) {
56
56
  errorMessage = message;
57
57
  state = ERROR;
58
58
  }
59
-
59
+
60
60
  bool isDigit(char ch) const {
61
61
  return (ch >= '0' && ch <= '9')
62
62
  || (ch >= 'a' && ch <= 'f')
63
63
  || (ch >= 'A' && ch <= 'Z');
64
64
  }
65
-
65
+
66
66
  void parseSizeBuffer() {
67
67
  remainingDataSize = hexToUint(StaticString(sizeBuffer, sizeBufferLen));
68
68
  }
69
-
69
+
70
70
  void emitDataEvent(const char *data, size_t size) const {
71
71
  if (onData != NULL) {
72
72
  onData(data, size, userData);
@@ -78,19 +78,19 @@ private:
78
78
  onEnd(userData);
79
79
  }
80
80
  }
81
-
81
+
82
82
  public:
83
83
  DataCallback onData;
84
84
  Callback onEnd;
85
85
  void *userData;
86
-
86
+
87
87
  Dechunker() {
88
88
  onData = NULL;
89
89
  onEnd = NULL;
90
90
  userData = NULL;
91
91
  reset();
92
92
  }
93
-
93
+
94
94
  /**
95
95
  * Resets the internal state so that this Dechunker can be reused
96
96
  * for parsing new data.
@@ -104,7 +104,7 @@ public:
104
104
  remainingDataSize = 0;
105
105
  errorMessage = NULL;
106
106
  }
107
-
107
+
108
108
  /**
109
109
  * Feeds data into this parser. Any data chunks it has parsed will be emitted
110
110
  * through the onData callback. Returns the number of bytes that have been
@@ -116,7 +116,7 @@ public:
116
116
  const char *end = data + size;
117
117
  const char *needle;
118
118
  size_t dataSize;
119
-
119
+
120
120
  while (current < end && state != DONE && state != ERROR) {
121
121
  switch (state) {
122
122
  case EXPECTING_DATA:
@@ -132,7 +132,7 @@ public:
132
132
  }
133
133
  }
134
134
  break;
135
-
135
+
136
136
  case EXPECTING_SIZE:
137
137
  while (current < end
138
138
  && sizeBufferLen < sizeof(sizeBuffer)
@@ -153,12 +153,12 @@ public:
153
153
  }
154
154
  current++;
155
155
  }
156
-
156
+
157
157
  if (sizeBufferLen == sizeof(sizeBuffer) && state == EXPECTING_SIZE) {
158
158
  setError("The chunk size header is too large.");
159
159
  }
160
160
  break;
161
-
161
+
162
162
  case EXPECTING_CHUNK_EXTENSION:
163
163
  needle = (const char *) memchr(current, CR, end - current);
164
164
  if (needle == NULL) {
@@ -168,7 +168,7 @@ public:
168
168
  state = EXPECTING_HEADER_LF;
169
169
  }
170
170
  break;
171
-
171
+
172
172
  case EXPECTING_HEADER_LF:
173
173
  if (*current == LF) {
174
174
  state = EXPECTING_DATA;
@@ -177,7 +177,7 @@ public:
177
177
  setError("Parse error: expected a chunk header LF.");
178
178
  }
179
179
  break;
180
-
180
+
181
181
  case EXPECTING_NON_FINAL_CR:
182
182
  if (*current == CR) {
183
183
  state = EXPECTING_NON_FINAL_LF;
@@ -186,7 +186,7 @@ public:
186
186
  setError("Parse error: expected a chunk finalizing CR.");
187
187
  }
188
188
  break;
189
-
189
+
190
190
  case EXPECTING_NON_FINAL_LF:
191
191
  if (*current == LF) {
192
192
  reset();
@@ -195,7 +195,7 @@ public:
195
195
  setError("Parse error: expected a chunk finalizing LF.");
196
196
  }
197
197
  break;
198
-
198
+
199
199
  case EXPECTING_FINAL_CR:
200
200
  if (*current == CR) {
201
201
  state = EXPECTING_FINAL_LF;
@@ -204,7 +204,7 @@ public:
204
204
  setError("Parse error: expected a final CR.");
205
205
  }
206
206
  break;
207
-
207
+
208
208
  case EXPECTING_FINAL_LF:
209
209
  if (*current == LF) {
210
210
  emitEndEvent();
@@ -214,23 +214,23 @@ public:
214
214
  setError("Parse error: expected a final LF.");
215
215
  }
216
216
  break;
217
-
217
+
218
218
  default:
219
219
  abort();
220
220
  }
221
221
  }
222
-
222
+
223
223
  return current - data;
224
224
  }
225
-
225
+
226
226
  bool acceptingInput() const {
227
227
  return state != DONE && state != ERROR;
228
228
  }
229
-
229
+
230
230
  bool hasError() const {
231
231
  return state == ERROR;
232
232
  }
233
-
233
+
234
234
  const char *getErrorMessage() const {
235
235
  return errorMessage;
236
236
  }