bool read822(struct req *req) { char buf[BUFSIZ]; xstr *input = xstr_create("", req); while (fgets(buf, sizeof(buf), stdin)) { if (!buf[0] || buf[0] == '\n') break; xstr_append(input, buf); } /* eof? */ if (xstr_length(input) == 0) exit(0); dbg(8, "parsing %s\n", xstr_string(input)); req->params = ut_new_thash( rfc822_parse(xstr_string(input), req), req); return common(req, true); }
__USE_LIBASN int main(int argc, char *argv[]) { char buf[BUFSIZ]; mmatic *mm = mmatic_create(); xstr *xs = xstr_create("", mm); json *js = json_create(mm); while (fgets(buf, BUFSIZ, stdin)) xstr_append(xs, buf); ut *parsed = json_parse(js, xstr_string(xs)); if (ut_ok(parsed)) printf("%s", json_print(js, parsed)); else printf("%s\n", ut_err(parsed)); return 0; }
static char *get_query(struct req *req) { const char *orig_query; int i; bool inspace = false; xstr *query; query = xstr_create("", req); orig_query = uth_char(req->params, "query"); i = sizeof SQLER_TAG; if (i > xstr_length(uth_xstr(req->params, "query"))) goto end; /* skip whitechars */ for (; orig_query[i]; i++) if (isalpha(orig_query[i])) break; /* replace all whitechars, newlines, etc with single space */ for (; orig_query[i]; i++) { switch (orig_query[i]) { case ' ': if (inspace) continue; xstr_append_char(query, orig_query[i]); inspace = true; break; case '\t': case '\r': case '\n': break; default: xstr_append_char(query, orig_query[i]); inspace = false; } } end: return xstr_string(query); }
/** Parse config file * @retval 0 success * @retval 1 syntax error * @retval 2 logic error * @retval 3 other error */ static int parse_config(struct mg *mg) { FILE *fp; xstr *xs; char buf[4096], *str; json *js; ut *cfg; /* read file contents, ignoring empty lines and comments */ fp = fopen(mg->options.conf_file, "r"); if (!fp) { dbg(0, "%s: fopen() failed: %s\n", mg->options.conf_file, strerror(errno)); return 3; } xs = xstr_create("{", mg->mmtmp); while (fgets(buf, sizeof buf, fp)) { str = pjf_trim(buf); if (!str || !str[0] || str[0] == '#') continue; xstr_append(xs, str); } xstr_append_char(xs, '}'); fclose(fp); /* parse config file as loose JSON */ js = json_create(mg->mmtmp); json_setopt(js, JSON_LOOSE, 1); cfg = json_parse(js, xstr_string(xs)); if (!ut_ok(cfg)) { dbg(0, "parsing config file failed: %s\n", ut_err(cfg)); return 1; } /* parse config */ return (parse_config_ut(mg, cfg) ? 2 : 0); }
static bool readjson_len(struct req *req, int len) { char buf[BUFSIZ]; xstr *xs = xstr_create("", req); json *js; if (len < 0) { while (fgets(buf, sizeof(buf), stdin)) { if (!buf[0] || buf[0] == '\n') break; xstr_append(xs, buf); } } else { int r; while ((r = fread(buf, 1, MIN(len, sizeof(buf)), stdin))) { if (r < 0) { dbg(5, "fread() returned %d, len=%d\n", r, len); break; } /* always appends \0 */ xstr_append_size(xs, buf, r); len -= r; if (len <= 0) break; } } /* eof? */ if (xstr_length(xs) == 0) exit(0); js = json_create(req); req->params = json_parse(js, xstr_string(xs)); return common(req, false); }
bool readhttp(struct req *req) { enum http_type ht; char first[256], buf[BUFSIZ], *ct, *cl, *ac, *uri, *auth; int len; xstr *xs = xstr_create("", req); /* read query */ if (!fgets(first, sizeof(first), stdin) || first[0] == '\n') exit(0); /* eof */ if (strncmp(first, "POST ", 5) == 0) { ht = POST; uri = first + 5; } else if (strncmp(first, "OPTIONS ", 8) == 0) { ht = OPTIONS; uri = first + 8; } else if (strncmp(first, "GET ", 4) == 0 && O.http.htdocs) { /* @1 */ ht = GET; uri = first + 4; } else { dbg(4, "invalid method: %s\n", first); return errmsg("Invalid HTTP method"); } /* read headers */ while (fgets(buf, sizeof(buf), stdin)) { if (!buf[0] || buf[0] == '\n' || buf[0] == '\r') break; xstr_append(xs, buf); } req->http.headers = rfc822_parse(xstr_string(xs), req); /* fetch authentication information ASAP */ auth = thash_get(req->http.headers, "Authorization"); if (auth && strncmp(auth, "Basic ", 6) == 0) { xstr *ad = asn_b64_dec(auth+6, req); char *pass = strchr(xstr_string(ad), ':'); if (pass) { *pass++ = '\0'; req->http.user = xstr_string(ad); req->http.pass = pass; } } const char *cc = thash_get(req->http.headers, "Connection"); if (cc && (streq(cc, "close") || streq(cc, "Close"))) req->last = true; if (ht == OPTIONS) return errcode(JSON_RPC_HTTP_OPTIONS); /* handle static query, note that htdocs!=NULL checked @1 */ if (ht == GET) { req->http.needauth = true; char *space = strchr(uri, ' '); if (space) *space = '\0'; char *params = strchr(uri, '?'); if (params) *params = '\0'; if (streq(uri, "/")) { uri = "/index.html"; } else if (strstr(uri, "..")) { dbg(4, "invalid uri: '%s'\n", uri); return errcode(JSON_RPC_HTTP_NOT_FOUND); } req->http.uripath = mmatic_printf(req, "%s%s", O.http.htdocs, uri); if (asn_isfile(req->http.uripath) > 0) { dbg(4, "GET '%s'\n", req->http.uripath); return errcode(JSON_RPC_HTTP_GET); } dbg(4, "not found: '%s'\n", uri); req->http.uripath = NULL; return errcode(JSON_RPC_HTTP_NOT_FOUND); } /* = POST - ie. normal RPC call = */ ct = thash_get(req->http.headers, "Content-Type"); if (!ct) return errmsg("Content-Type needed"); if (strncmp(ct, "application/json", 16) != 0) return errmsg("Unsupported Content-Type"); ac = thash_get(req->http.headers, "Accept"); if (!ac) return errmsg("Accept needed"); if (!strstr(ac, "application/json") && !strstr(ac, "*/*")) return errmsg("Unsupported Accept"); /* read the query */ cl = thash_get(req->http.headers, "Content-Length"); if (!cl) return errmsg("Content-Length needed"); len = atoi(cl); if (len < 0) return errmsg("Unsupported Content-Length"); return readjson_len(req, len); }