/*
- * Copyright (c) 2002-2003, Index Data.
+ * Copyright (c) 2002-2004, Index Data.
* See the file LICENSE for details.
*
- * $Id: zgdu.c,v 1.5 2003-12-31 00:14:01 adam Exp $
+ * $Id: zgdu.c,v 1.9 2004-02-25 12:59:56 adam Exp $
*/
+#include <ctype.h>
#include <yaz/odr.h>
#include <yaz/yaz-version.h>
#include <yaz/yaz-iconv.h>
#include <yaz/zgdu.h>
+#ifdef WIN32
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
+#endif
+
static int decode_headers_content(ODR o, int off, Z_HTTP_Header **headers,
char **content_buf, int *content_len)
{
int i = off;
+ int chunked = 0;
*headers = 0;
while (i < o->size-1 && o->buf[i] == '\r')
memcpy ((*headers)->value, o->buf + po, i - po);
(*headers)->value[i - po] = '\0';
+ if (!strcasecmp((*headers)->name, "Transfer-Encoding")
+ &&
+ !strcasecmp((*headers)->value, "chunked"))
+ chunked = 1;
headers = &(*headers)->next;
}
*headers = 0;
}
i++;
- if (i > o->size)
+ if (chunked)
{
- o->error = OHTTP;
- return 0;
- }
- else if (i == o->size)
- {
- *content_buf = 0;
- *content_len = 0;
+ int off = 0;
+
+ /* we know buffer will be smaller than o->size - i*/
+ *content_buf = (char*) odr_malloc(o, o->size - i);
+
+ while (1)
+ {
+ /* chunk length .. */
+ int chunk_len = 0;
+ for (; i < o->size-2; i++)
+ if (isdigit(o->buf[i]))
+ chunk_len = chunk_len * 16 +
+ (o->buf[i] - '0');
+ else if (isupper(o->buf[i]))
+ chunk_len = chunk_len * 16 +
+ (o->buf[i] - ('A'-10));
+ else if (islower(o->buf[i]))
+ chunk_len = chunk_len * 16 +
+ (o->buf[i] - ('a'-10));
+ else
+ break;
+ /* chunk extension ... */
+ while (o->buf[i] != '\r' && o->buf[i+1] != '\n')
+ {
+ if (i >= o->size-2)
+ {
+ o->error = OHTTP;
+ return 0;
+ }
+ i++;
+ }
+ i += 2; /* skip CRLF */
+ if (chunk_len == 0)
+ break;
+ if (chunk_len < 0 || off + chunk_len > o->size)
+ {
+ o->error = OHTTP;
+ return 0;
+ }
+ /* copy chunk .. */
+ memcpy (*content_buf + off, o->buf + i, chunk_len);
+ i += chunk_len + 2; /* skip chunk+CRLF */
+ off += chunk_len;
+ }
+ if (!off)
+ *content_buf = 0;
+ *content_len = off;
}
- else
+ else
{
- *content_len = o->size - i;
- *content_buf = (char*) odr_malloc(o, *content_len + 1);
- memcpy(*content_buf, o->buf + i, *content_len);
- (*content_buf)[*content_len] = '\0';
+ if (i > o->size)
+ {
+ o->error = OHTTP;
+ return 0;
+ }
+ else if (i == o->size)
+ {
+ *content_buf = 0;
+ *content_len = 0;
+ }
+ else
+ {
+ *content_len = o->size - i;
+ *content_buf = (char*) odr_malloc(o, *content_len + 1);
+ memcpy(*content_buf, o->buf + i, *content_len);
+ (*content_buf)[*content_len] = '\0';
+ }
}
return 1;
}
hr = (*p)->u.HTTP_Response = (Z_HTTP_Response *)
odr_malloc(o, sizeof(*hr));
+ hr->content_buf = 0;
+ hr->content_len = 0;
+
po = i = 5;
while (i < o->size-2 && o->buf[i] != ' ' && o->buf[i] != '\r')
i++;