From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Derek Upham Newsgroups: gmane.lisp.guile.devel Subject: [Patch] Handle all four etags types in HTTP client Date: Tue, 31 Mar 2020 16:50:48 +0200 (CEST) Message-ID: <87tv24o9x7.fsf@priss.frightenedpiglet.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="105237"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: mu4e 1.3.2; emacs 28.0.50 To: guile-devel@gnu.org Original-X-From: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Tue Mar 31 16:52:11 2020 Return-path: Envelope-to: guile-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jJIFP-000RFZ-FA for guile-devel@m.gmane-mx.org; Tue, 31 Mar 2020 16:52:11 +0200 Original-Received: from localhost ([::1]:39396 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jJIFO-0007w5-Bb for guile-devel@m.gmane-mx.org; Tue, 31 Mar 2020 10:52:10 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:55144) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jJIED-000636-9L for guile-devel@gnu.org; Tue, 31 Mar 2020 10:50:58 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jJIEB-0000BK-Pb for guile-devel@gnu.org; Tue, 31 Mar 2020 10:50:57 -0400 Original-Received: from mailout-l3b-97.contactoffice.com ([212.3.242.97]:58954) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1jJIEB-00009p-Dt for guile-devel@gnu.org; Tue, 31 Mar 2020 10:50:55 -0400 Original-Received: from smtpauth1.co-bxl (smtpauth1.co-bxl [10.2.0.15]) by mailout-l3b-97.contactoffice.com (Postfix) with ESMTP id 4FC0BC8 for ; Tue, 31 Mar 2020 16:50:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mailfence.com; s=20160819-nLV10XS2; t=1585666253; bh=D/JxOAvtRSvEqSiS7Ng15IRIuZWjxYNmUU2VZh+wyRA=; h=From:To:Subject:Date:From; b=dStaVuFjR0q9lnZ83FAd1E88veaiMKqGzLptvk+2zQGwu2v/ZnXXlGYy1qUBBVxO1 gZDopCw8l28ommHzF65ZJLTEGzpSTRrNuoFliTBWpTkXVjc4tAITS6hujjhHurnt7z LGXqwhNen3Q2AUPGzI5ThXRxmQAVbzteJABgUgqkGwfoFAcALKerVq3mSIx74yR1SF BzHAgVNlMtGTrm6WhbEwYKtWtoROWyi3SZdOl/yKSjzakVi2gzHWr2NRJIfKAUNhSy +beh2fnN1pulXHrHS/mZxafefuYBaI4VyGYKMyngqfNScKO8YUkzCFnDSDN9rE090z RSUw6/ZXC3uVQ== Original-Received: by smtp.mailfence.com with ESMTPSA for ; Tue, 31 Mar 2020 16:50:47 +0200 (CEST) Original-Received: from localhost ([::1] helo=priss.frightenedpiglet.com) by priss.frightenedpiglet.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1jJIE0-00FFsS-BR; Tue, 31 Mar 2020 07:50:44 -0700 X-ContactOffice-Account: com:175140567 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 212.3.242.97 X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Original-Sender: "guile-devel" Xref: news.gmane.io gmane.lisp.guile.devel:20477 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable The HTTP client code is aware of and handles strong and weak etags=20 as quoted strings (matching the spec), and strong etags as=20 unquoted strings (which don=E2=80=99t match the spec, but which some=20 servers send anyway). Some servers also violate the spec by=20 returning *weak* tags as unquoted strings. This patch updates the=20 parsing code to recognize and handle that case. --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0002-Properly-handle-unquoted-and-quoted-etags.patch Content-Description: 0002-Properly-handle-unquoted-and-quoted-etags.patch >From dfd68f4f2dc6c2b3b86191e550a50a19533522d3 Mon Sep 17 00:00:00 2001 From: Derek Upham Date: Sun, 19 Jan 2020 16:55:10 -0800 Subject: [PATCH 2/2] Properly handle unquoted and quoted etags. --- module/web/http.scm | 20 +++++++++++++------- test-suite/tests/web-http.test | 1 + 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/module/web/http.scm b/module/web/http.scm index c5e559bea..0d495ff69 100644 --- a/module/web/http.scm +++ b/module/web/http.scm @@ -875,8 +875,10 @@ as an ordered alist." ;; Following https://tools.ietf.org/html/rfc7232#section-2.3, an entity ;; tag should really be a qstring. However there are a number of -;; servers that emit etags as unquoted strings. Assume that if the -;; value doesn't start with a quote, it's an unquoted strong etag. +;; servers that emit strong and weak etags as unquoted strings. We have +;; to handle all four combinations of quoted/unquoted and strong/weak. +;; (Use the heuristic that an unquoted entity tag with an initial 'W/' +;; is a weak tag, with the tag following the slash.) (define* (parse-entity-tag val #:optional (start 0) (end (string-length val)) #:key sloppy-delimiters) (define (parse-proper-etag-at start strong?) @@ -888,16 +890,20 @@ as an ordered alist." (values (cons tag strong?) next)))) (else (values (cons (parse-qstring val start end) strong?) end)))) + (define (parse-unquoted-etag-at start strong?) + (let ((delim (or (and sloppy-delimiters + (string-index val sloppy-delimiters start end)) + end))) + (values (cons (substring val start delim) strong?) delim))) (cond - ((string-prefix? "W/" val 0 2 start end) + ((string-prefix? "W/\"" val 0 3 start end) (parse-proper-etag-at (+ start 2) #f)) + ((string-prefix? "W/" val 0 2 start end) + (parse-unquoted-etag-at (+ start 2) #f)) ((string-prefix? "\"" val 0 1 start end) (parse-proper-etag-at start #t)) (else - (let ((delim (or (and sloppy-delimiters - (string-index val sloppy-delimiters start end)) - end))) - (values (cons (substring val start delim) #t) delim))))) + (parse-unquoted-etag-at start #t)))) (define (entity-tag? val) (match val diff --git a/test-suite/tests/web-http.test b/test-suite/tests/web-http.test index 843936bb5..0cf3b6129 100644 --- a/test-suite/tests/web-http.test +++ b/test-suite/tests/web-http.test @@ -410,6 +410,7 @@ (pass-if-parse etag "\"foo\"" '("foo" . #t)) (pass-if-parse etag "W/\"foo\"" '("foo" . #f)) (pass-if-parse etag "foo" '("foo" . #t)) + (pass-if-parse etag "W/foo" '("foo" . #t)) (pass-if-parse location "http://other-place" (build-uri 'http #:host "other-place")) (pass-if-only-parse location "#foo" -- 2.25.1 --=-=-= Content-Type: text/plain; format=flowed Derek -- Derek Upham derek_upham@mailfence.com --=-=-=--