mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-06-16 02:15:48 +00:00
4f57ef33af
This reverts commit ba3ac9ad09.
Since it looks like add_export_option does not copy the string we
shouldn't free it.
288 lines
4.9 KiB
C
288 lines
4.9 KiB
C
#ifdef UWSGI_YAML
|
|
|
|
#include "uwsgi.h"
|
|
|
|
extern struct uwsgi_server uwsgi;
|
|
|
|
|
|
#ifndef UWSGI_LIBYAML
|
|
/*
|
|
yaml file must be read ALL into memory.
|
|
This memory must not be freed for all the server lifecycle
|
|
*/
|
|
|
|
void yaml_rstrip(char *line) {
|
|
|
|
off_t i;
|
|
|
|
for (i = strlen(line) - 1; i >= 0; i--) {
|
|
if (line[i] == ' ' || line[i] == '\t') {
|
|
line[i] = 0;
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
char *yaml_lstrip(char *line) {
|
|
|
|
off_t i;
|
|
char *ptr = line;
|
|
|
|
for (i = 0; i < (int) strlen(line); i++) {
|
|
if (line[i] == ' ' || line[i] == '\t' || line[i] == '\r') {
|
|
ptr++;
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
|
|
|
|
int yaml_get_depth(char *line) {
|
|
|
|
off_t i;
|
|
int depth = 0;
|
|
|
|
for (i = 0; i < (int) strlen(line); i++) {
|
|
if (line[i] == ' ') {
|
|
depth++;
|
|
continue;
|
|
}
|
|
else if (line[i] == '\t' || line[i] == '\r') {
|
|
depth += 8;
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return depth;
|
|
}
|
|
|
|
char *yaml_get_line(char *yaml, size_t size) {
|
|
|
|
size_t i;
|
|
char *ptr = yaml;
|
|
int comment = 0;
|
|
|
|
for (i = 0; i < size; i++) {
|
|
ptr++;
|
|
if (yaml[i] == '#') {
|
|
yaml[i] = 0;
|
|
comment = 1;
|
|
}
|
|
else if (yaml[i] == '\n') {
|
|
yaml[i] = 0;
|
|
return ptr;
|
|
}
|
|
else if (comment) {
|
|
yaml[i] = 0;
|
|
}
|
|
}
|
|
|
|
// check if it is a stupid file without \n at the end
|
|
if (ptr > yaml) {
|
|
return ptr;
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
#else
|
|
#include <yaml.h>
|
|
#endif
|
|
|
|
void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
|
|
|
size_t len = 0;
|
|
char *yaml;
|
|
|
|
int in_uwsgi_section = 0;
|
|
|
|
char *key = NULL;
|
|
char *val = NULL;
|
|
|
|
char *section_asked = "uwsgi";
|
|
char *colon;
|
|
|
|
if (uwsgi_check_scheme(file)) {
|
|
colon = uwsgi_get_last_char(file, '/');
|
|
colon = uwsgi_get_last_char(colon, ':');
|
|
}
|
|
else {
|
|
colon = uwsgi_get_last_char(file, ':');
|
|
}
|
|
|
|
if (colon) {
|
|
colon[0] = 0;
|
|
if (colon[1] != 0) {
|
|
section_asked = colon + 1;
|
|
}
|
|
}
|
|
|
|
uwsgi_log_initial("[uWSGI] getting YAML configuration from %s\n", file);
|
|
|
|
yaml = uwsgi_open_and_read(file, &len, 1, magic_table);
|
|
|
|
#ifdef UWSGI_LIBYAML
|
|
yaml_parser_t parser;
|
|
yaml_token_t token;
|
|
int status = 0;
|
|
int parsing = 1;
|
|
|
|
if (!yaml_parser_initialize(&parser)) {
|
|
uwsgi_log("unable to initialize YAML parser (libyaml)\n");
|
|
exit(1);
|
|
}
|
|
|
|
yaml_parser_set_input_string(&parser, (unsigned char *) yaml, (size_t) len - 1);
|
|
|
|
while (parsing) {
|
|
if (!yaml_parser_scan(&parser, &token)) {
|
|
uwsgi_log("error parsing YAML file: %s (%c)\n", parser.problem, yaml[parser.problem_offset]);
|
|
exit(1);
|
|
}
|
|
switch (token.type) {
|
|
case YAML_STREAM_END_TOKEN:
|
|
parsing = 0;
|
|
break;
|
|
case YAML_KEY_TOKEN:
|
|
status = 1;
|
|
break;
|
|
case YAML_VALUE_TOKEN:
|
|
status = 2;
|
|
break;
|
|
case YAML_FLOW_SEQUENCE_START_TOKEN:
|
|
case YAML_BLOCK_SEQUENCE_START_TOKEN:
|
|
status = 3;
|
|
break;
|
|
case YAML_BLOCK_MAPPING_START_TOKEN:
|
|
if (!in_uwsgi_section) {
|
|
if (key) {
|
|
if (!strcmp(section_asked, key)) {
|
|
in_uwsgi_section = 1;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case YAML_BLOCK_END_TOKEN:
|
|
if (in_uwsgi_section) {
|
|
parsing = 0;
|
|
break;
|
|
}
|
|
break;
|
|
case YAML_SCALAR_TOKEN:
|
|
case YAML_FLOW_ENTRY_TOKEN:
|
|
case YAML_BLOCK_ENTRY_TOKEN:
|
|
if (status == 1) {
|
|
key = (char *) token.data.scalar.value;
|
|
}
|
|
else if (status == 2) {
|
|
val = (char *) token.data.scalar.value;
|
|
if (key && val && in_uwsgi_section) {
|
|
add_exported_option(key, val, 0);
|
|
}
|
|
status = 0;
|
|
}
|
|
else if (status == 3) {
|
|
val = (char *) token.data.scalar.value;
|
|
if (key && val && in_uwsgi_section) {
|
|
add_exported_option(key, val, 0);
|
|
}
|
|
}
|
|
else {
|
|
uwsgi_log("unsupported YAML token in %s block\n", section_asked);
|
|
parsing = 0;
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
status = 0;
|
|
}
|
|
}
|
|
|
|
#else
|
|
int depth;
|
|
int current_depth = 0;
|
|
int lines = 1;
|
|
char *yaml_line;
|
|
char *section = "";
|
|
|
|
|
|
while (len) {
|
|
yaml_line = yaml_get_line(yaml, len);
|
|
if (yaml_line == NULL) {
|
|
break;
|
|
}
|
|
lines++;
|
|
|
|
// skip empty line
|
|
if (yaml[0] == 0)
|
|
goto next;
|
|
depth = yaml_get_depth(yaml);
|
|
if (depth <= current_depth) {
|
|
current_depth = depth;
|
|
// end the parsing cycle
|
|
if (in_uwsgi_section)
|
|
return;
|
|
}
|
|
else if (depth > current_depth && !in_uwsgi_section) {
|
|
goto next;
|
|
}
|
|
|
|
key = yaml_lstrip(yaml);
|
|
// skip empty line
|
|
if (key[0] == 0)
|
|
goto next;
|
|
|
|
// skip list and {} defined dict
|
|
if (key[0] == '-' || key[0] == '[' || key[0] == '{') {
|
|
if (in_uwsgi_section)
|
|
return;
|
|
goto next;
|
|
}
|
|
|
|
if (!in_uwsgi_section) {
|
|
section = strchr(key, ':');
|
|
if (!section)
|
|
goto next;
|
|
section[0] = 0;
|
|
if (!strcmp(key, section_asked)) {
|
|
in_uwsgi_section = 1;
|
|
}
|
|
}
|
|
else {
|
|
// get dict value
|
|
val = strstr(key, ": ");
|
|
if (!val) {
|
|
val = strstr(key, ":\t");
|
|
}
|
|
if (!val)
|
|
return;
|
|
// get the right key
|
|
val[0] = 0;
|
|
// yeah overengeneering....
|
|
yaml_rstrip(key);
|
|
|
|
val = yaml_lstrip(val + 2);
|
|
yaml_rstrip(val);
|
|
|
|
//uwsgi_log("YAML: %s = %s\n", key, val);
|
|
|
|
add_exported_option((char *) key, val, 0);
|
|
}
|
|
next:
|
|
len -= (yaml_line - yaml);
|
|
yaml += (yaml_line - yaml);
|
|
|
|
}
|
|
#endif
|
|
|
|
if (colon) colon[0] = ':';
|
|
|
|
}
|
|
|
|
#endif
|