* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "filebundle.h"
#include "tvheadend.h"
+#include "filebundle.h"
#include <unistd.h>
#include <stdlib.h>
* Compression/Decompression
* *************************************************************************/
-#if (ENABLE_ZLIB && ENABLE_BUNDLE)
-static uint8_t *_fb_inflate ( const uint8_t *data, size_t size, size_t orig )
+#if ENABLE_ZLIB
+uint8_t *gzip_inflate ( const uint8_t *data, size_t size, size_t orig )
{
int err;
z_stream zstr;
#endif
#if ENABLE_ZLIB
-static uint8_t *_fb_deflate ( const uint8_t *data, size_t orig, size_t *size )
+uint8_t *gzip_deflate ( const uint8_t *data, size_t orig, size_t *size )
{
int err;
z_stream zstr;
zstr.avail_out = orig;
zstr.next_out = bufout;
- /* Decompress */
+ /* Compress */
while (1) {
err = deflate(&zstr, Z_FINISH);
#if (ENABLE_ZLIB && ENABLE_BUNDLE)
ret->gzip = 0;
ret->size = fb->f.orig;
- ret->buf = _fb_inflate(fb->f.data, fb->f.size, fb->f.orig);
+ ret->buf = gzip_inflate(fb->f.data, fb->f.size, fb->f.orig);
if (!ret->buf) {
free(ret);
ret = NULL;
if (ret->type == FB_BUNDLE) {
const uint8_t *data;
data = ret->b.root->f.data;
- ret->buf = _fb_deflate(data, ret->size, &ret->size);
+ ret->buf = gzip_deflate(data, ret->size, &ret->size);
} else {
uint8_t *data = malloc(ret->size);
ssize_t c = fread(data, 1, ret->size, ret->d.cur);
if (c == ret->size)
- ret->buf = _fb_deflate(data, ret->size, &ret->size);
+ ret->buf = gzip_deflate(data, ret->size, &ret->size);
fclose(ret->d.cur);
ret->d.cur = NULL;
free(data);
/* Miscellaneous */
int fb_stat ( const char *path, struct filebundle_stat *st );
+#if ENABLE_ZLIB
+uint8_t *gzip_deflate ( const uint8_t *data, size_t orig, size_t *size );
+uint8_t *gzip_inflate ( const uint8_t *data, size_t size, size_t orig );
+#endif
/* Directory processing wrappers */
fb_dir *fb_opendir ( const char *path );
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
+#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include "tvheadend.h"
#include "tcp.h"
#include "http.h"
+#include "filebundle.h"
#include "access.h"
#include "notify.h"
#include "channels.h"
tcp_write_queue(hc->hc_fd, &hdrs);
}
+/*
+ *
+ */
+int
+http_encoding_valid(http_connection_t *hc, const char *encoding)
+{
+ const char *accept;
+ size_t l = strlen(encoding);
+ size_t i;
+
+ accept = http_arg_get(&hc->hc_args, "accept-encoding");
+ if (!accept)
+ return 0;
+ while (*accept) {
+ for (i = 0; i < l; i++)
+ if (tolower(accept[i]) != encoding[i])
+ break;
+ if (i < l)
+ continue;
+ accept += l;
+ while (*accept == ' ')
+ accept++;
+ if (*accept == ',' || *accept == '\0')
+ return 1;
+ }
+ return 0;
+}
/**
* Transmit a HTTP reply
http_send_reply(http_connection_t *hc, int rc, const char *content,
const char *encoding, const char *location, int maxage)
{
- http_send_header(hc, rc, content, hc->hc_reply.hq_size,
+ size_t size = hc->hc_reply.hq_size;
+ uint8_t *data = NULL;
+
+#if ENABLE_ZLIB
+ if (http_encoding_valid(hc, "gzip") && encoding == NULL && size > 256) {
+ uint8_t *data2 = (uint8_t *)htsbuf_to_string(&hc->hc_reply);
+ data = gzip_deflate(data2, size, &size);
+ free(data2);
+ encoding = "gzip";
+ }
+#endif
+
+ http_send_header(hc, rc, content, size,
encoding, location, maxage, 0, NULL, NULL);
- if(hc->hc_no_output)
- return;
+ if(!hc->hc_no_output) {
+ if (data == NULL)
+ tcp_write_queue(hc->hc_fd, &hc->hc_reply);
+ else
+ tvh_write(hc->hc_fd, data, size);
+ }
- tcp_write_queue(hc->hc_fd, &hc->hc_reply);
+ free(data);
}
void http_error(http_connection_t *hc, int error);
+int http_encoding_valid(http_connection_t *hc, const char *encoding);
+
void http_output_html(http_connection_t *hc);
void http_output_content(http_connection_t *hc, const char *content);