remote-curl: reencode http error messages

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>

Jeff King committed May 22, 2014 at 05:30 UTC fc1b774c72990f0ff92370316412b19fd72baa77
3 files changed +19 -7
remote-curl.c
+10 -7
@@ -194,19 +194,19 @@ static void free_discovery(struct discovery *d)
194 }
195 }
196
197 -static int show_http_message(struct strbuf *type, struct strbuf *msg)
197 +static int show_http_message(struct strbuf *type, struct strbuf *charset,
198 + struct strbuf *msg)
199 {
200 const char *p, *eol;
201
202 /*
203 * We only show text/plain parts, as other types are likely
204 * to be ugly to look at on the user's terminal.
204 - *
205 - * TODO should handle "; charset=XXX", and re-encode into
206 - * logoutputencoding
205 */
206 if (strcmp(type->buf, "text/plain"))
207 return -1;
208 + if (charset->len)
209 + strbuf_reencode(msg, charset->buf, get_log_output_encoding());
210
211 strbuf_trim(msg);
212 if (!msg->len)
@@ -225,6 +225,7 @@ static struct discovery* discover_refs(const char *service, int for_push)
225 {
226 struct strbuf exp = STRBUF_INIT;
227 struct strbuf type = STRBUF_INIT;
228 + struct strbuf charset = STRBUF_INIT;
229 struct strbuf buffer = STRBUF_INIT;
230 struct strbuf refs_url = STRBUF_INIT;
231 struct strbuf effective_url = STRBUF_INIT;
@@ -249,6 +250,7 @@ static struct discovery* discover_refs(const char *service, int for_push)
250
251 memset(&options, 0, sizeof(options));
252 options.content_type = &type;
253 + options.charset = &charset;
254 options.effective_url = &effective_url;
255 options.base_url = &url;
256 options.no_cache = 1;
@@ -259,13 +261,13 @@ static struct discovery* discover_refs(const char *service, int for_push)
261 case HTTP_OK:
262 break;
263 case HTTP_MISSING_TARGET:
262 - show_http_message(&type, &buffer);
264 + show_http_message(&type, &charset, &buffer);
265 die("repository '%s' not found", url.buf);
266 case HTTP_NOAUTH:
265 - show_http_message(&type, &buffer);
267 + show_http_message(&type, &charset, &buffer);
268 die("Authentication failed for '%s'", url.buf);
269 default:
268 - show_http_message(&type, &buffer);
270 + show_http_message(&type, &charset, &buffer);
271 die("unable to access '%s': %s", url.buf, curl_errorstr);
272 }
273
@@ -310,6 +312,7 @@ static struct discovery* discover_refs(const char *service, int for_push)
312 strbuf_release(&refs_url);
313 strbuf_release(&exp);
314 strbuf_release(&type);
315 + strbuf_release(&charset);
316 strbuf_release(&effective_url);
317 strbuf_release(&buffer);
318 last_discovery = last;
t/lib-httpd/error.sh
+4
@@ -15,6 +15,10 @@ case "$PATH_INFO" in
15 printf "text/plain; charset=utf-8"
16 charset=utf-8
17 ;;
18 +*utf16*)
19 + printf "text/plain; charset=utf-16"
20 + charset=utf-16
21 + ;;
22 esac
23 printf "\n"
24
t/t5550-http-fetch-dumb.sh
+5
@@ -186,5 +186,10 @@ test_expect_success 'git client shows text/plain with a charset' '
186 grep "this is the error message" stderr
187 '
188
189 +test_expect_success 'http error messages are reencoded' '
190 + test_must_fail git clone "$HTTPD_URL/error/utf16" 2>stderr &&
191 + grep "this is the error message" stderr
192 +'
193 +
194 stop_httpd
195 test_done