summaryrefslogtreecommitdiff
path: root/lib/http_chunks.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2007-01-14 14:57:51 +0000
committerDaniel Stenberg <daniel@haxx.se>2007-01-14 14:57:51 +0000
commit0fb5a65a58130da7882f0a8d396e24b95c25064f (patch)
treed6c39e8a01c8815f724c47005d7a7409fe678ab7 /lib/http_chunks.c
parentc8afb02b4cf51038e84edec13fb52a6ad149d044 (diff)
downloadcurl-0fb5a65a58130da7882f0a8d396e24b95c25064f.tar.gz
- David McCreedy provided libcurl changes for doing HTTP communication on
non-ASCII platforms. It does add some complexity, most notably with more #ifdefs, but I want to see this supported added and I can't see how we can add it without the extra stuff added.
Diffstat (limited to 'lib/http_chunks.c')
-rw-r--r--lib/http_chunks.c48
1 files changed, 39 insertions, 9 deletions
diff --git a/lib/http_chunks.c b/lib/http_chunks.c
index f398b100c..d9774a2c3 100644
--- a/lib/http_chunks.c
+++ b/lib/http_chunks.c
@@ -36,6 +36,7 @@
#include "content_encoding.h"
#include "http.h"
#include "memory.h"
+#include "easyif.h" /* for Curl_convert_to_network prototype */
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -96,6 +97,9 @@ void Curl_httpchunk_init(struct connectdata *conn)
* client (for byte-counting and whatever).
*
* The states and the state-machine is further explained in the header file.
+ *
+ * This function always uses ASCII hex values to accommodate non-ASCII hosts.
+ * For example, 0x0d and 0x0a are used instead of '\r' and '\n'.
*/
CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
char *datap,
@@ -115,7 +119,11 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
while(length) {
switch(ch->state) {
case CHUNK_HEX:
- if(ISXDIGIT(*datap)) {
+ /* Check for an ASCII hex digit.
+ We avoid the use of isxdigit to accommodate non-ASCII hosts. */
+ if((*datap >= 0x30 && *datap <= 0x39) /* 0-9 */
+ || (*datap >= 0x41 && *datap <= 0x46) /* A-F */
+ || (*datap >= 0x61 && *datap <= 0x66)) { /* a-f */
if(ch->hexindex < MAXNUM_SIZE) {
ch->hexbuffer[ch->hexindex] = *datap;
datap++;
@@ -134,6 +142,17 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
}
/* length and datap are unmodified */
ch->hexbuffer[ch->hexindex]=0;
+#ifdef CURL_DOES_CONVERSIONS
+ /* convert to host encoding before calling strtoul */
+ result = Curl_convert_from_network(conn->data,
+ ch->hexbuffer,
+ ch->hexindex);
+ if(result != CURLE_OK) {
+ /* Curl_convert_from_network calls failf if unsuccessful */
+ /* Treat it as a bad hex character */
+ return(CHUNKE_ILLEGAL_HEX);
+ }
+#endif /* CURL_DOES_CONVERSIONS */
ch->datasize=strtoul(ch->hexbuffer, NULL, 16);
ch->state = CHUNK_POSTHEX;
}
@@ -143,7 +162,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
/* In this state, we're waiting for CRLF to arrive. We support
this to allow so called chunk-extensions to show up here
before the CRLF comes. */
- if(*datap == '\r')
+ if(*datap == 0x0d)
ch->state = CHUNK_CR;
length--;
datap++;
@@ -151,7 +170,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
case CHUNK_CR:
/* waiting for the LF */
- if(*datap == '\n') {
+ if(*datap == 0x0a) {
/* we're now expecting data to come, unless size was zero! */
if(0 == ch->datasize) {
if (conn->bits.trailerHdrPresent!=TRUE) {
@@ -235,7 +254,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
break;
case CHUNK_POSTCR:
- if(*datap == '\r') {
+ if(*datap == 0x0d) {
ch->state = CHUNK_POSTLF;
datap++;
length--;
@@ -245,7 +264,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
break;
case CHUNK_POSTLF:
- if(*datap == '\n') {
+ if(*datap == 0x0a) {
/*
* The last one before we go back to hex state and start all
* over.
@@ -277,7 +296,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
}
conn->trailer[conn->trlPos++]=*datap;
- if(*datap == '\r')
+ if(*datap == 0x0d)
ch->state = CHUNK_TRAILER_CR;
else {
datap++;
@@ -286,7 +305,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
break;
case CHUNK_TRAILER_CR:
- if(*datap == '\r') {
+ if(*datap == 0x0d) {
ch->state = CHUNK_TRAILER_POSTCR;
datap++;
length--;
@@ -296,14 +315,25 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
break;
case CHUNK_TRAILER_POSTCR:
- if (*datap == '\n') {
- conn->trailer[conn->trlPos++]='\n';
+ if (*datap == 0x0a) {
+ conn->trailer[conn->trlPos++]=0x0a;
conn->trailer[conn->trlPos]=0;
if (conn->trlPos==2) {
ch->state = CHUNK_STOP;
return CHUNKE_STOP;
}
else {
+#ifdef CURL_DOES_CONVERSIONS
+ /* Convert to host encoding before calling Curl_client_write */
+ result = Curl_convert_from_network(conn->data,
+ ch->hexbuffer,
+ ch->hexindex);
+ if(result != CURLE_OK) {
+ /* Curl_convert_from_network calls failf if unsuccessful */
+ /* Treat it as a bad chunk */
+ return(CHUNKE_BAD_CHUNK);
+ }
+#endif /* CURL_DOES_CONVERSIONS */
Curl_client_write(conn, CLIENTWRITE_HEADER,
conn->trailer, conn->trlPos);
}