1 /**
2  * Deflater
3  * 
4  * Copyright:
5  * (C) 2012-2015 Tatsuhiro Tsujikawa
6  * (C) 2014-2015 Etienne Cimon
7  *
8  * License: 
9  * Distributed under the terms of the MIT license with an additional section 1.2 of the curl/libcurl project. 
10  * Consult the provided LICENSE.md file for details
11  */
12 module libhttp2.deflater;
13 
14 import libhttp2.constants;
15 import libhttp2.types;
16 import libhttp2.buffers;
17 import libhttp2.huffman;
18 
19 struct Deflater
20 {
21     HDTable ctx;
22 
23     /// The upper limit of the header table size the deflater accepts.
24 	size_t deflate_hd_table_bufsize_max = DEFAULT_MAX_DEFLATE_BUFFER_SIZE;
25 
26     /// Minimum header table size notified in the next context update
27     size_t min_hd_table_bufsize_max;
28 
29     /// If nonzero, send header table size using encoding context update in the next deflate process
30     bool notify_table_size_change;
31 
32 	/*
33 	 * Initializes |deflater| for deflating header fields.
34 	 *
35 	 * The encoder only uses up to DEFAULT_MAX_DEFLATE_BUFFER_SIZE bytes
36 	 * for header table even if the larger value is specified later in changeTableSize().
37 	 */
38 	this(size_t _deflate_hd_table_bufsize_max)
39 	{
40 		ctx = Mem.alloc!HDTable();
41 		
42 		if (_deflate_hd_table_bufsize_max < HD_DEFAULT_MAX_BUFFER_SIZE) {
43 			notify_table_size_change = true;
44 			ctx.hd_table_bufsize_max = _deflate_hd_table_bufsize_max;
45 		} else {
46 			notify_table_size_change = false;
47 		}
48 		
49 		deflate_hd_table_bufsize_max = _deflate_hd_table_bufsize_max;
50 		min_hd_table_bufsize_max = uint.max;
51 	}
52 
53 	void free()
54 	{
55 		Mem.free(ctx);
56 	}
57 
58 	/*
59 	 * Deflates the |hfa|, which has |hfa.length| header fields, into
60 	 * the |bufs|.
61 	 *
62 	 * This function expands |bufs| as necessary to store the result. If
63 	 * buffers is full and the process still requires more space, this
64 	 * funtion fails and returns ErrorCode.HEADER_COMP.
65 	 *
66 	 * After this function returns, it is safe to delete the |hfa|.
67 	 *
68 	 * This function returns 0 if it succeeds, or one of the following
69 	 * negative error codes:
70 	 * 
71 	 * ErrorCode.HEADER_COMP
72 	 *     Deflation process has failed.
73 	 * ErrorCode.BUFFER_ERROR
74 	 *     Out of buffer space.
75 	 */
76 	ErrorCode deflate(Buffers bufs, in HeaderField[] hfa) {
77 		size_t i;
78 		ErrorCode rv;
79 		
80 		if (ctx.bad)
81 			return ErrorCode.HEADER_COMP;
82 		
83 		if (notify_table_size_change) {
84 			size_t _min_hd_table_bufsize_max  = min_hd_table_bufsize_max;
85 			
86 			notify_table_size_change = false;
87 			min_hd_table_bufsize_max = uint.max;
88 			
89 			if (ctx.hd_table_bufsize_max > _min_hd_table_bufsize_max) {
90 
91 				rv = emitTableSize(bufs, _min_hd_table_bufsize_max);
92 
93 				if (rv != 0) {
94 					goto fail;
95 				}
96 			}
97 
98 			rv = emitTableSize(bufs, ctx.hd_table_bufsize_max);
99 			
100 			if (rv != 0) {
101 				goto fail;
102 			}
103 		}
104 		
105 		for (i = 0; i < hfa.length; ++i) {
106 			rv = deflate(bufs, hfa[i]);
107 			if (rv != 0)
108 				goto fail;
109 		}
110 		
111 		LOGF("deflatehd: success");
112 		
113 		return ErrorCode.OK;
114 	fail:
115 		LOGF("deflatehd: error return %d", rv);
116 		
117 		ctx.bad = 1;
118 		return rv;
119 	}
120 
121 	/**
122 	 * Deflates the |hfa|, which has |hfa.length| header fields, into
123 	 * the |buf| of length |buf.length|.
124 	 *
125 	 * If |buf| is not large enough to store the deflated header block,
126 	 * this function fails with $(D ErrorCode.INSUFF_BUFSIZE).  The
127 	 * caller should use `Deflater.upperBound()` to know the upper
128 	 * bound of buffer size required to deflate given header fields.
129 	 *
130 	 * Once this function fails, subsequent call of this function always
131 	 * returns $(D ErrorCode.HEADER_COMP).
132 	 *
133 	 * After this function returns, it is safe to delete the |hfa|.
134 	 *
135 	 * This function returns 0 if it succeeds, or one of the following
136 	 * negative error codes:
137 	 *
138 	 * $(D ErrorCode.HEADER_COMP)
139 	 *     Deflation process has failed.
140 	 * $(D ErrorCode.INSUFF_BUFSIZE)
141 	 *     The provided |buflen| size is too small to hold the output.
142 	 */
143 	int deflate(ubyte[] buf, in HeaderField[] hfa)
144 	{
145 		Buffers bufs = Mem.alloc!Buffers(buf);
146 		ErrorCode rv;
147 
148 		rv = deflate(bufs, hfa);
149 		
150 		size_t buflen = bufs.length;
151 		
152 		bufs.free();
153 		Mem.free(bufs);
154 
155 		if (rv == ErrorCode.BUFFER_ERROR)
156 			return ErrorCode.INSUFF_BUFSIZE;
157 		return cast(int)buflen;
158 	}
159 
160 	/**
161 	 * Returns an upper bound on the compressed size after deflation of |hfa|
162 	 */
163 	size_t upperBound(in HeaderField[] hfa) {
164 		size_t n = 0;
165 		size_t i;
166 		
167 		/* Possible Maximum Header Table Size Change.  Encoding (1u << 31) -
168 		   1 using 4 bit prefix requires 6 bytes.  We may emit this at most
169 		   twice. 
170 		*/
171 		n += 12;
172 		
173 		/* Use Literal Header Field without indexing - New Name, since it is
174 		   most space consuming format.  Also we choose the less one between
175 		   non-huffman and huffman, so using literal byte count is
176 		   sufficient for upper bound.
177 
178 		   Encoding (1u << 31) - 1 using 7 bit prefix requires 6 bytes.  We
179 		   need 2 of this for |hflen| header fields.
180 		 */
181 		n += 6 * 2 * hfa.length;
182 		
183 		for (i = 0; i < hfa.length; ++i)
184 		{
185 			n += hfa[i].name.length + hfa[i].value.length;
186 		}
187 		
188 		return n;
189 	}
190 
191 	/**
192 	 * Changes header table size of the |Deflater| to
193 	 * |settings_hd_table_bufsize_max| bytes.  This may trigger eviction
194 	 * in the dynamic table.
195 	 *
196 	 * The |settings_hd_table_bufsize_max| should be the value received in
197 	 * SettingsID.HEADER_TABLE_SIZE.
198 	 *
199 	 * The deflater never uses more memory than ``hd_table_bufsize_max`` bytes 
200 	 * specified in the constructor.  Therefore, if |settings_hd_table_bufsize_max| > 
201 	 * ``hd_table_bufsize_max``, resulting maximum table size becomes ``hd_table_bufsize_max``.
202 	 */
203 	void changeTableSize(size_t settings_hd_table_bufsize_max) {
204 		import std.algorithm : min;
205 
206 		size_t next_bufsize = min(settings_hd_table_bufsize_max, deflate_hd_table_bufsize_max);
207 		
208 		ctx.hd_table_bufsize_max = next_bufsize;
209 		
210 		min_hd_table_bufsize_max = min(min_hd_table_bufsize_max, next_bufsize);
211 		
212 		notify_table_size_change = true;
213 		
214 		ctx.shrink();
215 
216 	}
217 	
218 
219 package:
220 	ErrorCode deflate(Buffers bufs, const ref HeaderField hf) {
221 		ErrorCode rv;
222 		int res;
223 		bool found;
224 		int idx;
225 		bool incidx;
226 		uint name_hash = hf.name.hash();
227 		uint value_hash = hf.value.hash();
228 		
229 		LOGF("deflatehd: deflating %s: %s", hf.name, hf.value);		
230 
231 		res = ctx.search(hf, name_hash, value_hash, found);
232 
233 		idx = res;
234 		
235 		if (found) {
236 			
237 			LOGF("deflatehd: name/value match index=%d", idx);
238 			
239 			rv = emitIndexedBlock(bufs, idx);
240 
241 			if (rv != 0)
242 				return rv;
243 			
244 			return ErrorCode.OK;
245 		}
246 		
247 		if (idx != -1)
248 			LOGF("deflatehd: name match index=%d", res);
249 
250 		
251 		if (shouldIndex(hf)) 
252 		{
253 			HDEntry new_ent;
254 			if (idx != -1 && idx < cast(int) static_table.length) {
255 				HeaderField hf_indname;
256 				hf_indname = hf;
257 				hf_indname.name = ctx.get(idx).hf.name;
258 				new_ent = ctx.add(hf_indname, name_hash, value_hash, HDFlags.VALUE_ALLOC);
259 			} else 
260 				new_ent = ctx.add(hf, name_hash, value_hash, HDFlags.NAME_ALLOC | HDFlags.VALUE_ALLOC);
261 
262 			if (!new_ent)
263 				return ErrorCode.HEADER_COMP;
264 			if (new_ent.refcnt == 0)
265 				Mem.free(new_ent);
266 
267 			incidx = true;
268 		}
269 
270 		if (idx == -1)
271 			rv = emitNewNameBlock(bufs, hf, incidx);
272 		else
273 			rv = emitIndexedNameBlock(bufs, idx, hf, incidx);
274 		
275 		if (rv != 0)
276 			return rv;
277 
278 		
279 		return ErrorCode.OK;
280 	}
281 
282 	bool shouldIndex(in HeaderField hf)
283 	{
284 		if ((hf.flag & HeaderFlag.NO_INDEX) || entryRoom(hf.name.length, hf.value.length) > ctx.hd_table_bufsize_max * 3 / 4) 
285 		{
286 			return false;
287 		}
288 
289 		return  !name_match(hf, ":path") && 	 	!name_match(hf, "content-length") &&
290 				!name_match(hf, "set-cookie") && 	!name_match(hf, "etag") &&
291 				!name_match(hf, "if-modified-since") &&
292 				!name_match(hf, "if-none-match") && !name_match(hf, "location") &&
293 				!name_match(hf, "age");
294 	}
295 	private bool name_match(in HeaderField hf, string name) {
296 		return hf.name == name;
297 	}
298 }
299 
300 package:
301 
302 ErrorCode emitIndexedNameBlock(Buffers bufs, size_t idx, const ref HeaderField hf, bool inc_indexing) {
303 	ErrorCode rv;
304 	ubyte* bufp;
305 	size_t blocklen;
306 	ubyte[16] sb;
307 	size_t prefixlen;
308 	bool no_index;
309 	
310 	no_index = (hf.flag & HeaderFlag.NO_INDEX) != 0;
311 	
312 	if (inc_indexing)
313 		prefixlen = 6;
314 	else
315 		prefixlen = 4;
316 
317 	LOGF("deflatehd: emit indname index=%d, valuelen=%d, indexing=%d, no_index=%d", idx, hf.value.length, inc_indexing, no_index);
318 	
319 	blocklen = countEncodedLength(idx + 1, prefixlen);
320 	
321 	if (sb.length < blocklen) {
322 		return ErrorCode.HEADER_COMP;
323 	}
324 	
325 	bufp = sb.ptr;
326 	
327 	*bufp = packFirstByte(inc_indexing, no_index);
328 	
329 	encodeLength(bufp, idx + 1, prefixlen);
330 	
331 	rv = bufs.add(cast(string)sb[0 .. blocklen]);
332 	if (rv != 0)
333 		return rv;
334 		
335 	rv = emitString(bufs, hf.value);
336 	if (rv != 0) 
337 		return rv;
338 	
339 	return ErrorCode.OK;
340 }
341 
342 ErrorCode emitNewNameBlock(Buffers bufs, in HeaderField hf, bool inc_indexing) {
343 	ErrorCode rv;
344 	bool no_index;
345 	
346 	no_index = (hf.flag & HeaderFlag.NO_INDEX) != 0;
347 	
348 	LOGF("deflatehd: emit newname namelen=%d, valuelen=%d, indexing=%d, no_index=%d", hf.name.length, hf.value.length, inc_indexing, no_index);
349 	
350 	rv = bufs.add(packFirstByte(inc_indexing, no_index));
351 	if (rv != 0) {
352 		return rv;
353 	}
354 	
355 	rv = emitString(bufs, hf.name);
356 	if (rv != 0) {
357 		return rv;
358 	}
359 	
360 	rv = emitString(bufs, hf.value);
361 	if (rv != 0) {
362 		return rv;
363 	}
364 	
365 	return ErrorCode.OK;
366 }
367 
368 ErrorCode emitIndexedBlock(Buffers bufs, size_t idx) {
369 	ErrorCode rv;
370 	size_t blocklen;
371 	ubyte[16] sb;
372 	ubyte *bufp;
373 	
374 	blocklen = countEncodedLength(idx + 1, 7);
375 	
376 	LOGF("deflatehd: emit indexed index=%d, %d bytes", idx,
377 			blocklen);
378 	
379 	if (sb.length < blocklen) {
380 		return ErrorCode.HEADER_COMP;
381 	}
382 	
383 	bufp = sb.ptr;
384 	*bufp = 0x80;
385 	encodeLength(bufp, idx + 1, 7);
386 	
387 	rv = bufs.add(cast(string)sb[0 .. blocklen]);
388 	if (rv != 0) {
389 		return rv;
390 	}
391 	
392 	return ErrorCode.OK;
393 }
394 
395 ErrorCode emitString(Buffers bufs, in string str) {
396 	ErrorCode rv;
397 	size_t len = str.length;
398 	ubyte[16] sb;
399 	ubyte *bufp;
400 	size_t blocklen;
401 	size_t enclen;
402 	bool huffman;
403 
404 	{ // count the required bytes for encoding str
405 		size_t i;
406 		size_t nbits = 0;
407 		
408 		for (i = 0; i < len; ++i) {
409 			nbits += symbol_table[cast(ubyte)str[i]].nbits;
410 		}
411 		/* pad the prefix of EOS (256) */
412 		enclen = (nbits + 7) / 8;
413 	}
414 	
415 	if (enclen < len)
416 		huffman = true;
417 	else
418 		enclen = len;
419 	
420 	blocklen = countEncodedLength(enclen, 7);
421 	
422 	LOGF("deflatehd: emit string str=%s, length=%d, huffman=%d, encoded_length=%d", str, len, huffman, enclen);
423 	
424 	if (sb.length < blocklen) {
425 		return ErrorCode.HEADER_COMP;
426 	}
427 	
428 	bufp = sb.ptr;
429 	*bufp = huffman ? 1 << 7 : 0;
430 	encodeLength(bufp, enclen, 7);
431 	
432 	rv = bufs.add(cast(string)sb[0 .. blocklen]);
433 	if (rv != 0)
434 		return rv;
435 		
436 	if (huffman) {
437 		rv = encodeHuffman(bufs, str);
438 	} else {
439 		assert(enclen == len);
440 		rv = bufs.add(str);
441 	}
442 	
443 	return rv;
444 }
445 
446 
447 ErrorCode emitTableSize(Buffers bufs, size_t table_size) {
448 	ErrorCode rv;
449 	ubyte *bufp;
450 	size_t blocklen;
451 	ubyte[16] sb;
452 	
453 	LOGF("deflatehd: emit table_size=%d", table_size);
454 	
455 	blocklen = countEncodedLength(table_size, 5);
456 	
457 	if (sb.length < blocklen) {
458 		return ErrorCode.HEADER_COMP;
459 	}
460 	
461 	bufp = sb.ptr;
462 	
463 	*bufp = 0x20;
464 	
465 	encodeLength(bufp, table_size, 5);
466 	
467 	rv = bufs.add(cast(string)sb[0 .. blocklen]);
468 	if (rv != 0)
469 		return rv;
470 	
471 	return ErrorCode.OK;
472 }
473 
474 ubyte packFirstByte(bool inc_indexing, bool no_index) {
475 	if (inc_indexing) 
476 		return 0x40;	
477 	if (no_index)
478 		return 0x10;	
479 	return 0x00;
480 }
481 
482 size_t encodeLength(ubyte* buf, size_t n, size_t prefix) {
483 	size_t k = (1 << prefix) - 1;
484 	ubyte *begin = buf;
485 
486 	*buf &= ~cast(int)(cast(ubyte) k);
487 	
488 	if (n < k) {
489 		*buf |= cast(ubyte) n;
490 		return 1;
491 	}
492 	
493 	*buf++ |= (cast(ubyte)k);
494 	n -= k;
495 
496 	for (; n >= 128; n >>= 7) {
497 		*buf++ = cast(ubyte)((1 << 7) | ((cast(ubyte)n) & 0x7f));
498 	}
499 	
500 	*buf++ = cast(ubyte) n;
501 	
502 	return cast(size_t)(buf - begin);
503 }
504 
505 
506 /*
507  * Encodes the given data |src| with length |srclen| to the |bufs|.
508  * This function expands extra buffers in |bufs| if necessary.
509  *
510  * This function returns 0 if it succeeds, or one of the following
511  * negative error codes:
512  *
513  * ErrorCode.BUFFER_ERROR
514  *     Out of buffer space.
515  */
516 ErrorCode encodeHuffman(Buffers bufs, in string src)
517 {
518 	ErrorCode rv;
519 	int rembits = 8;
520 	size_t i;
521 	size_t avail;
522 
523 	avail = bufs.curAvailable;
524 	
525 	for (i = 0; i < src.length; ++i) 
526 	{
527 		Symbol sym = symbol_table[src[i]];
528 		if (rembits == 8) {
529 			if (avail) {
530 				bufs.addHold(0);
531 			} else {
532 				rv = bufs.addHold(0);
533 				if (rv != 0) {
534 					return rv;
535 				}
536 				avail = bufs.curAvailable;
537 			}
538 		}
539 		rembits = sym.encode(bufs, avail, rembits);
540 		if (rembits < 0) {
541 			return cast(ErrorCode) rembits;
542 		}
543 	}
544 	/* 256 is special terminal symbol, pad with its prefix */
545 	if (rembits < 8) {
546 		/* if rembits < 8, we should have at least 1 buffer space available */
547 		const Symbol sym = symbol_table[256];
548 		assert(avail);
549 		/* Caution we no longer adjust avail here */
550 		bufs.fastOr(cast(ubyte)(sym.code >> (sym.nbits - rembits)));
551 	}
552 	
553 	return ErrorCode.OK;
554 }
555 
556 size_t countEncodedLength(size_t n, size_t prefix) {
557     size_t k = (1 << prefix) - 1;
558     size_t len = 0;
559     
560     if (n < k) {
561         return 1;
562     }
563     
564     n -= k;
565     ++len;
566     
567     for (; n >= 128; n >>= 7, ++len)
568         continue;
569     
570     return len + 1;
571 }