/**
 * Extract one request header. A header can span multiple lines, in
 * which case they will be folded into one before parsing is attempted.
 *
 * @param[in] connp
 * @param[in] data
 * @param[in] len
 * @return HTP_OK or HTP_ERROR
 */
htp_status_t htp_process_request_header_generic(htp_connp_t *connp, unsigned char *data, size_t len) {
    // Create a new header structure.
    htp_header_t *h = calloc(1, sizeof (htp_header_t));
    if (h == NULL) return HTP_ERROR;

    // Now try to parse the header.
    if (htp_parse_request_header_generic(connp, h, data, len) != HTP_OK) {
        free(h);
        return HTP_ERROR;
    }

    #ifdef HTP_DEBUG
    fprint_bstr(stderr, "Header name", h->name);
    fprint_bstr(stderr, "Header value", h->value);
    #endif

    // Do we already have a header with the same name?
    htp_header_t *h_existing = htp_table_get(connp->in_tx->request_headers, h->name);
    if (h_existing != NULL) {
        // TODO Do we want to have a list of the headers that are
        //      allowed to be combined in this way?

        // Add to the existing header.
        bstr *new_value = bstr_expand(h_existing->value, bstr_len(h_existing->value) + 2 + bstr_len(h->value));
        if (new_value == NULL) {
            bstr_free(h->name);
            bstr_free(h->value);
            free(h);
            return HTP_ERROR;
        }

        h_existing->value = new_value;
        bstr_add_mem_noex(h_existing->value, ", ", 2);
        bstr_add_noex(h_existing->value, h->value);

        // The new header structure is no longer needed.
        bstr_free(h->name);
        bstr_free(h->value);
        free(h);

        // Keep track of repeated same-name headers.
        h_existing->flags |= HTP_FIELD_REPEATED;
    } else {
        // Add as a new header.
        htp_table_add(connp->in_tx->request_headers, h->name, h);
    }

    return HTP_OK;
}
int generate_test_vectors()
{
	FILE                *fp;
	char                fileName[MAX_FILE_NAME];
	unsigned char       msg[MAX_MESSAGE_LENGTH];
	unsigned char		digest[CRYPTO_BYTES];
	int                 ret_val = KAT_SUCCESS;
	int					count = 1;
	unsigned long long	mlen;

	init_buffer(msg, sizeof(msg));

	sprintf(fileName, "LWC_HASH_KAT_%d.txt", (CRYPTO_BYTES * 8));

	if ((fp = fopen(fileName, "w")) == NULL) {
		fprintf(stderr, "Couldn't open <%s> for write\n", fileName);
		return KAT_FILE_OPEN_ERROR;
	}

	for (mlen = 0; mlen <= MAX_MESSAGE_LENGTH; mlen++) {

		fprintf(fp, "Count = %d\n", count++);

		fprint_bstr(fp, "Msg = ", msg, mlen);

		ret_val = crypto_hash(digest, msg, mlen);
		
		if(ret_val != 0) {
			fprintf(fp, "crypto_hash returned <%d>\n", ret_val);
			ret_val = KAT_CRYPTO_FAILURE;
			break;
		}

		fprint_bstr(fp, "MD = ", digest, CRYPTO_BYTES);

		fprintf(fp, "\n");
	}

	fclose(fp);

	return ret_val;
}
/**
 * Generic response header line(s) processor, which assembles folded lines
 * into a single buffer before invoking the parsing function.
 * 
 * @param[in] connp
 * @param[in] data
 * @param[in] len
 * @return HTP status
 */
htp_status_t htp_process_response_header_generic(htp_connp_t *connp, unsigned char *data, size_t len) {
    // Create a new header structure.
    htp_header_t *h = calloc(1, sizeof (htp_header_t));
    if (h == NULL) return HTP_ERROR;

    if (htp_parse_response_header_generic(connp, h, data, len) != HTP_OK) {
        free(h);
        return HTP_ERROR;
    }

    #ifdef HTP_DEBUG
    fprint_bstr(stderr, "Header name", h->name);
    fprint_bstr(stderr, "Header value", h->value);
    #endif

    // Do we already have a header with the same name?
    htp_header_t *h_existing = htp_table_get(connp->out_tx->response_headers, h->name);
    if (h_existing != NULL) {
        // Keep track of repeated same-name headers.
        h_existing->flags |= HTP_FIELD_REPEATED;
                
        // Having multiple C-L headers is against the RFC but many
        // browsers ignore the subsequent headers if the values are the same.
        if (bstr_cmp_c_nocase(h->name, "Content-Length") == 0) {
            // Don't use string comparison here because we want to
            // ignore small formatting differences.

            int64_t existing_cl, new_cl;

            existing_cl = htp_parse_content_length(h_existing->value);
            new_cl = htp_parse_content_length(h->value);
            if ((existing_cl == -1) || (new_cl == -1) || (existing_cl != new_cl)) {
                // Ambiguous response C-L value.
                htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Ambiguous response C-L value");

                bstr_free(h->name);
                bstr_free(h->value);
                free(h);
                
                return HTP_ERROR;
            }

            // Ignoring the new C-L header that has the same value as the previous ones.
        } else {            
            // Add to the existing header.

            bstr *new_value = bstr_expand(h_existing->value, bstr_len(h_existing->value) + 2 + bstr_len(h->value));
            if (new_value == NULL) {
                bstr_free(h->name);
                bstr_free(h->value);
                free(h);
                return HTP_ERROR;
            }

            h_existing->value = new_value;
            bstr_add_mem_noex(h_existing->value, (unsigned char *) ", ", 2);
            bstr_add_noex(h_existing->value, h->value);
        }

        // The new header structure is no longer needed.
        bstr_free(h->name);
        bstr_free(h->value);
        free(h);       
    } else {
        // Add as a new header.
        if (htp_table_add(connp->out_tx->response_headers, h->name, h) != HTP_OK) {
            bstr_free(h->name);
            bstr_free(h->value);
            free(h);
            return HTP_ERROR;
        }
    }
   
    return HTP_OK;
}