static int http_parse_arguments(struct http_request *r, NMEM nmem, const char *args) { const char *p2 = args; while (*p2) { struct http_argument *a; const char *equal = strchr(p2, '='); const char *eoa = strchr(p2, '&'); if (!equal) { yaz_log(YLOG_WARN, "Expected '=' in argument"); return -1; } if (!eoa) eoa = equal + strlen(equal); // last argument else if (equal > eoa) { yaz_log(YLOG_WARN, "Missing '&' in argument"); return -1; } a = nmem_malloc(nmem, sizeof(struct http_argument)); a->name = nmem_strdupn(nmem, p2, equal - p2); a->value = nmem_strdupn(nmem, equal+1, eoa - equal - 1); urldecode(a->name, a->name); urldecode(a->value, a->value); a->next = r->arguments; r->arguments = a; p2 = eoa; while (*p2 == '&') p2++; } return 0; }
void yaz_marc_add_subfield(yaz_marc_t mt, const char *code_data, size_t code_data_len) { if (mt->debug) { size_t i; char msg[80]; sprintf(msg, "subfield:"); for (i = 0; i < 16 && i < code_data_len; i++) sprintf(msg + strlen(msg), " %02X", code_data[i] & 0xff); if (i < code_data_len) sprintf(msg + strlen(msg), " .."); yaz_marc_add_comment(mt, msg); } if (mt->subfield_pp) { struct yaz_marc_subfield *n = (struct yaz_marc_subfield *) nmem_malloc(mt->nmem, sizeof(*n)); n->code_data = nmem_strdupn(mt->nmem, code_data, code_data_len); n->next = 0; /* mark subfield_pp to point to this one, so we append here next */ *mt->subfield_pp = n; mt->subfield_pp = &n->next; } }
void yaz_marc_add_leader(yaz_marc_t mt, const char *leader, size_t leader_len) { struct yaz_marc_node *n = yaz_marc_add_node(mt); n->which = YAZ_MARC_LEADER; n->u.leader = nmem_strdupn(mt->nmem, leader, leader_len); marc_exec_leader(mt->leader_spec, n->u.leader, leader_len); }
void yaz_marc_add_datafield_xml(yaz_marc_t mt, const xmlNode *ptr_tag, const char *indicator, size_t indicator_len) { struct yaz_marc_node *n = yaz_marc_add_node(mt); n->which = YAZ_MARC_DATAFIELD; n->u.datafield.tag = nmem_text_node_cdata(ptr_tag, mt->nmem); n->u.datafield.indicator = nmem_strdupn(mt->nmem, indicator, indicator_len); n->u.datafield.subfields = 0; /* make subfield_pp the current (last one) */ mt->subfield_pp = &n->u.datafield.subfields; }
static void extract_user_pass(NMEM nmem, const char *uri, char **uri_lean, char **http_user, char **http_pass) { const char *cp1 = strchr(uri, '/'); *uri_lean = 0; *http_user = 0; *http_pass = 0; if (cp1 && cp1 > uri) { cp1--; if (!strncmp(cp1, "://", 3)) { const char *cp3 = 0; const char *cp2 = cp1 + 3; while (*cp2 && *cp2 != '/' && *cp2 != '@') { if (*cp2 == ':') cp3 = cp2; cp2++; } if (*cp2 == '@' && cp3) { *uri_lean = nmem_malloc(nmem, strlen(uri) + 1); memcpy(*uri_lean, uri, cp1 + 3 - uri); strcpy(*uri_lean + (cp1 + 3 - uri), cp2 + 1); *http_user = nmem_strdupn(nmem, cp1 + 3, cp3 - (cp1 + 3)); *http_pass = nmem_strdupn(nmem, cp3 + 1, cp2 - (cp3 + 1)); } } } if (*uri_lean == 0) *uri_lean = nmem_strdup(nmem, uri); }
void yaz_marc_add_controlfield(yaz_marc_t mt, const char *tag, const char *data, size_t data_len) { struct yaz_marc_node *n = yaz_marc_add_node(mt); n->which = YAZ_MARC_CONTROLFIELD; n->u.controlfield.tag = nmem_strdup(mt->nmem, tag); n->u.controlfield.data = nmem_strdupn(mt->nmem, data, data_len); if (mt->debug) { size_t i; char msg[80]; sprintf(msg, "controlfield:"); for (i = 0; i < 16 && i < data_len; i++) sprintf(msg + strlen(msg), " %02X", data[i] & 0xff); if (i < data_len) sprintf(msg + strlen(msg), " .."); yaz_marc_add_comment(mt, msg); } }
struct http_request *http_parse_request(struct http_channel *c, struct http_buf **queue, int len) { struct http_request *r = nmem_malloc(c->nmem, sizeof(*r)); char *p, *p2; char *start = nmem_malloc(c->nmem, len+1); char *buf = start; if (http_buf_read(c->http_server, queue, buf, len) < len) { yaz_log(YLOG_WARN, "http_buf_read < len (%d)", len); return 0; } r->search = ""; r->channel = c; r->arguments = 0; r->headers = 0; r->content_buf = 0; r->content_len = 0; // Parse first line for (p = buf, p2 = r->method; *p && *p != ' ' && p - buf < 19; p++) *(p2++) = *p; if (*p != ' ') { yaz_log(YLOG_WARN, "Unexpected HTTP method in request"); return 0; } *p2 = '\0'; if (!(buf = strchr(buf, ' '))) { yaz_log(YLOG_WARN, "Missing Request-URI in HTTP request"); return 0; } buf++; if (!(p = strchr(buf, ' '))) { yaz_log(YLOG_WARN, "HTTP Request-URI not terminated (too long?)"); return 0; } *(p++) = '\0'; if ((p2 = strchr(buf, '?'))) // Do we have arguments? *(p2++) = '\0'; r->path = nmem_strdup(c->nmem, buf); if (p2) { r->search = nmem_strdup(c->nmem, p2); // Parse Arguments http_parse_arguments(r, c->nmem, p2); } buf = p; if (strncmp(buf, "HTTP/", 5)) strcpy(r->http_version, "1.0"); else { size_t skipped; buf += 5; // strlen("HTTP/") p = (char*) next_crlf(buf, &skipped); if (!p || skipped < 3 || skipped > 5) return 0; memcpy(r->http_version, buf, skipped); r->http_version[skipped] = '\0'; buf = p; } strcpy(c->version, r->http_version); r->headers = 0; while (*buf) { size_t skipped; p = (char *) next_crlf(buf, &skipped); if (!p) { return 0; } else if (skipped == 0) { buf = p; break; } else { char *cp; char *n_v = nmem_malloc(c->nmem, skipped+1); struct http_header *h = nmem_malloc(c->nmem, sizeof(*h)); memcpy(n_v, buf, skipped); n_v[skipped] = '\0'; if (!(cp = strchr(n_v, ':'))) return 0; h->name = nmem_strdupn(c->nmem, n_v, cp - n_v); cp++; while (isspace(*cp)) cp++; h->value = nmem_strdup(c->nmem, cp); h->next = r->headers; r->headers = h; buf = p; } } // determine if we do keep alive if (!strcmp(c->version, "1.0")) { const char *v = http_lookup_header(r->headers, "Connection"); if (v && !strcmp(v, "Keep-Alive")) c->keep_alive = 1; else c->keep_alive = 0; } else { const char *v = http_lookup_header(r->headers, "Connection"); if (v && !strcmp(v, "close")) c->keep_alive = 0; else c->keep_alive = 1; } if (buf < start + len) { const char *content_type = http_lookup_header(r->headers, "Content-Type"); r->content_len = start + len - buf; r->content_buf = buf; if (!yaz_strcmp_del("application/x-www-form-urlencoded", content_type, "; ")) { http_parse_arguments(r, c->nmem, r->content_buf); } } return r; }
char *odr_strdupn(ODR o, const char *str, size_t n) { return nmem_strdupn(o->mem, str, n); }