From 9b582c4a2767fdadbf5e8e9ea7ebeb269f623f22 Mon Sep 17 00:00:00 2001 From: snowdrop Date: Wed, 17 Dec 2003 12:55:02 +0000 Subject: added connection close recv. fixed chunked encoding --- nanohttp/nanohttp-client.c | 129 +++++++++++++++++++++++++++++++++++---------- nanohttp/nanohttp-common.h | 4 +- nanohttp/nanohttp-socket.c | 18 +++++-- 3 files changed, 118 insertions(+), 33 deletions(-) diff --git a/nanohttp/nanohttp-client.c b/nanohttp/nanohttp-client.c index e31a171..cd6b802 100644 --- a/nanohttp/nanohttp-client.c +++ b/nanohttp/nanohttp-client.c @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-client.c,v 1.3 2003/12/16 14:12:57 snowdrop Exp $ + * $Id: nanohttp-client.c,v 1.4 2003/12/17 12:55:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -390,7 +390,7 @@ int httpc_get_cb(httpc_conn_t *conn, const char *urlstr, char *rest; int restsize; httpc_cb_userdata_t cbdata; - int i; + int i, done; /* content-length */ char *content_length_str; @@ -410,6 +410,10 @@ int httpc_get_cb(httpc_conn_t *conn, const char *urlstr, int chunk_size_cur; char chunk_ch[2]; + /* connection closed */ + char *connection_status; + + if (conn == NULL) { log_error1("Connection object is NULL"); return 1; @@ -461,37 +465,61 @@ int httpc_get_cb(httpc_conn_t *conn, const char *urlstr, /* Receive Response incl. header */ rsize = restsize = 0; response = rest = NULL; + done = 0; - status = hsocket_read(conn->sock, buffer, HSOCKET_MAX_BUFSIZE*1, 0); - if (status <= 0) { - log_error2("Can not receive response (status:%d)", status); - return 6; - } - - for (i=0;isock, buffer, HSOCKET_MAX_BUFSIZE, 0); + + if (status <= 0) { + log_error2("Can not receive response (status:%d)", status); + return 6; + } + + + for (i=0;i '%c' (%d, %d)", buffer[i], buffer[i], + buffer[i+1], buffer[i+2]); + */ + if (buffer[i] == '\n') { + if (buffer[i+1] == '\n') { + + response = (char*)realloc(response, rsize+i+1); + strncpy(&response[rsize], buffer, i); + response[rsize+i] = '\0'; + rsize += i; + + restsize = status - i - 2; + rest = (char*)malloc(restsize+1); + strncpy(rest, &buffer[i+2], restsize); + rest[restsize] = '\0'; + done = 1; + break; + + } else if (buffer[i+1] == '\r' && buffer[i+2] == '\n') { + + response = (char*)realloc(response, rsize+i+1); + strncpy(&response[rsize], buffer, i); + response[rsize+i] = '\0'; + rsize += i; - restsize = status - rsize - 3; - rest = &buffer[i+3]; - rest[restsize] = '\0'; /* REST WILL BE FREED IN BUFFEREDSOCKET !!!! */ + + restsize = status - i - 3; + rest = (char*)malloc(restsize+1); + strncpy(rest, &buffer[i+3], restsize); + rest[restsize] = '\0'; + done = 1; + break; + } } } + + if (!done) + rsize += status; } + if (response == NULL) { log_error1("Header too long!"); return 13; @@ -571,6 +599,7 @@ int httpc_get_cb(httpc_conn_t *conn, const char *urlstr, bufsock.buffer = rest; bufsock.bufsize = restsize; + chunk_size = 1; while (chunk_size > 0) { /* read chunk size */ @@ -583,6 +612,9 @@ int httpc_get_cb(httpc_conn_t *conn, const char *urlstr, return 9; } + log_debug2("chunk_size_str[chunk_size_cur] = '%c'", + chunk_size_str[chunk_size_cur]); + if (chunk_size_str[chunk_size_cur] == '\n') { chunk_size_str[chunk_size_cur] = '\0'; break; @@ -601,7 +633,7 @@ int httpc_get_cb(httpc_conn_t *conn, const char *urlstr, if (chunk_size <= 0) break; - chunk_buffer = (char*)malloc(chunk_size); + chunk_buffer = (char*)malloc(chunk_size+1); if (hbufsocket_read(&bufsock, chunk_buffer, chunk_size)) { log_error1("Can not read from socket"); return 9; @@ -609,6 +641,12 @@ int httpc_get_cb(httpc_conn_t *conn, const char *urlstr, cb(counter++, conn, userdata, chunk_size, chunk_buffer); free(chunk_buffer); + /* skip new line */ + buffer[0] = 0; /* reset buffer[0] */ + while (buffer[0] != '\n') { + hbufsocket_read(&bufsock, &buffer[0], 1); + } + } /* while (chunk_size > 0) */ /* rest and response are no longer required */ @@ -617,8 +655,43 @@ int httpc_get_cb(httpc_conn_t *conn, const char *urlstr, } /* if transfer_encodig */ + /* ================================================= */ + /* Retreive with only "Connection: close" */ + /* ================================================= */ + connection_status = + hpairnode_get(res->header, HEADER_CONNECTION); + + if (connection_status != NULL && + !strcmp(connection_status, "close")) { + + /* Invoke callback for rest */ + if (restsize > 0) + cb(0, conn, userdata, restsize, rest); + + log_debug1("Server communicates with 'Connection: close' !"); + + while (1) { + + status = hsocket_read(conn->sock, buffer, HSOCKET_MAX_BUFSIZE, 0); + + if (status == 0) { /* connection closed */ + return 0; + } + + if (status < 0) { /* error */ + log_error2("Can nor read from socket (status: %d)", status); + return 11; + } + + /* Invoke callback */ + cb(counter++, conn, userdata, status, buffer); + } + + } + log_error1("Unknown server response retreive type!"); + return 1; } diff --git a/nanohttp/nanohttp-common.h b/nanohttp/nanohttp-common.h index 65e8167..9e32368 100644 --- a/nanohttp/nanohttp-common.h +++ b/nanohttp/nanohttp-common.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-common.h,v 1.2 2003/12/16 13:16:14 snowdrop Exp $ + * $Id: nanohttp-common.h,v 1.3 2003/12/17 12:55:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -28,6 +28,8 @@ #define HEADER_CONTENT_LENGTH "Content-Length" #define HEADER_CONTENT_TYPE "Content-Type" #define HEADER_TRANSFER_ENCODING "Transfer-Encoding" +#define HEADER_CONNECTION "Connection" + #define HEADER_HOST "Host" #define HEADER_DATE "Date" diff --git a/nanohttp/nanohttp-socket.c b/nanohttp/nanohttp-socket.c index 9974e76..9aaca65 100644 --- a/nanohttp/nanohttp-socket.c +++ b/nanohttp/nanohttp-socket.c @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-socket.c,v 1.3 2003/12/16 14:12:58 snowdrop Exp $ + * $Id: nanohttp-socket.c,v 1.4 2003/12/17 12:55:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -380,15 +380,25 @@ int hbufsocket_read(hbufsocket_t *bufsock, char *buffer, int size) size -= tmpsize; free(bufsock->buffer); - status = recv(bufsock->sock, bufsock->buffer, size, 0); - if (status > 0) { + /* + status = recv(bufsock->sock, bufsock->buffer, size, 0); + if (status > 0) { bufsock->bufsize = size; bufsock->cur = size; strncpy(&buffer[tmpsize], bufsock->buffer, size); + } else { + return status; + } + */ + status = hsocket_read(bufsock->sock, &buffer[tmpsize], size, 1); + if (status == size) { + bufsock->buffer = (char*)malloc(size+1); + strncpy(bufsock->buffer, &buffer[tmpsize], size); + bufsock->cur = size; } else { return status; } - + return HSOCKET_OK; } } -- cgit v1.1-32-gdbae