static void on_header_value(ebb_request* request, const char *at, size_t length, int header_index) { ebb_request_info *reqinfo = (ebb_request_info *)(request->data); ebb_connection *conn = reqinfo->conn; ebb_connection_info *conninfo = (ebb_connection_info *)(conn->data); if (reqinfo->parsing_host_header) { if (length+1 > sizeof(reqinfo->host)) { reqinfo->host[0] = 0; } else { memcpy(reqinfo->host, at, length); reqinfo->host[length] = 0; } reqinfo->parsing_host_header = false; } if (reqinfo->parsing_auth_header) { if (length > 6) { if (0 == memcmp(at, "Basic ", 6)) { if (NULL != (reqinfo->auth = calloc(1, (length-6)+1))) { b64_decode(reqinfo->auth, at + 6, length-6); LOG_DEBUG("auth='%s'", reqinfo->auth); } } } reqinfo->parsing_auth_header = false; } if (reqinfo->parsing_ifmodifiedsince_header) { char str[512]; if (length < sizeof(str)) { memcpy(str, at, length); str[length] = 0; conninfo->ifmodifiedsince = tdate_parse(str); LOG_DEBUG("tdate_parse %s = %u", str, conninfo->ifmodifiedsince); } reqinfo->parsing_ifmodifiedsince_header = false; } }
/* Returns 1 if elems should continue being read, 0 otherwise */ static int procheadelem(struct connstruct *cn, char *buf) { char *delim, *value; if ((delim = strchr(buf, ' ')) == NULL) return 0; *delim = 0; value = delim + 1; if (strcmp(buf, "GET") == 0 || strcmp(buf, "HEAD") == 0 || strcmp(buf, "POST") == 0) { if (buf[0] == 'H') cn->reqtype = TYPE_HEAD; else if (buf[0] == 'P') cn->reqtype = TYPE_POST; if ((delim = strchr(value, ' ')) == NULL) /* expect HTTP type */ return 0; *delim++ = 0; urldecode(value); if (sanitizefile(value) == 0) { send_error(cn, 403); return 0; } #if defined(CONFIG_HTTP_HAS_CGI) decode_path_info(cn, value); #else my_strncpy(cn->filereq, value, MAXREQUESTLENGTH); #endif cn->if_modified_since = -1; if (strcmp(delim, "HTTP/1.0") == 0) /* v1.0 HTTP? */ cn->is_v1_0 = 1; } else if (strcasecmp(buf, "Host:") == 0) { if (sanitizehost(value) == 0) { removeconnection(cn); return 0; } my_strncpy(cn->server_name, value, MAXREQUESTLENGTH); } else if (strcasecmp(buf, "Connection:") == 0 && strcmp(value, "close") == 0) { cn->close_when_done = 1; } else if (strcasecmp(buf, "If-Modified-Since:") == 0) { cn->if_modified_since = tdate_parse(value); } else if (strcasecmp(buf, "Expect:") == 0) { /* supposed to be safe to ignore 100-continue */ if (strcasecmp(value, "100-continue") != 0) { send_error(cn, 417); /* expectation failed */ return 0; } } #ifdef CONFIG_HTTP_HAS_AUTHORIZATION else if (strcasecmp(buf, "Authorization:") == 0 && strncmp(value, "Basic ", 6) == 0) { int size = sizeof(cn->authorization); if (base64_decode(&value[6], strlen(&value[6]), (uint8_t *)cn->authorization, &size)) cn->authorization[0] = 0; /* error */ else cn->authorization[size] = 0; } #endif #if defined(CONFIG_HTTP_HAS_CGI) else if (strcasecmp(buf, "Content-Length:") == 0) { sscanf(value, "%d", &cn->content_length); } else if (strcasecmp(buf, "Content-Type:") == 0) { my_strncpy(cn->cgicontenttype, value, MAXREQUESTLENGTH); } else if (strcasecmp(buf, "Cookie:") == 0) { my_strncpy(cn->cookie, value, MAXREQUESTLENGTH); } #endif return 1; }