summaryrefslogtreecommitdiff
path: root/src/cache.c
diff options
context:
space:
mode:
authorJorge Arellano Cid <jcid@dillo.org>2009-01-07 15:53:19 -0300
committerJorge Arellano Cid <jcid@dillo.org>2009-01-07 15:53:19 -0300
commit6a205d77ba2747dd8bb21ceba452d43f36721eba (patch)
treeb23294b1e839ee9461e1725fac5d84a9e4a6f84e /src/cache.c
parent0135f90bd480311f2d74f4e43e3cfbf3feaf4277 (diff)
Cleanup of cache.c WRT charset decoders.
This patch gets rid of a series of valgrind complains with this page: http://selenic.com/pipermail/mercurial/
Diffstat (limited to 'src/cache.c')
-rw-r--r--src/cache.c157
1 files changed, 69 insertions, 88 deletions
diff --git a/src/cache.c b/src/cache.c
index e9a3418e..9cdcdfb4 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -485,40 +485,33 @@ static Dstr *Cache_data(CacheEntry_t *entry)
* Change Content-Type for cache entry found by url.
* Return new content type.
*/
-const char *a_Cache_set_content_type(const DilloUrl *url, const char *ctype,
- bool_t force)
+const char *a_Cache_set_content_type(const DilloUrl *url, const char *ctype)
{
+ char *charset;
const char *curr;
CacheEntry_t *entry = Cache_entry_search_with_redirect(url);
- if (!entry)
- return NULL;
+ dReturn_val_if_fail (entry != NULL, NULL);
- curr = Cache_current_content_type(entry);
- if (entry->TypeMeta && (force == FALSE)) {
- /* it's already been set */
- return curr;
- }
-
- if (a_Misc_content_type_cmp(curr, ctype)) {
- char *charset;
+ MSG("a_Cache_set_content_type {%s} {%s}\n", ctype, URL_STR(url));
- dFree(entry->TypeMeta);
+ curr = Cache_current_content_type(entry);
+ if (entry->TypeMeta) {
+ /* Type is already been set. Do nothing.
+ * Multiple META elements? */
+ } else if (a_Misc_content_type_cmp(curr, ctype)) {
+ /* TypeMeta not set, and META gives one different from default */
curr = entry->TypeMeta = dStrdup(ctype);
-
if (entry->CharsetDecoder)
a_Decode_free(entry->CharsetDecoder);
a_Misc_parse_content_type(ctype, NULL, NULL, &charset);
entry->CharsetDecoder = a_Decode_charset_init(charset);
dFree(charset);
+ /* Invalidate UTF8Data */
dStr_free(entry->UTF8Data, 1);
- if (entry->CharsetDecoder && entry->DataRefcount > 0)
- entry->UTF8Data = a_Decode_process(entry->CharsetDecoder,
- entry->Data->str,
- entry->Data->len);
- else
- entry->UTF8Data = NULL;
+ entry->UTF8Data = NULL;
+
}
return curr;
@@ -634,7 +627,7 @@ static Dlist *Cache_parse_multiple_fields(const char *header,
static void Cache_parse_header(CacheEntry_t *entry)
{
char *header = entry->Header->str;
- char *Length, *Type, *location_str, *encoding, *charset;
+ char *Length, *Type, *location_str, *encoding;
#ifndef DISABLE_COOKIES
Dlist *Cookies;
#endif
@@ -643,6 +636,8 @@ static void Cache_parse_header(CacheEntry_t *entry)
void *data;
int i;
+ MSG("Cache_parse_header\n");
+
if (entry->Header->len > 12) {
if (header[9] == '1' && header[10] == '0' && header[11] == '0') {
/* 100: Continue. The "real" header has not come yet. */
@@ -753,20 +748,11 @@ static void Cache_parse_header(CacheEntry_t *entry)
MSG_HTTP("Server didn't send Content-Type in header.\n");
}
} else {
+ /* This HTTP Content-Type is not trusted. It's checked against real data
+ * in Cache_process_queue(); only then CA_GotContentType becomes true. */
entry->TypeHdr = Type;
- _MSG("Content-Type {%s} {%s}\n", Type, URL_STR(entry->Url));
- /* This Content-Type is not trusted. It's checked against real data
- * in Cache_process_queue(); only then CA_GotContentType becomes true.
- */
- a_Misc_parse_content_type(Type, NULL, NULL, &charset);
- if (charset) {
- entry->CharsetDecoder = a_Decode_charset_init(charset);
- if (entry->CharsetDecoder) {
- dStr_free(entry->UTF8Data, 1);
- entry->UTF8Data = dStr_new("");
- }
- dFree(charset);
- }
+ MSG("TypeHdr {%s} {%s}\n", Type, URL_STR(entry->Url));
+ MSG("TypeMeta {%s}\n", entry->TypeMeta);
}
}
@@ -816,15 +802,60 @@ static int Cache_get_header(CacheEntry_t *entry,
void a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size,
const DilloUrl *Url)
{
- int offset = 0;
- int len;
+ int offset, len;
const char *str;
+ Dstr *dstr1, *dstr2, *dstr3;
CacheEntry_t *entry = Cache_entry_search(Url);
/* Assert a valid entry (not aborted) */
dReturn_if_fail (entry != NULL);
- if (Op == IOClose) {
+ MSG("__a_Cache_process_dbuf__\n");
+
+ if (Op == IORead) {
+ /*
+ * Cache_get_header() will set CA_GotHeader if it has a full header, and
+ * Cache_parse_header() will unset it if the header ends being
+ * merely an informational response from the server (i.e., 100 Continue)
+ */
+ for (offset = 0; !(entry->Flags & CA_GotHeader) &&
+ (len = Cache_get_header(entry, buf + offset, buf_size - offset));
+ Cache_parse_header(entry) ) {
+ offset += len;
+ }
+
+ if (entry->Flags & CA_GotHeader) {
+ str = buf + offset;
+ len = buf_size - offset;
+ entry->TransferSize += len;
+ dstr1 = dstr2 = dstr3 = NULL;
+
+ /* Decode arrived data (<= 3 stages) */
+ if (entry->TransferDecoder) {
+ dstr1 = a_Decode_process(entry->TransferDecoder, str, len);
+ str = dstr1->str;
+ len = dstr1->len;
+ }
+ if (entry->ContentDecoder) {
+ dstr2 = a_Decode_process(entry->ContentDecoder, str, len);
+ str = dstr2->str;
+ len = dstr2->len;
+ }
+ dStr_append_l(entry->Data, str, len);
+ if (entry->CharsetDecoder && entry->UTF8Data) {
+ dstr3 = a_Decode_process(entry->CharsetDecoder, str, len);
+ dStr_append_l(entry->UTF8Data, dstr3->str, dstr3->len);
+ }
+ dStr_free(dstr1, 1);
+ dStr_free(dstr2, 1);
+ dStr_free(dstr3, 1);
+
+ if (entry->Data->len)
+ entry->Flags &= ~CA_IsEmpty;
+
+ Cache_process_queue(entry);
+ }
+ } else if (Op == IOClose) {
if ((entry->Flags & CA_GotLength) &&
(entry->ExpectedSize != entry->TransferSize)) {
MSG_HTTP("Content-Length does NOT match message body,\n"
@@ -847,61 +878,11 @@ void a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size,
if (entry->Flags & CA_GotHeader) {
Cache_unref_data(entry);
}
- return;
+
} else if (Op == IOAbort) {
/* unused */
MSG("a_Cache_process_dbuf Op = IOAbort; not implemented!\n");
- return;
}
-
- /*
- * Cache_get_header() will set CA_GotHeader if it has a full header, and
- * Cache_parse_header() will unset it if the header turns out to have been
- * merely an informational response from the server (i.e., 100 Continue)
- */
- while (!(entry->Flags & CA_GotHeader) &&
- (len = Cache_get_header(entry, buf + offset, buf_size - offset))) {
- offset += len;
- /* Let's scan, allocate, and set things according to header info */
- Cache_parse_header(entry);
- }
-
- if (!(entry->Flags & CA_GotHeader))
- return;
-
- str = buf + offset;
- len = buf_size - offset;
- entry->TransferSize += len;
-
- if (entry->TransferDecoder) {
- Dstr *dbuf = a_Decode_process(entry->TransferDecoder, str, len);
- str = dbuf->str;
- len = dbuf->len;
- dStr_free(dbuf, 0);
- }
- if (entry->ContentDecoder) {
- Dstr *dbuf = a_Decode_process(entry->ContentDecoder, str, len);
- if (entry->TransferDecoder)
- dFree((char *)str);
- str = dbuf->str;
- len = dbuf->len;
- dStr_free(dbuf, 0);
- }
- dStr_append_l(entry->Data, str, len);
-
- if (entry->UTF8Data) {
- Dstr *dbuf = a_Decode_process(entry->CharsetDecoder, str, len);
- dStr_append_l(entry->UTF8Data, dbuf->str, dbuf->len);
- dStr_free(dbuf, 1);
- }
-
- if (entry->TransferDecoder || entry->ContentDecoder)
- dFree((char *)str);
-
- if (entry->Data->len)
- entry->Flags &= ~CA_IsEmpty;
-
- Cache_process_queue(entry);
}
/*