19 #include <sys/types.h>
29 #define GRN_NO_FLAGS 0
82 char *null_terminated_c_string;
85 if (!null_terminated_c_string) {
89 memcpy(null_terminated_c_string, string->
data, string->
len);
90 null_terminated_c_string[
string->len] =
'\0';
92 return null_terminated_c_string;
96 ngx_str_equal_c_string(
ngx_str_t *
string,
const char *c_string)
98 if (string->
len != strlen(c_string)) {
102 return memcmp(c_string, string->
data, string->
len) == 0;
107 const char *timestamp,
const char *title,
108 const char *
message,
const char *location,
112 const char level_marks[] =
" EACewnid-";
116 if (location && *location) {
119 timestamp, *(level_marks + level), title, message,
124 timestamp, *(level_marks + level), title, message);
126 ngx_write_fd(logger_data->
file->
fd, buffer, last - buffer);
130 ngx_http_groonga_logger_reopen(
grn_ctx *ctx,
void *user_data)
138 ngx_http_groonga_logger_fin(
grn_ctx *ctx,
void *user_data)
149 ngx_http_groonga_logger_log,
150 ngx_http_groonga_logger_reopen,
151 ngx_http_groonga_logger_fin
169 "http_groonga: failed to allocate memory for logger");
173 logger_data->
pool = pool;
176 ngx_http_groonga_logger.
user_data = logger_data;
183 ngx_http_groonga_query_logger_log(
grn_ctx *ctx,
unsigned int flag,
184 const char *timestamp,
const char *info,
185 const char *message,
void *user_data)
193 timestamp, info, message);
194 ngx_write_fd(data->
file->
fd, buffer, last - buffer);
198 ngx_http_groonga_query_logger_reopen(
grn_ctx *ctx,
void *user_data)
203 "query log will be closed: <%.*s>",
207 "query log is opened: <%.*s>",
212 ngx_http_groonga_query_logger_fin(
grn_ctx *ctx,
void *user_data)
222 ngx_http_groonga_query_logger_log,
223 ngx_http_groonga_query_logger_reopen,
224 ngx_http_groonga_query_logger_fin
228 ngx_http_groonga_context_init_query_logger(
grn_ctx *context,
241 if (!query_logger_data) {
243 "http_groonga: failed to allocate memory for query logger");
247 query_logger_data->
pool = pool;
250 ngx_http_groonga_query_logger.
user_data = query_logger_data;
257 ngx_http_groonga_context_init(
grn_ctx *context,
266 status = ngx_http_groonga_context_init_logger(context,
275 status = ngx_http_groonga_context_init_query_logger(context,
284 if (location_conf->
cache) {
307 ngx_http_groonga_context_log_error(log, context);
317 if (buffer == NULL) {
330 ngx_http_groonga_handler_cleanup(
void *user_data)
349 ngx_http_groonga_context_receive_handler(
grn_ctx *context,
355 unsigned int result_size = 0;
362 grn_ctx_recv(context, &result, &result_size, &recv_flags);
379 grn_ctx_recv(context, &result, &result_size, &recv_flags);
388 if (result_size > 0 ||
391 if (result_size > 0) {
409 size_t base_path_length;
419 base_path_length = http_location_conf->
name.
len;
423 "requested URI is shorter than groonga_base_path: "
424 "URI: <%V>, groonga_base_path: <%V>",
426 }
else if (strncmp((
const char *)command_path->
data,
430 "groonga_base_path doesn't match requested URI: "
431 "URI: <%V>, groonga_base_path: <%V>",
437 command_path->
data += base_path_length;
438 command_path->
len -= base_path_length;
439 if (command_path->
len > 0 && command_path->
data[0] ==
'/') {
440 command_path->
data += 1;
441 command_path->
len -= 1;
443 if (command_path->
len == 0) {
452 const char *content_type)
475 cleanup->
handler = ngx_http_groonga_handler_cleanup;
476 data = cleanup->
data;
480 rc = ngx_http_groonga_context_init(context, location_conf,
490 rc = ngx_http_groonga_context_check_error(r->
connection->
log, context);
496 ngx_http_groonga_context_receive_handler,
516 ngx_http_groonga_context_log_error(r->
connection->
log, context);
532 command.
len = command_path->
len;
536 if (ngx_str_equal_c_string(&command,
"load")) {
541 ngx_http_groonga_handler_set_content_type(r,
"text/plain");
550 ngx_http_groonga_send_lines(
grn_ctx *context,
559 for (line_start = current; current < last; current++) {
560 if (*current !=
'\n') {
564 grn_ctx_send(context, (
const char *)line_start, current - line_start,
566 rc = ngx_http_groonga_context_check_error(r->
connection->
log, context);
570 line_start = current + 1;
572 if (line_start < current) {
573 grn_ctx_send(context, (
const char *)line_start, current - line_start,
575 rc = ngx_http_groonga_context_check_error(r->
connection->
log, context);
603 for (current = chain; current; current = current->
next) {
609 "http_groonga: failed to allocate memory for request body");
614 for (current = chain; current; current = current->
next) {
615 buffer = current->
buf;
622 "http_groonga: failed to read a request body stored in a file");
628 out_cursor += buffer_size;
632 *out_end = out + out_size;
647 u_char *body_data_end;
653 ngx_http_groonga_handler_set_content_type(r,
"text/plain");
658 rc = ngx_http_groonga_join_request_body_chain(r,
666 rc = ngx_http_groonga_send_lines(context, r, body_data, body_data_end);
680 rc = ngx_http_groonga_handler_validate_post_command(r, command_path, data);
685 rc = ngx_http_groonga_handler_process_command_path(r, command_path, data);
690 rc = ngx_http_groonga_handler_process_body(r, data);
708 new_chain->
next = NULL;
715 while (last_chain->
next) {
716 last_chain = last_chain->
next;
718 last_chain->
next = new_chain;
728 const char *content_type;
729 ngx_buf_t *head_buf, *body_buf, *foot_buf;
738 ngx_http_groonga_handler_set_content_type(r, content_type);
742 head_buf = ngx_http_groonga_grn_obj_to_ngx_buf(r->
pool, &(data->
head));
747 body_buf = ngx_http_groonga_grn_obj_to_ngx_buf(r->
pool, &(data->
body));
752 foot_buf = ngx_http_groonga_grn_obj_to_ngx_buf(r->
pool, &(data->
foot));
758 head_chain.
buf = head_buf;
759 output_chain = ngx_http_groonga_attach_chain(output_chain, &head_chain);
760 body_chain.
buf = body_buf;
761 output_chain = ngx_http_groonga_attach_chain(output_chain, &body_chain);
762 foot_chain.
buf = foot_buf;
763 output_chain = ngx_http_groonga_attach_chain(output_chain, &foot_chain);
791 rc = ngx_http_groonga_extract_command_path(r, &command_path);
796 rc = ngx_http_groonga_handler_create_data(r, &data);
801 rc = ngx_http_groonga_handler_process_command_path(r, &command_path, data);
812 rc = ngx_http_groonga_handler_send_response(r, data);
824 rc = ngx_http_groonga_extract_command_path(r, &command_path);
826 rc = ngx_http_groonga_handler_create_data(r, &data);
829 rc = ngx_http_groonga_handler_process_load(r, &command_path, data);
832 ngx_http_groonga_handler_send_response(r, data);
844 rc = ngx_http_groonga_handler_get(r);
874 if (groonga_location_conf->
enabled) {
875 location_conf->
handler = ngx_http_groonga_handler;
876 groonga_location_conf->
name =
877 ngx_str_null_terminate(cf->
pool, &(location_conf->
name));
904 if (strncmp((
const char *)(groonga_location_conf->
log_path.
data),
912 if (!groonga_location_conf->
log_file) {
914 "http_groonga: failed to open groonga log file: <%V>",
915 &(groonga_location_conf->
log_path));
930 value = ngx_str_null_terminate(cf->
cycle->
pool,
932 if (strcasecmp(value,
"none") == 0) {
934 }
else if (strcasecmp(value,
"emergency") == 0) {
936 }
else if (strcasecmp(value,
"alert") == 0) {
938 }
else if (strcasecmp(value,
"critical") == 0) {
940 }
else if (strcasecmp(value,
"error") == 0) {
942 }
else if (strcasecmp(value,
"warning") == 0) {
944 }
else if (strcasecmp(value,
"notice") == 0) {
946 }
else if (strcasecmp(value,
"info") == 0) {
948 }
else if (strcasecmp(value,
"debug") == 0) {
950 }
else if (strcasecmp(value,
"dump") == 0) {
953 status =
"must be one of 'none', 'emergency', 'alert', "
954 "'ciritical', 'error', 'warning', 'notice', 'info', 'debug' and 'dump'";
962 ngx_http_groonga_conf_set_query_log_path_slot(
ngx_conf_t *cf,
988 "http_groonga: failed to open groonga query log file: <%V>",
997 ngx_http_groonga_create_loc_conf(
ngx_conf_t *cf)
1028 ngx_http_groonga_merge_loc_conf(
ngx_conf_t *cf,
void *parent,
void *child)
1040 #ifdef NGX_HTTP_GROONGA_LOG_PATH
1043 default_log_path.
data = (u_char *)NGX_HTTP_GROONGA_LOG_PATH;
1044 default_log_path.
len = strlen(NGX_HTTP_GROONGA_LOG_PATH);
1049 "failed to open the default groonga log file: <%V>",
1059 NGX_HTTP_GROONGA_QUERY_LOG_PATH);
1066 "failed to open the default groonga query log file: <%V>",
1094 ngx_http_groonga_each_loc_conf_in_tree(node->
left, callback, user_data);
1095 ngx_http_groonga_each_loc_conf_in_tree(node->
right, callback, user_data);
1096 ngx_http_groonga_each_loc_conf_in_tree(node->
tree, callback, user_data);
1118 server_conf = server_confs[
i];
1127 ngx_http_groonga_mkdir_p(
ngx_log_t *log,
const char *dir_name)
1130 size_t i, dir_name_length;
1132 dir_name_length = strlen(dir_name);
1133 sub_path[0] = dir_name[0];
1134 for (i = 1; i < dir_name_length + 1; i++) {
1135 if (dir_name[i] ==
'/' || dir_name[i] ==
'\0') {
1136 struct stat stat_buffer;
1138 if (stat(sub_path, &stat_buffer) == -1) {
1141 "failed to create directory: %s (%s): %s",
1148 sub_path[
i] = dir_name[
i];
1158 const char *database_base_name;
1162 if (database_base_name) {
1164 database_dir[0] =
'\0';
1165 strncat(database_dir,
1168 data->
rc = ngx_http_groonga_mkdir_p(data->
log, database_dir);
1174 context = &(location_conf->
context);
1181 "failed to create groonga database: %s",
1193 context = &(location_conf->
context);
1194 data->
rc = ngx_http_groonga_context_init(context, location_conf,
1202 "%s: \"groonga_database\" must be specified in block at %s:%d",
1203 location_conf->
name,
1218 ngx_http_groonga_create_database(location_conf, data);
1221 "failed to open groonga database: %s",
1229 if (!location_conf->
cache) {
1231 "failed to open groonga cache: %s",
1238 location_conf->
cache,
1250 context = &(location_conf->
context);
1251 ngx_http_groonga_context_init_logger(context,
1255 ngx_http_groonga_context_init_query_logger(context,
1262 ngx_http_groonga_context_log_error(data->
log, context);
1290 ngx_http_groonga_each_loc_conf(http_conf,
1291 ngx_http_groonga_open_database_callback,
1307 ngx_http_groonga_each_loc_conf(http_conf,
1308 ngx_http_groonga_close_database_callback,
1320 ngx_http_groonga_conf_set_groonga_slot,
1332 {
ngx_string(
"groonga_database_auto_create"),
1348 ngx_http_groonga_conf_set_log_path_slot,
1355 ngx_http_groonga_conf_set_log_level_slot,
1362 ngx_http_groonga_conf_set_query_log_path_slot,
1387 ngx_http_groonga_create_loc_conf,
1388 ngx_http_groonga_merge_loc_conf,
1393 &ngx_http_groonga_module_ctx,
1394 ngx_http_groonga_commands,
1398 ngx_http_groonga_init_process,
1401 ngx_http_groonga_exit_process,