summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2014-05-22 09:30:05 (GMT)
committerJunio C Hamano <gitster@pobox.com>2014-05-27 16:59:19 (GMT)
commite31316263af98c4583be39b469f3152a23eba91d (patch)
tree2bab83853f1a2dbb953689da98fe6cd218b72fb8
parentbf197fd7eebcb3579dd659af35822ce88adc66c8 (diff)
downloadgit-e31316263af98c4583be39b469f3152a23eba91d.zip
git-e31316263af98c4583be39b469f3152a23eba91d.tar.gz
git-e31316263af98c4583be39b469f3152a23eba91d.tar.bz2
http: optionally extract charset parameter from content-type
Since the previous commit, we now give a sanitized, shortened version of the content-type header to any callers who ask for it. This patch adds back a way for them to cleanly access specific parameters to the type. We could easily extract all parameters and make them available via a string_list, but: 1. That complicates the interface and memory management. 2. In practice, no planned callers care about anything except the charset. This patch therefore goes with the simplest thing, and we can expand or change the interface later if it becomes necessary. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--http.c54
-rw-r--r--http.h7
2 files changed, 57 insertions, 4 deletions
diff --git a/http.c b/http.c
index 6bfd093..84463df 100644
--- a/http.c
+++ b/http.c
@@ -907,6 +907,32 @@ static CURLcode curlinfo_strbuf(CURL *curl, CURLINFO info, struct strbuf *buf)
}
/*
+ * Check for and extract a content-type parameter. "raw"
+ * should be positioned at the start of the potential
+ * parameter, with any whitespace already removed.
+ *
+ * "name" is the name of the parameter. The value is appended
+ * to "out".
+ */
+static int extract_param(const char *raw, const char *name,
+ struct strbuf *out)
+{
+ size_t len = strlen(name);
+
+ if (strncasecmp(raw, name, len))
+ return -1;
+ raw += len;
+
+ if (*raw != '=')
+ return -1;
+ raw++;
+
+ while (*raw && !isspace(*raw))
+ strbuf_addch(out, *raw++);
+ return 0;
+}
+
+/*
* Extract a normalized version of the content type, with any
* spaces suppressed, all letters lowercased, and no trailing ";"
* or parameters.
@@ -916,11 +942,15 @@ static CURLcode curlinfo_strbuf(CURL *curl, CURLINFO info, struct strbuf *buf)
* but "text/plain" is the only reasonable output, and this keeps
* our code simple.
*
+ * If the "charset" argument is not NULL, store the value of any
+ * charset parameter there.
+ *
* Example:
- * "TEXT/PLAIN; charset=utf-8" -> "text/plain"
+ * "TEXT/PLAIN; charset=utf-8" -> "text/plain", "utf-8"
* "text / plain" -> "text/plain"
*/
-static void extract_content_type(struct strbuf *raw, struct strbuf *type)
+static void extract_content_type(struct strbuf *raw, struct strbuf *type,
+ struct strbuf *charset)
{
const char *p;
@@ -929,10 +959,25 @@ static void extract_content_type(struct strbuf *raw, struct strbuf *type)
for (p = raw->buf; *p; p++) {
if (isspace(*p))
continue;
- if (*p == ';')
+ if (*p == ';') {
+ p++;
break;
+ }
strbuf_addch(type, tolower(*p));
}
+
+ if (!charset)
+ return;
+
+ strbuf_reset(charset);
+ while (*p) {
+ while (isspace(*p))
+ p++;
+ if (!extract_param(p, "charset", charset))
+ return;
+ while (*p && !isspace(*p))
+ p++;
+ }
}
/* http_request() targets */
@@ -989,7 +1034,8 @@ static int http_request(const char *url,
if (options && options->content_type) {
struct strbuf raw = STRBUF_INIT;
curlinfo_strbuf(slot->curl, CURLINFO_CONTENT_TYPE, &raw);
- extract_content_type(&raw, options->content_type);
+ extract_content_type(&raw, options->content_type,
+ options->charset);
strbuf_release(&raw);
}
diff --git a/http.h b/http.h
index e64084f..473179b 100644
--- a/http.h
+++ b/http.h
@@ -144,6 +144,13 @@ struct http_get_options {
struct strbuf *content_type;
/*
+ * If non-NULL, and content_type above is non-NULL, returns
+ * the charset parameter from the content-type. If none is
+ * present, returns an empty string.
+ */
+ struct strbuf *charset;
+
+ /*
* If non-NULL, returns the URL we ended up at, including any
* redirects we followed.
*/