webroar 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +48 -1
- data/README +11 -14
- data/Rakefile +1 -1
- data/conf/mime_type.yml +172 -166
- data/conf/server_internal_config.yml +30 -8
- data/doc/user-guide.html +294 -153
- data/doc/user-guide.txt +9 -13
- data/lib/command_runner.rb +1 -0
- data/lib/dependencies.rb +18 -15
- data/lib/installer.rb +115 -50
- data/src/admin_panel/app/controllers/admin_controller.rb +1 -15
- data/src/admin_panel/app/controllers/application_controller.rb +2 -2
- data/src/admin_panel/app/controllers/application_specification_controller.rb +2 -1
- data/src/admin_panel/app/controllers/headers_controller.rb +73 -0
- data/src/admin_panel/app/controllers/mail_specification_controller.rb +10 -0
- data/src/admin_panel/app/controllers/server_specification_controller.rb +14 -0
- data/src/admin_panel/app/helpers/admin_helper.rb +0 -85
- data/src/admin_panel/app/models/app.rb +1 -1
- data/src/admin_panel/app/models/application_specification.rb +33 -25
- data/src/admin_panel/app/models/headers.rb +116 -0
- data/src/admin_panel/app/models/mail_specification.rb +20 -5
- data/src/admin_panel/app/models/server_specification.rb +2 -7
- data/src/admin_panel/app/views/admin/configuration.html.erb +10 -5
- data/src/admin_panel/app/views/exceptions/_exception_list_partial.html.erb +4 -4
- data/src/admin_panel/app/views/graph/_graph_page.html.erb +3 -0
- data/src/admin_panel/app/views/headers/_add_expires_text_box.html.erb +35 -0
- data/src/admin_panel/app/views/headers/_expires_by_type_form.html.erb +65 -0
- data/src/admin_panel/app/views/headers/_headers_table.html.erb +113 -0
- data/src/admin_panel/app/views/mail_specification/_current_spec.html.erb +168 -0
- data/src/admin_panel/app/views/{admin → server_specification}/_add_div.html.erb +1 -1
- data/src/admin_panel/config/initializers/application_constants.rb +6 -0
- data/src/admin_panel/lib/control.rb +6 -3
- data/src/admin_panel/lib/scgi.rb +74 -21
- data/src/admin_panel/lib/yaml_writer.rb +51 -17
- data/src/admin_panel/public/javascripts/application.js +20 -1
- data/src/head/wr_access_log.c +2 -2
- data/src/head/wr_application.c +294 -236
- data/src/head/wr_application.h +8 -8
- data/src/head/wr_configurator.c +451 -517
- data/src/head/wr_configurator.h +10 -115
- data/src/head/wr_connection.c +26 -25
- data/src/head/wr_connection.h +2 -3
- data/src/head/wr_controller.c +110 -93
- data/src/head/wr_controller.h +6 -6
- data/src/head/wr_main.c +31 -24
- data/src/head/wr_request.c +70 -93
- data/src/head/wr_request.h +0 -4
- data/src/head/wr_resolver.c +21 -15
- data/src/head/wr_resolver.h +2 -2
- data/src/head/wr_server.c +36 -26
- data/src/head/wr_server.h +5 -5
- data/src/head/wr_worker.c +551 -512
- data/src/head/wr_worker.h +33 -20
- data/src/helper/wr_config.c +316 -0
- data/src/helper/wr_config.h +235 -0
- data/src/helper/wr_helper.h +1 -5
- data/src/helper/wr_logger.c +4 -4
- data/src/helper/wr_scgi.c +3 -4
- data/src/helper/wr_scgi.h +2 -0
- data/src/helper/wr_string.h +2 -2
- data/src/helper/wr_util.c +3 -1
- data/src/helper/wr_util.h +0 -0
- data/src/helper/wr_yaml_parser.c +30 -0
- data/src/helper/wr_yaml_parser.h +1 -0
- data/src/ruby_lib/exception_tracker/instrumentation/action_controller.rb +2 -1
- data/src/ruby_lib/mailer/smtpmail.rb +7 -4
- data/src/ruby_lib/profiler/instrumentation/action_controller.rb +2 -1
- data/src/ruby_lib/profiler/instrumentation/active_record.rb +3 -0
- data/src/ruby_lib/rack/adapter/rails.rb +14 -7
- data/src/ruby_lib/ruby_interface/client.rb +1 -1
- data/src/ruby_lib/ruby_interface/version.rb +2 -2
- data/src/ruby_lib/webroar_app_loader.rb +4 -2
- data/src/worker/wkr_controller.c +200 -140
- data/src/worker/wkr_http.c +14 -28
- data/src/worker/wkr_http.h +4 -4
- data/src/worker/wkr_http_request.c +12 -11
- data/src/worker/wkr_http_request.h +7 -8
- data/src/worker/wkr_http_response.c +10 -14
- data/src/worker/wkr_http_response.h +0 -1
- data/src/worker/wkr_main.c +74 -140
- data/src/worker/wkr_static.c +295 -108
- data/src/worker/wkr_static.h +20 -7
- data/src/worker/worker.c +245 -70
- data/src/worker/worker.h +46 -34
- data/tasks/compile.rake +128 -175
- data/tasks/test.rake +345 -469
- data/test/spec/webroar_command_spec.rb +23 -0
- metadata +173 -43
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/README +0 -34
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/Rakefile +0 -13
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/init.rb +0 -5
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/lib/action_mailer_tls.rb +0 -16
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/lib/smtp_tls.rb +0 -123
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/test/tls_test.rb +0 -42
- data/src/head/wr_config.h +0 -165
- data/src/ruby_lib/mailer/action_mailer_tls.rb +0 -16
- data/src/ruby_lib/mailer/smtp_tls.rb +0 -123
|
@@ -18,9 +18,10 @@
|
|
|
18
18
|
*/
|
|
19
19
|
#include <worker.h>
|
|
20
20
|
#include <stdlib.h>
|
|
21
|
-
#include <wr_logger.h>
|
|
22
21
|
#include <assert.h>
|
|
23
22
|
|
|
23
|
+
extern config_t *Config;
|
|
24
|
+
|
|
24
25
|
http_req_t* http_req_new() {
|
|
25
26
|
LOG_FUNCTION
|
|
26
27
|
http_req_t* req = wr_malloc(http_req_t);
|
|
@@ -109,7 +110,7 @@ int http_req_body_read(http_req_t *req, char *buf, int len) {
|
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
/** Read SCGI request body in buffer */
|
|
112
|
-
|
|
113
|
+
void http_req_body_read_in_buff(http_req_t *req, struct ev_loop *loop, struct ev_io *watcher) {
|
|
113
114
|
LOG_FUNCTION
|
|
114
115
|
ssize_t read = recv(watcher->fd,
|
|
115
116
|
req->buf + req->scgi_header_len + req->bytes_read,
|
|
@@ -136,14 +137,14 @@ static inline void http_req_body_read_in_buff(http_req_t *req, struct ev_loop *l
|
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
/** Read SCGI request body in file */
|
|
139
|
-
|
|
140
|
+
void http_req_body_read_in_file(http_req_t *req, struct ev_loop *loop, struct ev_io *watcher) {
|
|
140
141
|
LOG_FUNCTION
|
|
141
|
-
char buffer[
|
|
142
|
+
char buffer[STR_SIZE10KB+1];
|
|
142
143
|
ssize_t read, write = 0, rv;
|
|
143
144
|
|
|
144
145
|
read = recv(watcher->fd,
|
|
145
146
|
buffer,
|
|
146
|
-
wr_min(req->req_len - req->bytes_read,
|
|
147
|
+
wr_min(req->req_len - req->bytes_read, STR_SIZE10KB),
|
|
147
148
|
0);
|
|
148
149
|
|
|
149
150
|
if(read < 0) {
|
|
@@ -170,7 +171,7 @@ static inline void http_req_body_read_in_file(http_req_t *req, struct ev_loop *l
|
|
|
170
171
|
}
|
|
171
172
|
|
|
172
173
|
/** Read SCGI request body */
|
|
173
|
-
|
|
174
|
+
void http_req_body_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) {
|
|
174
175
|
LOG_FUNCTION
|
|
175
176
|
wkr_t *w = (wkr_t*) watcher->data;
|
|
176
177
|
http_req_t *req = w->http->req;
|
|
@@ -193,7 +194,7 @@ static void http_req_body_cb(struct ev_loop *loop, struct ev_io *watcher, int re
|
|
|
193
194
|
}
|
|
194
195
|
|
|
195
196
|
/** Parse SCGI request */
|
|
196
|
-
|
|
197
|
+
void parser_req_buf(http_req_t *req, struct ev_loop *loop, struct ev_io *watcher) {
|
|
197
198
|
LOG_FUNCTION
|
|
198
199
|
if(req->scgi_header_len == 0) {
|
|
199
200
|
// Fetch header packet length
|
|
@@ -234,7 +235,7 @@ static inline void parser_req_buf(http_req_t *req, struct ev_loop *loop, struct
|
|
|
234
235
|
#ifdef L_DEBUG
|
|
235
236
|
// Fetch Connection id
|
|
236
237
|
wkr_t *w = (wkr_t*) watcher->data;
|
|
237
|
-
scgi_header_t *header = scgi_header_get(req->scgi,
|
|
238
|
+
scgi_header_t *header = scgi_header_get(req->scgi, Config->Worker.Header.conn_id.str);
|
|
238
239
|
if(header){
|
|
239
240
|
w->http->conn_id = atoi(req->scgi->header + req->scgi->start_offset + header->value_offset);
|
|
240
241
|
}else{
|
|
@@ -242,7 +243,7 @@ static inline void parser_req_buf(http_req_t *req, struct ev_loop *loop, struct
|
|
|
242
243
|
}
|
|
243
244
|
|
|
244
245
|
// Fetch request id
|
|
245
|
-
header = scgi_header_get(req->scgi,
|
|
246
|
+
header = scgi_header_get(req->scgi, Config->Worker.Header.req_id.str);
|
|
246
247
|
if(header){
|
|
247
248
|
w->http->req_id = atoi(req->scgi->header + req->scgi->start_offset + header->value_offset);
|
|
248
249
|
}else{
|
|
@@ -257,7 +258,7 @@ static inline void parser_req_buf(http_req_t *req, struct ev_loop *loop, struct
|
|
|
257
258
|
req->bytes_read = 0;
|
|
258
259
|
http_req_process();
|
|
259
260
|
} else {
|
|
260
|
-
if(req->req_len + req->scgi_header_len >
|
|
261
|
+
if(req->req_len + req->scgi_header_len > STR_SIZE10KB) {
|
|
261
262
|
ssize_t write;
|
|
262
263
|
size_t processed_bytes = 0;
|
|
263
264
|
|
|
@@ -300,7 +301,7 @@ void http_req_header_cb(struct ev_loop *loop, struct ev_io *watcher, int revents
|
|
|
300
301
|
|
|
301
302
|
ssize_t read = recv(watcher->fd
|
|
302
303
|
, req->buf + req->bytes_read
|
|
303
|
-
,
|
|
304
|
+
, STR_SIZE10KB - req->bytes_read
|
|
304
305
|
, 0
|
|
305
306
|
);
|
|
306
307
|
if(read < 0) {
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
#ifndef WKR_HTTP_REQUEST_H_
|
|
20
20
|
#define WKR_HTTP_REQUEST_H_
|
|
21
21
|
|
|
22
|
-
#include <wr_config.h>
|
|
23
22
|
#include <wr_helper.h>
|
|
24
23
|
#include <errno.h>
|
|
25
24
|
#include <ev.h>
|
|
@@ -29,13 +28,13 @@ typedef struct http_req_s http_req_t;
|
|
|
29
28
|
|
|
30
29
|
/******* HTTP Request ******/
|
|
31
30
|
struct http_req_s {
|
|
32
|
-
char
|
|
33
|
-
size_t
|
|
34
|
-
scgi_t
|
|
35
|
-
FILE
|
|
36
|
-
char
|
|
37
|
-
size_t
|
|
38
|
-
size_t
|
|
31
|
+
char buf[STR_SIZE10KB]; /**< Request buffer */
|
|
32
|
+
size_t bytes_read;
|
|
33
|
+
scgi_t *scgi; /**< Parsed SCGI request */
|
|
34
|
+
FILE *file; /**< File pointer */
|
|
35
|
+
char file_name[STR_SIZE64]; /**< File name */
|
|
36
|
+
size_t scgi_header_len; /**< Header packet length */
|
|
37
|
+
size_t req_len; /**< Content length */
|
|
39
38
|
};
|
|
40
39
|
|
|
41
40
|
http_req_t* http_req_new();
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
*/
|
|
19
19
|
#include <worker.h>
|
|
20
20
|
#include <stdlib.h>
|
|
21
|
-
|
|
21
|
+
|
|
22
|
+
extern config_t *Config;
|
|
22
23
|
|
|
23
24
|
http_resp_t* http_resp_new() {
|
|
24
25
|
LOG_FUNCTION
|
|
@@ -83,12 +84,6 @@ void http_resp_set(http_resp_t *rsp) {
|
|
|
83
84
|
rsp->scgi = NULL;
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
int http_resp_body_add(http_resp_t *rsp, const char* str, size_t len) {
|
|
87
|
-
LOG_FUNCTION
|
|
88
|
-
wr_buffer_add(rsp->resp_body, str, len);
|
|
89
|
-
return 0;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
87
|
int http_resp_process(http_resp_t *rsp) {
|
|
93
88
|
LOG_FUNCTION
|
|
94
89
|
rsp->scgi = scgi_new();
|
|
@@ -101,10 +96,10 @@ int http_resp_process(http_resp_t *rsp) {
|
|
|
101
96
|
size_t len;
|
|
102
97
|
|
|
103
98
|
len = sprintf(str, "%d", rsp->resp_code);
|
|
104
|
-
scgi_header_add(rsp->scgi,
|
|
99
|
+
scgi_header_add(rsp->scgi, Config->Worker.Header.resp_code.str, Config->Worker.Header.resp_code.len, str, len);
|
|
105
100
|
|
|
106
101
|
len = sprintf(str, "%d", rsp->resp_body->len);
|
|
107
|
-
scgi_header_add(rsp->scgi,
|
|
102
|
+
scgi_header_add(rsp->scgi, Config->Worker.Header.resp_content_len.str, Config->Worker.Header.resp_content_len.len, str, len);
|
|
108
103
|
|
|
109
104
|
scgi_content_length_add(rsp->scgi, rsp->resp_body->len + rsp->header.len);
|
|
110
105
|
|
|
@@ -126,14 +121,14 @@ void http_resp_file_write_cb(struct ev_loop* loop, struct ev_io* watcher, int re
|
|
|
126
121
|
ssize_t sent;
|
|
127
122
|
|
|
128
123
|
if (rsp->file) {
|
|
129
|
-
char buffer[
|
|
124
|
+
char buffer[Config->Worker.max_body_size];
|
|
130
125
|
ssize_t read;
|
|
131
126
|
int rv = fseek(rsp->file, rsp->bytes_write, SEEK_SET);
|
|
132
127
|
if (rv < 0) {
|
|
133
128
|
LOG_ERROR(WARN, "Error reading file:%s", strerror(errno));
|
|
134
129
|
return;
|
|
135
130
|
}
|
|
136
|
-
read = fread(buffer, 1,
|
|
131
|
+
read = fread(buffer, 1, Config->Worker.max_body_size, rsp->file);
|
|
137
132
|
sent = send(watcher->fd, buffer, read, 0);
|
|
138
133
|
}
|
|
139
134
|
|
|
@@ -212,14 +207,14 @@ void http_resp_file_send_cb(struct ev_loop* loop, struct ev_io* watcher, int rev
|
|
|
212
207
|
return;
|
|
213
208
|
}
|
|
214
209
|
#else
|
|
215
|
-
char buffer[
|
|
210
|
+
char buffer[Config->Worker.max_body_size];
|
|
216
211
|
ssize_t read, sent;
|
|
217
212
|
int rv = fseek(rsp->file, rsp->bytes_write, SEEK_SET);
|
|
218
213
|
if(rv < 0) {
|
|
219
214
|
LOG_ERROR(WARN,"Error reading file:%s",strerror(errno));
|
|
220
215
|
return;
|
|
221
216
|
}
|
|
222
|
-
read = fread(buffer, 1,
|
|
217
|
+
read = fread(buffer, 1, Config->Worker.max_body_size, rsp->file);
|
|
223
218
|
sent = send(watcher->fd, buffer, read, 0);
|
|
224
219
|
if (sent < 0) {
|
|
225
220
|
LOG_ERROR(SEVERE, "error in file sending: %s\n", strerror(errno));
|
|
@@ -274,7 +269,8 @@ void http_resp_header_write_cb(struct ev_loop* loop, struct ev_io* watcher, int
|
|
|
274
269
|
LOG_DEBUG(DEBUG, "http_resp_header_write_cb() starting read watcher. bytes write=%d", rsp->bytes_write);
|
|
275
270
|
if (rsp->resp_body->len > 0) {
|
|
276
271
|
rsp->bytes_write = 0;
|
|
277
|
-
if (w->http->
|
|
272
|
+
if (w->http->stat && w->http->resp->resp_code == 200 &&
|
|
273
|
+
rsp->resp_body->str == NULL) {
|
|
278
274
|
ev_io_init(watcher, http_resp_file_send_cb, w->req_fd, EV_WRITE);
|
|
279
275
|
//send_file(w);
|
|
280
276
|
//ev_io_init(watcher, http_resp_file_write_cb, w->req_fd, EV_WRITE);
|
|
@@ -41,7 +41,6 @@ struct http_resp_s {
|
|
|
41
41
|
http_resp_t* http_resp_new();
|
|
42
42
|
void http_resp_free(http_resp_t**);
|
|
43
43
|
void http_resp_set(http_resp_t*);
|
|
44
|
-
int http_resp_body_add(http_resp_t*, const char* , size_t);
|
|
45
44
|
int http_resp_process(http_resp_t*);
|
|
46
45
|
void http_resp_scgi_write_cb(struct ev_loop*, struct ev_io*, int);
|
|
47
46
|
|
data/src/worker/wkr_main.c
CHANGED
|
@@ -23,56 +23,28 @@
|
|
|
23
23
|
#include <ruby.h>
|
|
24
24
|
#include <rubysig.h>
|
|
25
25
|
#include <execinfo.h>
|
|
26
|
-
#ifdef __linux__
|
|
27
|
-
#include <sys/prctl.h>
|
|
28
|
-
#endif
|
|
29
26
|
|
|
30
|
-
|
|
27
|
+
#define DEFAULT_LOWER_LIMIT 1024
|
|
28
|
+
#define DEFAULT_UPPER_LIMIT 10485760
|
|
29
|
+
|
|
30
|
+
static wkr_t *worker = NULL;
|
|
31
|
+
config_t *Config = NULL;
|
|
31
32
|
|
|
32
33
|
struct ev_loop *loop; // Event loop
|
|
33
34
|
struct ev_idle idle_watcher;
|
|
34
|
-
int
|
|
35
|
-
|
|
36
|
-
static int drop_privileges(wkr_t *w) {
|
|
37
|
-
change_log_file_owner(w->tmp->uid, w->tmp->gid);
|
|
38
|
-
//setting read, effective, saved group and user id
|
|
39
|
-
if(setgid(w->tmp->gid)!=0) {
|
|
40
|
-
LOG_ERROR(SEVERE,"setegid() failed");
|
|
41
|
-
return -1;
|
|
42
|
-
}
|
|
43
|
-
if(setuid(w->tmp->uid)!=0) {
|
|
44
|
-
LOG_ERROR(SEVERE,"seteuid() failed");
|
|
45
|
-
return -1;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
LOG_DEBUG(DEBUG,"Passed userid=%d and groupid=%d",
|
|
49
|
-
w->tmp->uid, w->tmp->gid);
|
|
50
|
-
LOG_DEBUG(DEBUG,"effective userid=%d and groupid=%d",geteuid(),getegid());
|
|
51
|
-
#ifdef __linux__
|
|
52
|
-
int rv = prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
|
|
53
|
-
LOG_DEBUG(DEBUG,"prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) = %d", rv);
|
|
54
|
-
if (rv < 0) {
|
|
55
|
-
LOG_ERROR(SEVERE,"error setting prctl(PR_SET_DUMPABLE, 1, 0, 0, 0), errno = %d, desc = %s", errno, strerror(errno));
|
|
56
|
-
}
|
|
57
|
-
#endif
|
|
58
|
-
return 0;
|
|
59
|
-
}
|
|
35
|
+
int is_alive = 1;
|
|
60
36
|
|
|
61
37
|
/** Usage */
|
|
62
|
-
|
|
63
|
-
printf("usage: \n%s
|
|
64
|
-
printf("[-
|
|
65
|
-
printf("
|
|
66
|
-
printf("<application_path> = path of rails application. e.g. /home/xyz/rails_projects/app1\n");
|
|
67
|
-
printf("<environment> = rails environment. development/production. Default is production.\n");
|
|
68
|
-
printf("<cuid> = User id.\n");
|
|
69
|
-
printf("<cgid> = Group id.\n");
|
|
70
|
-
printf("<control port/sock path> = Control port number (control sock path in case [-i 1])\n");
|
|
38
|
+
void print_usage(char *appname) {
|
|
39
|
+
printf("usage: \n%s [-c <control_port/sock_path>] [-i <uds>] [-n <application_name>]",appname);
|
|
40
|
+
printf("[-l <log_level>] [-f <log_file>] [-o <root_path>] [-k <keep_alive>]\n");
|
|
41
|
+
printf("<control_port/sock_path> = Control port number (control sock path in case [-i 1])\n");
|
|
71
42
|
printf("<uds> = Unix domain socket flag. Value should be 0 or 1.\n");
|
|
72
|
-
printf("<application_type> = Type of application {rails, merb}.\n");
|
|
73
43
|
printf("<application_name> = Name of application\n");
|
|
74
|
-
printf("<
|
|
75
|
-
printf("<
|
|
44
|
+
printf("<log_level> = Logging Level\n");
|
|
45
|
+
printf("<log_file> = Name of the log file\n");
|
|
46
|
+
printf("<root_path> = Root directory path\n");
|
|
47
|
+
printf("<keep_alive> = Keep Alive flag value must be 'y'/'n'\n");
|
|
76
48
|
}
|
|
77
49
|
|
|
78
50
|
void sigproc() {
|
|
@@ -83,11 +55,12 @@ void sigproc() {
|
|
|
83
55
|
|
|
84
56
|
void cleanup() {
|
|
85
57
|
LOG_FUNCTION
|
|
86
|
-
|
|
58
|
+
ev_idle_stop(loop, &idle_watcher);
|
|
87
59
|
LOG_DEBUG(DEBUG,"stoping event loop");
|
|
88
60
|
ev_unloop(loop,EVUNLOOP_ALL);
|
|
89
61
|
//TODO: send worker stopping signal
|
|
90
62
|
worker_free(&worker);
|
|
63
|
+
wr_worker_config_free(Config);
|
|
91
64
|
LOG_INFO("Worker stopped and exiting gracefully.");
|
|
92
65
|
close_logger();
|
|
93
66
|
exit(0);
|
|
@@ -95,10 +68,10 @@ void cleanup() {
|
|
|
95
68
|
|
|
96
69
|
/** Handle segmentation fault */
|
|
97
70
|
void crash_handler(int sig) {
|
|
98
|
-
void *array[
|
|
71
|
+
void *array[Config->Worker.stack_tace];
|
|
99
72
|
size_t size;
|
|
100
73
|
char **bt_symbols;
|
|
101
|
-
char bt_string[
|
|
74
|
+
char bt_string[Config->Worker.stack_tace * STR_SIZE256];
|
|
102
75
|
int i;
|
|
103
76
|
|
|
104
77
|
LOG_ERROR(FATAL, "Got %d signal, trying to create core file.", sig);
|
|
@@ -129,7 +102,7 @@ void crash_handler(int sig) {
|
|
|
129
102
|
}
|
|
130
103
|
sleep(5);
|
|
131
104
|
// get void*'s for all entries on the stack
|
|
132
|
-
size = backtrace(array,
|
|
105
|
+
size = backtrace(array, Config->Worker.stack_tace);
|
|
133
106
|
bt_symbols = backtrace_symbols(array, size);
|
|
134
107
|
strcpy(bt_string, "\n");
|
|
135
108
|
for(i = 0; i < size; i++) {
|
|
@@ -142,34 +115,43 @@ void crash_handler(int sig) {
|
|
|
142
115
|
cleanup();
|
|
143
116
|
}
|
|
144
117
|
|
|
118
|
+
/** Read and set Worker Configuration **/
|
|
119
|
+
void wr_worker_config_read(){
|
|
120
|
+
LOG_FUNCTION
|
|
121
|
+
node_t *root;
|
|
122
|
+
|
|
123
|
+
LOG_DEBUG(4,"YAML file path %s", Config->Worker.File.internal_config);
|
|
124
|
+
root = yaml_parse(Config->Worker.File.internal_config.str);
|
|
125
|
+
|
|
126
|
+
if(!root) {
|
|
127
|
+
LOG_ERROR(SEVERE, "Config file found with erroneous entries. Please correct it.");
|
|
128
|
+
printf("Config file found with erroneous entries. Please correct it.\n");
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
wr_set_numeric_value(root, "Worker/maximum_request_body_size", &Config->Worker.max_body_size, FALSE);
|
|
133
|
+
node_free(root);
|
|
134
|
+
|
|
135
|
+
Config->Worker.Compress.lower_limit = DEFAULT_LOWER_LIMIT;
|
|
136
|
+
Config->Worker.Compress.upper_limit = DEFAULT_UPPER_LIMIT;
|
|
137
|
+
}
|
|
138
|
+
|
|
145
139
|
/** Parse command line arguments */
|
|
146
|
-
|
|
140
|
+
wkr_tmp_t* parse_args(int argc, char **argv) {
|
|
147
141
|
int option;
|
|
148
142
|
extern char *optarg;
|
|
149
143
|
size_t len;
|
|
150
144
|
char *str;
|
|
151
|
-
int invalid_arg_flag = 0,
|
|
145
|
+
int invalid_arg_flag = 0, log_level = INFO;
|
|
152
146
|
wkr_tmp_t *tmp = wkr_tmp_new();
|
|
153
|
-
|
|
147
|
+
|
|
154
148
|
if(tmp == NULL)
|
|
155
149
|
return NULL;
|
|
156
|
-
|
|
157
|
-
while ( (option=getopt(argc,argv,"
|
|
150
|
+
|
|
151
|
+
while ( (option=getopt(argc,argv,"l:f:c:i:n:o:k:")) != -1 ) {
|
|
158
152
|
str = optarg;
|
|
159
153
|
len = strlen(str);
|
|
160
|
-
switch ( option ) {
|
|
161
|
-
case 'a': // Application Path
|
|
162
|
-
wr_string_new(tmp->path, str, len);
|
|
163
|
-
app_path_flag = 1;
|
|
164
|
-
break;
|
|
165
|
-
case 'b': // Ruby library path
|
|
166
|
-
wr_string_new(tmp->ruby_path, str, len);
|
|
167
|
-
tmp->script_path.str = (char*) malloc(sizeof(char)*(tmp->ruby_path.len + 32));
|
|
168
|
-
tmp->script_path.len = sprintf(tmp->script_path.str, "%s%swebroar_app_loader.rb", tmp->ruby_path.str, WR_PATH_SEPARATOR);
|
|
169
|
-
break;
|
|
170
|
-
case 'e': // Application environment
|
|
171
|
-
wr_string_new(tmp->env, str, len);
|
|
172
|
-
break;
|
|
154
|
+
switch ( option ) {
|
|
173
155
|
case 'l': // Logging level
|
|
174
156
|
log_level = atoi(optarg);
|
|
175
157
|
break;
|
|
@@ -177,12 +159,6 @@ static inline wkr_tmp_t* parse_args(int argc, char **argv) {
|
|
|
177
159
|
wr_string_free(tmp->log_file);
|
|
178
160
|
wr_string_new(tmp->log_file, str, len);
|
|
179
161
|
break;
|
|
180
|
-
case 'g': // Group id
|
|
181
|
-
tmp->gid = atoi(optarg);
|
|
182
|
-
break;
|
|
183
|
-
case 'u': // User id
|
|
184
|
-
tmp->uid = atoi(optarg);
|
|
185
|
-
break;
|
|
186
162
|
case 'c': // Control path
|
|
187
163
|
wr_string_new(tmp->ctl_path, str, len);
|
|
188
164
|
break;
|
|
@@ -191,9 +167,6 @@ static inline wkr_tmp_t* parse_args(int argc, char **argv) {
|
|
|
191
167
|
tmp->is_uds = TRUE;
|
|
192
168
|
}
|
|
193
169
|
break;
|
|
194
|
-
case 't': // Application type
|
|
195
|
-
wr_string_new(tmp->type, str, len);
|
|
196
|
-
break;
|
|
197
170
|
case 'n': // Application name
|
|
198
171
|
wr_string_new(tmp->name, str, len);
|
|
199
172
|
wr_string_free(tmp->log_file);
|
|
@@ -203,14 +176,6 @@ static inline wkr_tmp_t* parse_args(int argc, char **argv) {
|
|
|
203
176
|
case 'o': // Server root path
|
|
204
177
|
wr_string_new(tmp->root_path, str, len);
|
|
205
178
|
break;
|
|
206
|
-
case 'r': // Applicaiton base uri
|
|
207
|
-
wr_string_new(tmp->resolver, str, len);
|
|
208
|
-
break;
|
|
209
|
-
case 'p': // Analytics flag
|
|
210
|
-
if(strcmp(optarg, "y")==0) {
|
|
211
|
-
tmp->profiler = 'y';
|
|
212
|
-
}
|
|
213
|
-
break;
|
|
214
179
|
case 'k':
|
|
215
180
|
if(strcmp(optarg, "n")==0) {
|
|
216
181
|
tmp->keep_alive = FALSE;
|
|
@@ -220,9 +185,12 @@ static inline wkr_tmp_t* parse_args(int argc, char **argv) {
|
|
|
220
185
|
invalid_arg_flag++;
|
|
221
186
|
}
|
|
222
187
|
}
|
|
223
|
-
|
|
188
|
+
|
|
189
|
+
Config = wr_worker_config_init(tmp->root_path.str);
|
|
190
|
+
wr_worker_config_read();
|
|
191
|
+
|
|
224
192
|
if(tmp->log_file.str){
|
|
225
|
-
initialize_logger(tmp->log_file.str,
|
|
193
|
+
initialize_logger(tmp->log_file.str, Config->Worker.Server.name.str, Config->Worker.Server.version.str);
|
|
226
194
|
redirect_standard_io();
|
|
227
195
|
#ifdef L_DEBUG
|
|
228
196
|
set_log_severity(DEBUG);
|
|
@@ -232,14 +200,16 @@ static inline wkr_tmp_t* parse_args(int argc, char **argv) {
|
|
|
232
200
|
}else{
|
|
233
201
|
perror("Log file is not specified.");
|
|
234
202
|
}
|
|
235
|
-
|
|
236
|
-
if (invalid_arg_flag > 0 ||
|
|
203
|
+
|
|
204
|
+
if (invalid_arg_flag > 0 || tmp->root_path.str == NULL || Config == NULL) {
|
|
237
205
|
print_usage(argv[0]);
|
|
238
|
-
LOG_ERROR(SEVERE, "Either argument is invalid or application path is not passed.");
|
|
206
|
+
LOG_ERROR(SEVERE, "Either argument is invalid or application/root path is not passed.");
|
|
239
207
|
wkr_tmp_free(&tmp);
|
|
208
|
+
wr_worker_config_free(Config);
|
|
240
209
|
return NULL;
|
|
241
210
|
}
|
|
242
|
-
|
|
211
|
+
|
|
212
|
+
if(strcmp(tmp->name.str, Config->Worker.static_server.str) == 0){
|
|
243
213
|
tmp->is_static = 1;
|
|
244
214
|
}
|
|
245
215
|
return tmp;
|
|
@@ -252,11 +222,6 @@ void start_idle_watcher() {
|
|
|
252
222
|
}
|
|
253
223
|
}
|
|
254
224
|
|
|
255
|
-
void stop_idle_watcher() {
|
|
256
|
-
LOG_FUNCTION
|
|
257
|
-
ev_idle_stop(loop, &idle_watcher);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
225
|
void idle_cb (struct ev_loop *loop, struct ev_idle *w, int revents) {
|
|
261
226
|
LOG_FUNCTION
|
|
262
227
|
/* Calling libev's blocking call ev_loop() between TRAP_* macros were working on Ruby 1.8,
|
|
@@ -264,7 +229,7 @@ void idle_cb (struct ev_loop *loop, struct ev_idle *w, int revents) {
|
|
|
264
229
|
*/
|
|
265
230
|
if(rb_thread_alone()) {
|
|
266
231
|
/* Stop scheduling ruby threads, there is only one! */
|
|
267
|
-
|
|
232
|
+
ev_idle_stop(loop, &idle_watcher);
|
|
268
233
|
} else {
|
|
269
234
|
/* TODO: Found following three api to schedule ruby threads
|
|
270
235
|
* rb_thread_schedule() was getting called infinitely and eating most of the CPU.
|
|
@@ -280,10 +245,16 @@ void idle_cb (struct ev_loop *loop, struct ev_idle *w, int revents) {
|
|
|
280
245
|
}
|
|
281
246
|
}
|
|
282
247
|
|
|
248
|
+
void init_idle_watcher(wkr_t *w){
|
|
249
|
+
if(!w->http->stat){
|
|
250
|
+
ev_idle_init (&idle_watcher, idle_cb);
|
|
251
|
+
start_idle_watcher();
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
283
255
|
int main(int argc, char **argv) {
|
|
284
|
-
int retval = 0;
|
|
285
256
|
wkr_t* w = NULL;
|
|
286
|
-
|
|
257
|
+
|
|
287
258
|
if(argc == 1) {
|
|
288
259
|
print_usage(argv[0]);
|
|
289
260
|
return -1;
|
|
@@ -298,70 +269,33 @@ int main(int argc, char **argv) {
|
|
|
298
269
|
wkr_tmp_t *tmp = parse_args(argc, argv);
|
|
299
270
|
if(tmp == NULL)
|
|
300
271
|
return -1;
|
|
301
|
-
|
|
302
272
|
loop = ev_default_loop (0);
|
|
303
273
|
|
|
304
274
|
w = worker_new(loop, tmp);
|
|
305
|
-
if(w==NULL)
|
|
306
|
-
goto err;
|
|
307
|
-
worker = w;
|
|
308
275
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
if((retval = drop_privileges(w))!=0) {
|
|
313
|
-
goto err;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
w->http = http_new(w);
|
|
317
|
-
if(w->http == NULL) {
|
|
318
|
-
LOG_ERROR(SEVERE,"unable to load application.");
|
|
319
|
-
goto err;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
retval = worker_connect(w);
|
|
323
|
-
if(retval<0) {
|
|
324
|
-
LOG_ERROR(WARN,"Error Initializing Workers.");
|
|
325
|
-
retval = -1;
|
|
326
|
-
goto err;
|
|
276
|
+
if(w==NULL){
|
|
277
|
+
wr_worker_config_free(Config);
|
|
278
|
+
return -1;
|
|
327
279
|
}
|
|
328
280
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
w->tmp->ruby_path.str, w->tmp->root_path.str);
|
|
332
|
-
LOG_DEBUG(DEBUG,"path = %s, name = %s, type = %s, environment = %s, baseuri = %s, analytics = %c",
|
|
333
|
-
w->tmp->path.str, w->tmp->name.str, w->tmp->type.str,
|
|
334
|
-
w->tmp->env.str, w->tmp->resolver.str, w->tmp->profiler);
|
|
335
|
-
|
|
336
|
-
LOG_INFO("Successfully loaded rack application=%s with environment=%s",
|
|
337
|
-
w->tmp->path.str, w->tmp->env.str);
|
|
338
|
-
|
|
281
|
+
worker = w;
|
|
282
|
+
|
|
339
283
|
//TODO: Windows Portability?
|
|
340
284
|
signal(SIGHUP, sigproc); /* catch hangup signal */
|
|
341
285
|
signal(SIGINT, sigproc);
|
|
342
286
|
signal(SIGTERM, sigproc);
|
|
343
|
-
// signal(SIGCHLD, SIG_IGN);
|
|
287
|
+
// signal(SIGCHLD, SIG_IGN);
|
|
344
288
|
signal(SIGTSTP, SIG_IGN);
|
|
345
289
|
signal(SIGTTOU, SIG_IGN);
|
|
346
|
-
signal(SIGTTIN, SIG_IGN);
|
|
290
|
+
signal(SIGTTIN, SIG_IGN);
|
|
347
291
|
signal(SIGPIPE, SIG_IGN);
|
|
348
292
|
|
|
349
|
-
worker_accept_requests(w);
|
|
350
|
-
LOG_INFO("Worker ready for serving requests.");
|
|
351
|
-
|
|
352
|
-
if(!w->http->is_static){
|
|
353
|
-
ev_idle_init (&idle_watcher, idle_cb);
|
|
354
|
-
start_idle_watcher();
|
|
355
|
-
}
|
|
356
|
-
|
|
357
293
|
while(is_alive ==1) {
|
|
358
294
|
/* TODO: wrapping ev_loop() between TARP_* macros didn't worked in Ruby 1.9 */
|
|
359
295
|
//TRAP_BEG;
|
|
360
296
|
ev_loop(loop,EVLOOP_ONESHOT);
|
|
361
297
|
//TRAP_END;
|
|
362
298
|
}
|
|
363
|
-
|
|
364
|
-
err:
|
|
365
299
|
cleanup();
|
|
366
|
-
return
|
|
300
|
+
return 0;
|
|
367
301
|
}
|