summaryrefslogtreecommitdiffstats
path: root/nanohttp/nanohttp-client.c
diff options
context:
space:
mode:
authorGravatar snowdrop2003-12-16 13:16:11 +0000
committerGravatar snowdrop2003-12-16 13:16:11 +0000
commit15c050ac3a39c9022268aa72770dc94956088615 (patch)
tree7c77d7bbebba8a84cab4f56827f5d9e64d908c4d /nanohttp/nanohttp-client.c
parent39ad0f75f24d87e0e76d58b0f2da0b07b9a21ca7 (diff)
downloadcsoap-15c050ac3a39c9022268aa72770dc94956088615.tar.gz
csoap-15c050ac3a39c9022268aa72770dc94956088615.tar.bz2
added chunked transfer encoding
Diffstat (limited to 'nanohttp/nanohttp-client.c')
-rw-r--r--nanohttp/nanohttp-client.c188
1 files changed, 170 insertions, 18 deletions
diff --git a/nanohttp/nanohttp-client.c b/nanohttp/nanohttp-client.c
index 72af32e..8f3f37b 100644
--- a/nanohttp/nanohttp-client.c
+++ b/nanohttp/nanohttp-client.c
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: nanohttp-client.c,v 1.1 2003/12/11 14:51:04 snowdrop Exp $
+ * $Id: nanohttp-client.c,v 1.2 2003/12/16 13:16:11 snowdrop Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -374,7 +374,6 @@ int httpc_recv_cb_callback(hsocket_t sock, char *buffer,
return 1;
}
-
/*--------------------------------------------------
FUNCTION: httpc_get_cb
----------------------------------------------------*/
@@ -392,6 +391,24 @@ int httpc_get_cb(httpc_conn_t *conn, const char *urlstr,
int restsize;
httpc_cb_userdata_t cbdata;
+ /* content-length */
+ char *content_length_str;
+ long content_length;
+ long remain_length;
+ int counter;
+ int recvSize;
+ char readBuf[HSOCKET_MAX_BUFSIZE];
+
+ /* chunked encoding */
+ char *transfer_encoding;
+ char *chunk_buffer;
+ int chunk_size, cs;
+ hbufsocket_t bufsock;
+ char tmpch;
+ char chunk_size_str[25];
+ int chunk_size_cur;
+ char chunk_ch[2];
+
if (conn == NULL) {
log_error1("Connection object is NULL");
return 1;
@@ -440,40 +457,175 @@ int httpc_get_cb(httpc_conn_t *conn, const char *urlstr,
return 5;
}
- /* Receive Response */
+ /* Receive Response incl. header */
status = hsocket_recv_limit(conn->sock, &response,
"\r\n\r\n", &rest, &rsize, &restsize);
if (status != HSOCKET_OK) {
log_error2("Can not receive response (status:%d)", status);
- return NULL;
+ return 6;
}
res = hresponse_new(response);
if (res == NULL) {
log_error2("Can't create response (url:'%s')", urlstr);
- return 6;
+ return 7;
}
/* Invoke callback */
start_cb(conn, userdata, res->header, res->spec, res->errcode, res->desc);
- /* Invoke callback for rest */
- cb(0, conn, userdata, restsize, rest);
-
- /* rest and response are no longer required */
- free(rest);
- free(response);
- /* Invoke with callback */
- cbdata.conn = conn;
- cbdata.userdata = userdata;
- cbdata.callback = cb;
- cbdata.counter = 1;
+ /* ================================================= */
+ /* Retreive with content-length */
+ /* ================================================= */
- hsocket_recv_cb(conn->sock, httpc_recv_cb_callback, &cbdata);
+ /* Check if server communicates with content-length */
+ content_length_str =
+ hpairnode_get(res->header, HEADER_CONTENT_LENGTH);
- return 0;
+ if (content_length_str != NULL) {
+
+ log_debug1("Server communicates with content-length!");
+
+ /* Invoke callback for rest */
+ if (restsize > 0)
+ cb(0, conn, userdata, restsize, rest);
+
+ /* content length */
+ content_length = atol(content_length_str);
+
+ counter = 1;
+ remain_length = content_length - restsize;
+ while (remain_length > 0) {
+ if (remain_length >= HSOCKET_MAX_BUFSIZE) {
+ recvSize = HSOCKET_MAX_BUFSIZE;
+ } else {
+ recvSize = remain_length;
+ }
+
+ if (hsocket_read(conn->sock, readBuf, recvSize)) {
+ log_error1("Can not read from socket!");
+ return 9;
+ } else {
+ cb(counter++, conn, userdata, recvSize, readBuf);
+ }
+
+ remain_length -= HSOCKET_MAX_BUFSIZE;
+
+ } /* while */
+
+ /* rest and response are no longer required */
+ free(rest);
+ free(response);
+
+ return 0;
+
+ } /* if content length */
+
+
+ /* ================================================= */
+ /* Retreive with chunked encoding */
+ /* ================================================= */
+
+ /* Check if server communicates with chunked encoding */
+ transfer_encoding =
+ hpairnode_get(res->header, HEADER_TRANSFER_ENCODING);
+ if (transfer_encoding != NULL &&
+ !strcmp(transfer_encoding, "chunked")) {
+
+ log_debug1("Server communicates with chunked encoding !");
+
+ /* read chunk size */
+ /*
+ strncpy(chunk_size_str, rest, 15);
+ chunk_size_cur = 0;
+ cs = 0;
+ while (1) {
+
+ chunk_size_str[chunk_size_cur] = rest[cs++];
+
+ if (chunk_size_str[chunk_size_cur] == '\n') {
+ chunk_size_str[chunk_size_cur] = '\0';
+ break;
+ }
+
+ if (chunk_size_str[chunk_size_cur] != '\r'
+ && chunk_size_str[chunk_size_cur] != ';') {
+ chunk_size_cur++;
+ }
+
+ if (chunk_size_cur > 15) {
+ log_error1("Can not parse chunk size!");
+ return 10;
+ }
+
+ }
+
+ chunk_size = strtol(chunk_size_str,(char**)NULL, 16);
+
+ log_debug3("chunk_size: '%s' as dec: '%d'",
+ chunk_size_str, chunk_size);
+ */
+
+ /* initialize buffered socket */
+ bufsock.sock = conn->sock;
+ bufsock.cur = 0;
+ bufsock.buffer = rest;
+ bufsock.bufsize = restsize;
+
+ while (chunk_size > 0) {
+
+ /* read chunk size */
+ chunk_size_cur = 0;
+ while (1) {
+
+
+ if (hbufsocket_read(&bufsock, &chunk_size_str[chunk_size_cur], 1)) {
+ log_error1("Can not read from socket");
+ return 9;
+ }
+
+ if (chunk_size_str[chunk_size_cur] == '\n') {
+ chunk_size_str[chunk_size_cur] = '\0';
+ break;
+ }
+
+ if (chunk_size_str[chunk_size_cur] != '\r'
+ && chunk_size_str[chunk_size_cur] != ';') {
+ chunk_size_cur++;
+ }
+
+ } /* while (1) */
+
+ chunk_size = strtol(chunk_size_str,(char**)NULL, 16); /* hex to dec */
+ log_debug3("chunk_size: '%s' as dec: '%d'",
+ chunk_size_str, chunk_size);
+
+ if (chunk_size <= 0) break;
+
+ chunk_buffer = (char*)malloc(chunk_size);
+ if (hbufsocket_read(&bufsock, chunk_buffer, chunk_size)) {
+ log_error1("Can not read from socket");
+ return 9;
+ }
+ cb(counter++, conn, userdata, chunk_size, chunk_buffer);
+ free(chunk_buffer);
+
+ } /* while (chunk_size > 0)
+
+ /* rest and response are no longer required */
+ free(rest);
+ free(response);
+
+ return 0;
+
+ } /* if transfer_encodig */
+
+
+ log_error1("Unknown server response retreive type!");
+
+ return 1;
}