/*
 * HPACK decompressor (RFC7541)
 *
 * Copyright (C) 2014-2017 Willy Tarreau <willy@haproxy.org>
 * Copyright (C) 2017 HAProxy Technologies
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <common/hpack-enc.h>
#include <common/http-hdr.h>
#include <common/ist.h>

#include <types/global.h>

/* returns the number of bytes required to encode the string length <len>. The
 * number of usable bits is an integral multiple of 7 plus 6 for the last byte.
 * The maximum number of bytes returned is 4 (2097279 max length). Larger values
 * return 0.
 */
static inline int len_to_bytes(size_t len)
{
	ssize_t slen = len;

	slen -= 127;
	if (__builtin_expect(slen < 0, 1))
		return 1;
	if (slen < (1 << 14)) {
		if (__builtin_expect(slen < (1 << 7), 1))
			return 2;
		else
			return 3;
	}
	if (slen < (1 << 21))
		return 4;
	return 0;
}

/* Encode <len> into <out>+<pos> and return the new position. The caller is
 * responsible for checking for available room using len_to_bytes() first.
 */
static inline int hpack_encode_len(char *out, int pos, int len)
{
	int code = len - 127;

	if (code < 0) {
		out[pos++] = len;
	} else {
		out[pos++] = 127;
		for (; code >= 128; code >>= 7)
			out[pos++] = code | 128;
		out[pos++] = code;
	}
	return pos;
}


/* Tries to encode header whose name is <n> and value <v> into the chunk <out>.
 * Returns non-zero on success, 0 on failure (buffer full).
 */
int hpack_encode_header(struct buffer *out, const struct ist n,
			const struct ist v)
{
	int len = out->data;
	int size = out->size;

	if (len >= size)
		return 0;

	/* check a few very common response header fields to encode them using
	 * the static header table. The tests are sorted by size to help the
	 * compiler factor out the common sizes.
	 */
	if (isteq(n, ist("date")))
		out->area[len++] = 0x61; // literal with indexing -- name="date" (idx 33)
	else if (isteq(n, ist("etag")))
		out->area[len++] = 0x62; // literal with indexing -- name="etag" (idx 34)
	else if (isteq(n, ist(":path")))
		out->area[len++] = 0x44; // literal with indexing -- name=":path" (idx 4)
	else if (isteq(n, ist("server")))
		out->area[len++] = 0x76; // literal with indexing -- name="server" (idx 54)
	else if (isteq(n, ist("location")))
		out->area[len++] = 0x6e; // literal with indexing -- name="location" (idx 46)
	else if (isteq(n, ist("content-type")))
		out->area[len++] = 0x5f; // literal with indexing -- name="content-type" (idx 31)
	else if (isteq(n, ist("last-modified")))
		out->area[len++] = 0x6c; // literal with indexing -- name="last-modified" (idx 44)
	else if (isteq(n, ist("accept-ranges")))
		out->area[len++] = 0x52; // literal with indexing -- name="accept-ranges" (idx 18)
	else if (isteq(n, ist("cache-control")))
		out->area[len++] = 0x58; // literal with indexing -- name="cache-control" (idx 24)
	else if (isteq(n, ist("content-length")))
		out->area[len++] = 0x5c; // literal with indexing -- name="content-length" (idx 28)
	else if (likely(n.len < 127 && len + 1 + n.len <= size)) {
		out->area[len++] = 0x00;      /* literal without indexing -- new name */
		out->area[len++] = n.len;     /* single-byte length encoding */
		ist2bin(out->area + len, n);
		len += n.len;
	}
	else if (len_to_bytes(n.len) && len + 1 + len_to_bytes(n.len) + n.len <= size) {
		out->area[len++] = 0x00;      /* literal without indexing -- new name */
		len = hpack_encode_len(out->area, len, n.len);
		ist2bin(out->area + len, n);
		len += n.len;
	}
	else {
		/* header field name too large for the buffer */
		return 0;
	}

	/* copy literal header field value */
	if (!len_to_bytes(v.len) || len + len_to_bytes(v.len) + v.len > size) {
		/* header value too large for the buffer */
		return 0;
	}

	len = hpack_encode_len(out->area, len, v.len);
	memcpy(out->area + len, v.ptr, v.len);
	len += v.len;

	out->data = len;
	return 1;
}
