From patchwork Sun Sep 6 13:02:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian Kotelba X-Patchwork-Id: 514918 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (arrakis.dune.hu [78.24.191.176]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 604C51401AF for ; Sun, 6 Sep 2015 23:03:11 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=0bmlC8Lo; dkim-atps=neutral Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id C3F8028C04F; Sun, 6 Sep 2015 15:02:00 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00,FREEMAIL_FROM, T_DKIM_INVALID autolearn=unavailable version=3.3.2 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 964ED28C016 for ; Sun, 6 Sep 2015 15:01:56 +0200 (CEST) X-policyd-weight: using cached result; rate: -8.5 Received: from mail-yk0-f181.google.com (mail-yk0-f181.google.com [209.85.160.181]) by arrakis.dune.hu (Postfix) with ESMTPS for ; Sun, 6 Sep 2015 15:01:55 +0200 (CEST) Received: by ykei199 with SMTP id i199so59571983yke.0 for ; Sun, 06 Sep 2015 06:02:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=RGkE2a+07Cj2+K5feumVsf59IFYLfAyzcpQjYf99ljo=; b=0bmlC8LonXiL6+b8t6DEazU8u4ESdnVP7gUBWNs4jMQ1eTjBRaTC70ZXYJoPt/ck51 wSCvKyHRkim/oaf1J55dqhli2N0m69BqzOW/5pnPXKQ3ocX/S56YPW+7dDxuM3/jq6g5 B+x5KQb2S7Cw/9TrtLpo51ojTmPulRxmiOZNhDU5fn7FncLeFISPhv6KgAOK80dmQUmE umKUXeg9VFWO/u4+H3Fq6Q6FQ0kuJmX84CvyKhHs+BQMsxiO2MDEwcEmJ+6ohVOpuWlq 5Fy/qQTL+GJoiOAlcsWiqMxmukNIPy2QK0FYCTP72CWC+EH1Brk99J8O+WU1drhyWLw7 gCVQ== MIME-Version: 1.0 X-Received: by 10.170.114.18 with SMTP id g18mr14907069ykb.90.1441544576523; Sun, 06 Sep 2015 06:02:56 -0700 (PDT) Received: by 10.37.112.132 with HTTP; Sun, 6 Sep 2015 06:02:56 -0700 (PDT) In-Reply-To: References: Date: Sun, 6 Sep 2015 16:02:56 +0300 Message-ID: From: Adrian Kotelba To: openwrt-devel@lists.openwrt.org Subject: [OpenWrt-Devel] Fwd: [PATCH] uhttpd: serve precompressed files X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" Serving precompressed content with uhttpd. Signed-off-by: Adrian Kotelba >adrian.kotelba@gmail.com> diff --git a/file.c b/file.c index 480c40b..81f8186 100644 --- a/file.c +++ b/file.c @@ -136,6 +136,7 @@ uh_path_lookup(struct client *cl, const char *url) int docroot_len = strlen(docroot); char *pathptr = NULL; bool slash; + bool precompressed = 0; int i = 0; int len; @@ -191,11 +192,26 @@ uh_path_lookup(struct client *cl, const char *url) continue; /* test current path */ - if (stat(path_phys, &p.stat)) + if (stat(path_phys, &p.stat) == 0) { + snprintf(path_info, sizeof(path_info), "%s", uh_buf + i); + break; + } + + pathptr = path_phys + strlen(path_phys); + + /* try to locate precompressed file */ + len = path_phys + sizeof(path_phys) - pathptr - 1; + if (strlen(".gz") > len) continue; - snprintf(path_info, sizeof(path_info), "%s", uh_buf + i); - break; + strcpy(pathptr, ".gz"); + if (stat(path_phys, &p.stat) == 0) { + snprintf(path_info, sizeof(path_info), "%s", uh_buf + i); + precompressed = 1; + break; + } + + *pathptr = 0; } /* check whether found path is within docroot */ @@ -210,6 +226,7 @@ uh_path_lookup(struct client *cl, const char *url) p.phys = path_phys; p.name = &path_phys[docroot_len]; p.info = path_info[0] ? path_info : NULL; + p.compressed = precompressed; return &p; } @@ -258,9 +275,27 @@ uh_path_lookup(struct client *cl, const char *url) *pathptr = 0; } + /* try to locate precompressed index file */ + len = path_phys + sizeof(path_phys) - pathptr - 1; + list_for_each_entry(idx, &index_files, list) { + if (strlen(idx->name) + strlen(".gz") > len) + continue; + + strcpy(pathptr, idx->name); + strcpy(pathptr + strlen(idx->name), ".gz"); + if (!stat(path_phys, &s) && (s.st_mode & S_IFREG)) { + memcpy(&p.stat, &s, sizeof(p.stat)); + precompressed = 1; + break; + } + + *pathptr = 0; + } + p.root = docroot; p.phys = path_phys; p.name = &path_phys[docroot_len]; + p.compressed = precompressed; return p.phys ? &p : NULL; } @@ -561,6 +596,8 @@ static void uh_file_free(struct client *cl) static void uh_file_data(struct client *cl, struct path_info *pi, int fd) { + static char name[PATH_MAX]; + /* test preconditions */ if (!uh_file_if_modified_since(cl, &pi->stat) || !uh_file_if_match(cl, &pi->stat) || @@ -576,8 +613,15 @@ static void uh_file_data(struct client *cl, struct path_info *pi, int fd) /* write status */ uh_file_response_200(cl, &pi->stat); + strcpy(name, pi->name); + + if (pi->compressed) { + name[strlen(name) - strlen(".gz")] = 0; + ustream_printf(cl->us, "Content-Encoding: gzip\r\n"); + } + ustream_printf(cl->us, "Content-Type: %s\r\n", - uh_file_mime_lookup(pi->name)); + uh_file_mime_lookup(name)); ustream_printf(cl->us, "Content-Length: %" PRIu64 "\r\n\r\n", pi->stat.st_size); diff --git a/uhttpd.h b/uhttpd.h index fbcb1ed..7b580e4 100644 --- a/uhttpd.h +++ b/uhttpd.h @@ -140,6 +140,7 @@ struct path_info { const char *query; const char *auth; bool redirected; + bool compressed; struct stat stat; const struct interpreter *ip; };