remote-curl: reencode http error messages
authorJeff King <peff@peff.net>
Thu, 22 May 2014 09:30:29 +0000 (05:30 -0400)
committerJunio C Hamano <gitster@pobox.com>
Tue, 27 May 2014 16:59:22 +0000 (09:59 -0700)
We currently recognize an error message with a content-type
"text/plain; charset=utf-16" as text, but we ignore the
charset parameter entirely. Let's encode it to
log_output_encoding, which is presumably something the
user's terminal can handle.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
remote-curl.c
t/lib-httpd/error.sh
t/t5550-http-fetch-dumb.sh
index a5ab977306ab19ad0def98ea11a6c0826acf7bbc..4493b389ded6a814bd8c40481f3d06855c963bd7 100644 (file)
@@ -194,19 +194,19 @@ static void free_discovery(struct discovery *d)
        }
 }
 
-static int show_http_message(struct strbuf *type, struct strbuf *msg)
+static int show_http_message(struct strbuf *type, struct strbuf *charset,
+                            struct strbuf *msg)
 {
        const char *p, *eol;
 
        /*
         * We only show text/plain parts, as other types are likely
         * to be ugly to look at on the user's terminal.
-        *
-        * TODO should handle "; charset=XXX", and re-encode into
-        * logoutputencoding
         */
        if (strcmp(type->buf, "text/plain"))
                return -1;
+       if (charset->len)
+               strbuf_reencode(msg, charset->buf, get_log_output_encoding());
 
        strbuf_trim(msg);
        if (!msg->len)
@@ -225,6 +225,7 @@ static struct discovery* discover_refs(const char *service, int for_push)
 {
        struct strbuf exp = STRBUF_INIT;
        struct strbuf type = STRBUF_INIT;
+       struct strbuf charset = STRBUF_INIT;
        struct strbuf buffer = STRBUF_INIT;
        struct strbuf refs_url = STRBUF_INIT;
        struct strbuf effective_url = STRBUF_INIT;
@@ -249,6 +250,7 @@ static struct discovery* discover_refs(const char *service, int for_push)
 
        memset(&options, 0, sizeof(options));
        options.content_type = &type;
+       options.charset = &charset;
        options.effective_url = &effective_url;
        options.base_url = &url;
        options.no_cache = 1;
@@ -259,13 +261,13 @@ static struct discovery* discover_refs(const char *service, int for_push)
        case HTTP_OK:
                break;
        case HTTP_MISSING_TARGET:
-               show_http_message(&type, &buffer);
+               show_http_message(&type, &charset, &buffer);
                die("repository '%s' not found", url.buf);
        case HTTP_NOAUTH:
-               show_http_message(&type, &buffer);
+               show_http_message(&type, &charset, &buffer);
                die("Authentication failed for '%s'", url.buf);
        default:
-               show_http_message(&type, &buffer);
+               show_http_message(&type, &charset, &buffer);
                die("unable to access '%s': %s", url.buf, curl_errorstr);
        }
 
@@ -310,6 +312,7 @@ static struct discovery* discover_refs(const char *service, int for_push)
        strbuf_release(&refs_url);
        strbuf_release(&exp);
        strbuf_release(&type);
+       strbuf_release(&charset);
        strbuf_release(&effective_url);
        strbuf_release(&buffer);
        last_discovery = last;
index 23cec97cc315c935e308d0b8794c01a06a1630db..eafc9d2d90ff7646062edd9a376839e469334760 100755 (executable)
@@ -15,6 +15,10 @@ case "$PATH_INFO" in
        printf "text/plain; charset=utf-8"
        charset=utf-8
        ;;
+*utf16*)
+       printf "text/plain; charset=utf-16"
+       charset=utf-16
+       ;;
 esac
 printf "\n"
 
index b35b2610e3d9bca5ac23fc2a663444a919a888e0..01b8aae2ed12eab92ecbfb562cb616e0cfc47202 100755 (executable)
@@ -186,5 +186,10 @@ test_expect_success 'git client shows text/plain with a charset' '
        grep "this is the error message" stderr
 '
 
+test_expect_success 'http error messages are reencoded' '
+       test_must_fail git clone "$HTTPD_URL/error/utf16" 2>stderr &&
+       grep "this is the error message" stderr
+'
+
 stop_httpd
 test_done