static int ht_headers(struct channel *ch, struct buffer *bu, struct env *env) { struct headers_state hs; char name_str[80]; char value_str[2048]; struct buffer name = buffer_wrap(name_str); struct buffer value = buffer_wrap(value_str); buffer_reset(&name); buffer_reset(&value); env_init(env); hs_init(&hs); while (!ch_fill(ch)) { if (headers_parse(bu, &hs, &name, &value, env)) { ch_close(ch); return -1; } if (hs.done) break; } return 0; }
static Buffer* cookie_put_value(Buffer* cookie, const char* name, int nlen, const char* value, int vlen, int boolean, int encode) { Buffer dnam; Buffer dval; buffer_wrap(&dnam, name , nlen); buffer_wrap(&dval, value, vlen); /* output each part into the cookie */ do { if (cookie->pos > 0) { buffer_append(cookie, "; ", 2); } if (!encode) { buffer_append(cookie, dnam.data, dnam.size); } else { url_encode(&dnam, dnam.size, cookie); } if (!boolean) { buffer_append(cookie, "=", 1); if (!encode) { buffer_append(cookie, dval.data, dval.size); } else { url_encode(&dval, dval.size, cookie); } } } while (0); buffer_terminate(cookie); return cookie; }
static int ht_process(struct channel *ch) { char buf[4096]; struct buffer bu = buffer_wrap(buf); struct env env; char method[12]; char uri[512]; char version[10]; const char *host; if (ht_method(ch, &bu, sizeof(method), method, sizeof(uri), uri, sizeof(version), version)) return -1; if (strcasecmp(version, "HTTP/1.1")) /* require HTTP/1.1 */ return -1; if (ht_headers(ch, &bu, &env)) return -1; host = env_get(&env, "Host"); if (!host) { ht_response(ch, 400); ch_puts(ch, "Content-Type: text/plain\r\n"); ch_puts(ch, "Connection: close\r\n"); ch_puts(ch, "\r\n"); ch_puts(ch, "require Host in HTTP/1.1 headers.\n"); return 0; } printf("method=%s\n", method); printf("uri=%s\n", uri); printf("version=%s\n", version); printf("Host=%s\n", host); ht_response(ch, 200); /* send some basic headers */ ch_puts(ch, "Content-Type: text/plain\r\n"); ch_puts(ch, "Connection: close\r\n"); ch_puts(ch, "\r\n"); // TODO: output a real response ch_puts(ch, "Hello World!\n"); ch_printf(ch, "\n\turi=%s\n\thost=%s\n", uri, host); return 0; }
packet_t* packet_decode(buffer_t* buffer) { int error = buffer_ok; uint16_t length; uint8_t id; buffer->position = 0; error |= buffer_get_short(buffer, &length); error |= buffer_get_byte(buffer, &id); error |= buffer_available(buffer) == length; if (error || length > 5000 || length == 0) return NULL; uint8_t payload[length]; memcpy(payload, buffer->payload + buffer->position, length); packet_t* packet = safe_alloc(sizeof(packet_t)); packet->id = id; packet->buffer = buffer_wrap(payload, length); packet->buffer->position = 0; return packet; }
static int ht_process(struct channel *ch) { char buf[4096]; struct buffer bu = buffer_wrap(buf); struct env env; char method[12]; char uri[512]; char version[10]; const char *host; struct service *se; struct module *mo; struct domain *dom; const char *sub; if (ht_method(ch, &bu, sizeof(method), method, sizeof(uri), uri, sizeof(version), version)) return -1; if (strcasecmp(version, "HTTP/1.1")) /* require HTTP/1.1 */ return -1; if (ht_headers(ch, &bu, &env)) return -1; host = env_get(&env, "Host"); if (!host) { ht_response(ch, 400); ch_puts(ch, "Content-Type: text/plain\r\n"); ch_puts(ch, "Connection: close\r\n"); ch_puts(ch, "\r\n"); ch_puts(ch, "require Host in HTTP/1.1 headers.\n"); return 0; } dom = ha_find_dom(host); if (!dom) { ht_response(ch, 403); ch_puts(ch, "Content-Type: text/plain\r\n"); ch_puts(ch, "Connection: close\r\n"); ch_puts(ch, "\r\n"); ch_printf(ch, "Host \"%s\" is unavailable.\n\n", host); return 0; } Debug("method=\"%s\"\n", method); Debug("uri=\"%s\"\n", uri); Debug("version=\"%s\"\n", version); Debug("Host=\"%s\" (%s)\n", host, dom->name); se = se_find(dom, uri, &sub); if (!se) { ht_response(ch, 404); ch_puts(ch, "Content-Type: text/plain\r\n"); ch_puts(ch, "Connection: close\r\n"); ch_puts(ch, "\r\n"); ch_printf(ch, "Request-URI \"%s\" is unavailable.\n\n", uri); ch_printf(ch, "dom=\"%s\"\n", dom->name); ch_printf(ch, "host=\"%s\"\n", host); return 0; } mo = se->module; ht_response(ch, 200); /* send some basic headers */ ch_puts(ch, "Content-Type: text/plain\r\n"); ch_puts(ch, "Connection: close\r\n"); ch_puts(ch, "\r\n"); // TODO: output a real response ch_puts(ch, "Hello World!\n"); ch_printf(ch, "\n\turi=%s\n\thost=%s\n\tmodule=%s\n\tsubpath=%s\n", uri, dom->name, mo ? mo->name : "(none)", sub); return 0; }