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.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/.editorconfig +36 -2
- data/.travis.yml +1 -1
- data/CHANGELOG +16 -0
- data/Rakefile +0 -1
- data/build/apache2.rb +4 -4
- data/build/common_library.rb +18 -18
- data/build/cplusplus_support.rb +2 -2
- data/build/documentation.rb +1 -1
- data/build/integration_tests.rb +12 -4
- data/build/misc.rb +12 -7
- data/build/packaging.rb +14 -14
- data/build/preprocessor.rb +10 -10
- data/build/rake_extensions.rb +11 -11
- data/build/ruby_extension.rb +2 -2
- data/dev/ci/inituidgid +24 -0
- data/dev/ci/run_jenkins.sh +57 -0
- data/dev/ci/run_rpm_tests.sh +77 -0
- data/dev/{run_travis.sh → ci/run_travis.sh} +60 -4
- data/doc/Users guide Nginx.txt +2 -2
- data/doc/users_guide_snippets/environment_variables.txt +0 -2
- data/doc/users_guide_snippets/tips.txt +20 -1
- data/ext/apache2/Bucket.cpp +18 -18
- data/ext/apache2/Bucket.h +4 -4
- data/ext/apache2/Configuration.cpp +7 -7
- data/ext/apache2/Configuration.hpp +43 -43
- data/ext/apache2/DirectoryMapper.h +5 -5
- data/ext/apache2/Hooks.cpp +142 -142
- data/ext/apache2/MergeDirConfig.cpp +40 -40
- data/ext/common/Account.h +17 -17
- data/ext/common/AccountsDatabase.h +9 -9
- data/ext/common/AgentsStarter.cpp +2 -2
- data/ext/common/AgentsStarter.h +40 -40
- data/ext/common/ApplicationPool2/Common.h +10 -6
- data/ext/common/ApplicationPool2/ComponentInfo.h +2 -2
- data/ext/common/ApplicationPool2/DirectSpawner.h +17 -17
- data/ext/common/ApplicationPool2/DummySpawner.h +5 -5
- data/ext/common/ApplicationPool2/Group.h +54 -38
- data/ext/common/ApplicationPool2/Implementation.cpp +76 -49
- data/ext/common/ApplicationPool2/Options.h +98 -91
- data/ext/common/ApplicationPool2/Pool.h +70 -69
- data/ext/common/ApplicationPool2/Process.h +21 -21
- data/ext/common/ApplicationPool2/Session.h +11 -11
- data/ext/common/ApplicationPool2/SmartSpawner.h +60 -60
- data/ext/common/ApplicationPool2/Socket.h +19 -19
- data/ext/common/ApplicationPool2/Spawner.h +64 -72
- data/ext/common/ApplicationPool2/SpawnerFactory.h +4 -4
- data/ext/common/ApplicationPool2/SuperGroup.h +41 -41
- data/ext/common/BackgroundEventLoop.cpp +1 -1
- data/ext/common/BackgroundEventLoop.h +2 -2
- data/ext/common/Constants.h +1 -1
- data/ext/common/EventedBufferedInput.h +5 -5
- data/ext/common/EventedClient.h +51 -51
- data/ext/common/EventedMessageServer.h +39 -39
- data/ext/common/EventedServer.h +32 -32
- data/ext/common/Exceptions.h +23 -23
- data/ext/common/FileDescriptor.h +18 -18
- data/ext/common/Logging.cpp +1 -1
- data/ext/common/MessageClient.h +27 -27
- data/ext/common/MessageReadersWriters.h +79 -79
- data/ext/common/MessageServer.h +59 -59
- data/ext/common/RandomGenerator.h +12 -12
- data/ext/common/ResourceLocator.h +8 -8
- data/ext/common/SafeLibev.h +54 -25
- data/ext/common/ServerInstanceDir.h +31 -31
- data/ext/common/StaticString.h +50 -48
- data/ext/common/Utils.cpp +73 -78
- data/ext/common/Utils.h +6 -6
- data/ext/common/Utils/Base64.cpp +3 -3
- data/ext/common/Utils/Base64.h +7 -7
- data/ext/common/Utils/BlockingQueue.h +9 -9
- data/ext/common/Utils/BufferedIO.h +17 -17
- data/ext/common/Utils/CachedFileStat.hpp +16 -16
- data/ext/common/Utils/Dechunker.h +25 -25
- data/ext/common/Utils/FileChangeChecker.h +10 -10
- data/ext/common/Utils/MemZeroGuard.h +5 -5
- data/ext/common/Utils/MemoryBarrier.h +1 -1
- data/ext/common/Utils/MessageIO.h +61 -61
- data/ext/common/Utils/ProcessMetricsCollector.h +40 -40
- data/ext/common/Utils/ScopeGuard.h +7 -7
- data/ext/common/Utils/SpeedMeter.h +1 -1
- data/ext/common/Utils/StrIntUtils.cpp +13 -13
- data/ext/common/Utils/StrIntUtils.h +3 -3
- data/ext/common/Utils/StringScanning.h +5 -5
- data/ext/common/Utils/SystemMetricsCollector.h +2 -2
- data/ext/common/Utils/SystemTime.h +10 -10
- data/ext/common/Utils/Template.h +2 -2
- data/ext/common/Utils/Timer.h +6 -6
- data/ext/common/Utils/VariantMap.h +29 -29
- data/ext/common/agents/Base.cpp +19 -19
- data/ext/common/agents/HelperAgent/AgentOptions.h +1 -1
- data/ext/common/agents/HelperAgent/FileBackedPipe.h +6 -6
- data/ext/common/agents/HelperAgent/Main.cpp +44 -43
- data/ext/common/agents/HelperAgent/RequestHandler.cpp +4 -4
- data/ext/common/agents/HelperAgent/RequestHandler.h +29 -28
- data/ext/common/agents/HelperAgent/ScgiRequestParser.h +56 -50
- data/ext/common/agents/LoggingAgent/AdminController.h +8 -8
- data/ext/common/agents/LoggingAgent/DataStoreId.h +17 -17
- data/ext/common/agents/LoggingAgent/FilterSupport.h +167 -167
- data/ext/common/agents/LoggingAgent/LoggingServer.h +122 -122
- data/ext/common/agents/LoggingAgent/Main.cpp +7 -7
- data/ext/common/agents/LoggingAgent/RemoteSender.h +54 -54
- data/ext/common/agents/SpawnPreparer.cpp +4 -4
- data/ext/common/agents/TempDirToucher.c +2 -2
- data/ext/common/agents/Watchdog/AgentWatcher.cpp +47 -47
- data/ext/common/agents/Watchdog/HelperAgentWatcher.cpp +7 -7
- data/ext/common/agents/Watchdog/LoggingAgentWatcher.cpp +7 -7
- data/ext/common/agents/Watchdog/Main.cpp +22 -22
- data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +9 -9
- data/ext/libeio/eio.c +1 -1
- data/ext/nginx/Configuration.c +30 -30
- data/ext/nginx/Configuration.h +1 -1
- data/ext/nginx/ContentHandler.c +54 -54
- data/ext/nginx/ContentHandler.h +3 -3
- data/ext/nginx/StaticContentHandler.c +2 -2
- data/ext/nginx/ngx_http_passenger_module.c +21 -21
- data/ext/oxt/detail/backtrace_enabled.hpp +1 -1
- data/ext/oxt/detail/context.hpp +1 -1
- data/ext/oxt/detail/spin_lock_darwin.hpp +4 -4
- data/ext/oxt/detail/spin_lock_gcc_x86.hpp +3 -3
- data/ext/oxt/detail/spin_lock_pthreads.hpp +4 -4
- data/ext/oxt/detail/tracable_exception_disabled.hpp +1 -1
- data/ext/oxt/dynamic_thread_group.hpp +18 -18
- data/ext/oxt/implementation.cpp +9 -8
- data/ext/oxt/macros.hpp +2 -2
- data/ext/oxt/system_calls.cpp +11 -11
- data/ext/oxt/system_calls.hpp +13 -13
- data/ext/oxt/thread.hpp +22 -14
- data/ext/ruby/passenger_native_support.c +55 -55
- data/lib/phusion_passenger.rb +24 -24
- data/lib/phusion_passenger/common_library.rb +2 -0
- data/lib/phusion_passenger/loader_shared_helpers.rb +18 -18
- data/lib/phusion_passenger/packaging.rb +9 -4
- data/lib/phusion_passenger/platform_info/apache.rb +45 -31
- data/lib/phusion_passenger/platform_info/compiler.rb +11 -11
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +1 -1
- data/lib/phusion_passenger/request_handler/thread_handler.rb +8 -8
- data/lib/phusion_passenger/standalone/app_finder.rb +16 -16
- data/lib/phusion_passenger/standalone/command.rb +22 -22
- data/packaging/rpm/LICENSE.txt +19 -0
- data/packaging/rpm/Makefile +13 -0
- data/packaging/rpm/README.md +41 -0
- data/packaging/rpm/Vagrantfile +38 -0
- data/{rpm/Vagrantfile → packaging/rpm/Vagrantfile.centos} +0 -0
- data/packaging/rpm/build +170 -0
- data/packaging/rpm/create_project +41 -0
- data/packaging/rpm/git_update +88 -0
- data/packaging/rpm/image/Dockerfile +37 -0
- data/packaging/rpm/image/Gemfile +3 -0
- data/packaging/rpm/image/Gemfile.lock +12 -0
- data/packaging/rpm/image/RPM-GPG-KEY-amazon-ga +19 -0
- data/packaging/rpm/image/amazon2014-i386.cfg +96 -0
- data/packaging/rpm/image/amazon2014-x86_64.cfg +96 -0
- data/packaging/rpm/image/site-defaults.cfg +168 -0
- data/packaging/rpm/internal/build_tasks.rb +238 -0
- data/packaging/rpm/internal/dummygpg +11 -0
- data/packaging/rpm/internal/exec_build +42 -0
- data/packaging/rpm/internal/get_distro_arch +14 -0
- data/packaging/rpm/internal/get_distro_id +10 -0
- data/packaging/rpm/internal/git_update +27 -0
- data/packaging/rpm/internal/inituidgid +17 -0
- data/packaging/rpm/internal/my_init +344 -0
- data/packaging/rpm/internal/python27 +3 -0
- data/packaging/rpm/internal/repo_update +46 -0
- data/packaging/rpm/internal/setuser +26 -0
- data/packaging/rpm/internal/tracking_helper +40 -0
- data/packaging/rpm/jenkins_release +99 -0
- data/packaging/rpm/lib/build_tasks_support.rb +402 -0
- data/packaging/rpm/lib/preprocessor.rb +341 -0
- data/packaging/rpm/nginx_spec/404.html +119 -0
- data/packaging/rpm/nginx_spec/50x.html +119 -0
- data/packaging/rpm/nginx_spec/index.html +116 -0
- data/packaging/rpm/nginx_spec/nginx-auto-cc-gcc.patch +13 -0
- data/packaging/rpm/nginx_spec/nginx-logo.png +0 -0
- data/packaging/rpm/nginx_spec/nginx-upgrade +13 -0
- data/packaging/rpm/nginx_spec/nginx-upgrade.8 +151 -0
- data/packaging/rpm/nginx_spec/nginx.conf +131 -0
- data/packaging/rpm/nginx_spec/nginx.init +144 -0
- data/packaging/rpm/nginx_spec/nginx.logrotate +13 -0
- data/packaging/rpm/nginx_spec/nginx.service +15 -0
- data/packaging/rpm/nginx_spec/nginx.spec.template +559 -0
- data/packaging/rpm/nginx_spec/nginx.sysconfig +4 -0
- data/packaging/rpm/nginx_spec/passenger.conf +9 -0
- data/packaging/rpm/nginx_spec/poweredby.png +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/apache-passenger.conf.in +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/config.json +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger.logrotate +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger.spec.template +58 -31
- data/{rpm → packaging/rpm/passenger_spec}/passenger_dynamic_thread_group.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger_tests_default_config_example.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-GLIBC_HAVE_LONG_LONG.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-gcc47-include-sys_types.patch +0 -0
- data/packaging/rpm/repo_update +114 -0
- data/packaging/rpm/setup-system +60 -0
- data/packaging/rpm/shell +10 -0
- data/resources/templates/standalone/config.erb +3 -1
- data/test/config.json.rpm-automation +1 -1
- data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +11 -11
- data/test/cxx/ApplicationPool2/OptionsTest.cpp +5 -5
- data/test/cxx/ApplicationPool2/PoolTest.cpp +129 -89
- data/test/cxx/ApplicationPool2/ProcessTest.cpp +15 -15
- data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +22 -22
- data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +11 -11
- data/test/cxx/ScgiRequestParserTest.cpp +75 -61
- data/test/cxx/UtilsTest.cpp +86 -85
- data/test/gdbinit.example +3 -0
- data/test/integration_tests/nginx_tests.rb +3 -3
- data/test/integration_tests/source_packaging_test.rb +3 -1
- data/test/stub/nginx/nginx.conf.erb +8 -1
- data/test/support/nginx_controller.rb +7 -7
- metadata +62 -17
- metadata.gz.asc +7 -7
- data/build/rpm.rb +0 -128
- data/dev/rpmtool +0 -21
- data/dev/test_rpm_packaging.sh +0 -28
- data/rpm/get_distro_id.py +0 -4
data/ext/common/Utils.h
CHANGED
@@ -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
|
}
|
data/ext/common/Utils/Base64.cpp
CHANGED
@@ -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) {
|
data/ext/common/Utils/Base64.h
CHANGED
@@ -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
|
}
|