diff options
Diffstat (limited to 'nanohttp/nanohttp-socket.c')
-rw-r--r-- | nanohttp/nanohttp-socket.c | 543 |
1 files changed, 298 insertions, 245 deletions
diff --git a/nanohttp/nanohttp-socket.c b/nanohttp/nanohttp-socket.c index a555a7f..9b0e673 100644 --- a/nanohttp/nanohttp-socket.c +++ b/nanohttp/nanohttp-socket.c @@ -1,29 +1,37 @@ /****************************************************************** - * $Id: nanohttp-socket.c,v 1.8 2004/02/03 08:59:23 snowdrop Exp $ - * - * CSOAP Project: A http client/server library in C - * Copyright (C) 2003 Ferhat Ayaz - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Email: ayaz@jprogrammer.net - ******************************************************************/ +* $Id: nanohttp-socket.c,v 1.9 2004/08/26 17:07:47 rans Exp $ +* +* CSOAP Project: A http client/server library in C +* Copyright (C) 2003 Ferhat Ayaz +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, write to the +* Free Software Foundation, Inc., 59 Temple Place - Suite 330, +* Boston, MA 02111-1307, USA. +* +* Email: ayaz@jprogrammer.net +******************************************************************/ #include <nanohttp/nanohttp-socket.h> #include <nanohttp/nanohttp-common.h> +#ifdef WIN32 +#include "wsockcompat.h" +#include <winsock2.h> +#define close(s) closesocket(s) +typedef int ssize_t; +typedef int socklen_t; +#endif + #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -52,339 +60,384 @@ #include <errno.h> /*-------------------------------------------------- - FUNCTION: hsocket_module_init +FUNCTION: hsocket_module_init ----------------------------------------------------*/ int hsocket_module_init() { - /* nothing to init for unix sockets */ - return 0; + /* nothing to init for unix sockets */ + return 0; } /*-------------------------------------------------- - FUNCTION: hsocket_module_destroy +FUNCTION: hsocket_module_destroy ----------------------------------------------------*/ void hsocket_module_destroy() { - /* nothing to destroy for unix sockets */ + /* nothing to destroy for unix sockets */ } /*-------------------------------------------------- - FUNCTION: hsocket_init +FUNCTION: hsocket_init ----------------------------------------------------*/ int hsocket_init(hsocket_t *sock) { - /* nothing to init for unix sockets */ - /* just set the descriptor to -1 */ - *sock = -1; - return 0; + /* nothing to init for unix sockets */ + /* just set the descriptor to -1 */ + *sock = -1; +#ifdef WIN32 + // WSACleanup(); + struct WSAData info; + WSAStartup(MAKEWORD(2,2), &info); +#endif + return 0; } /*-------------------------------------------------- - FUNCTION: hsocket_free +FUNCTION: hsocket_free ----------------------------------------------------*/ void hsocket_free(hsocket_t sock) { - /* nothing to free for unix sockets */ + /* nothing to free for unix sockets */ } /*-------------------------------------------------- - FUNCTION: hsocket_open +FUNCTION: hsocket_open ----------------------------------------------------*/ int hsocket_open(hsocket_t *dsock, const char* hostname, int port) { - int sock; - struct sockaddr_in address; - struct hostent* host; +#ifdef WIN32 + SOCKET sock; +#else + int sock; +#endif + char *ip; + struct sockaddr_in address; + struct hostent* host; - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock <= 0) return HSOCKET_CAN_NOT_CREATE; + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock <= 0) return HSOCKET_CAN_NOT_CREATE; - /* Get host data */ - host = gethostbyname(hostname); - if (host == NULL) return HSOCKET_CAN_NOT_GET_HOSTNAME; + /* Get host data */ + host = gethostbyname(hostname); + if (host == NULL) return HSOCKET_CAN_NOT_GET_HOSTNAME; - /* set server addresss */ - address.sin_family = host->h_addrtype; - address.sin_port = htons(port); - memcpy((char*)&address.sin_addr.s_addr, - host->h_addr_list[0], host->h_length); + ip = inet_ntoa (*(struct in_addr *)*host->h_addr_list); + address.sin_addr.s_addr = inet_addr(ip); - /* connect to the server */ - if (connect(sock, (struct sockaddr*) &address, sizeof(address)) != 0) - return HSOCKET_CAN_NOT_CONNECT; + /* set server addresss */ + address.sin_family = host->h_addrtype; + address.sin_port = htons(port); + /* connect to the server */ + if (connect(sock, (struct sockaddr*) &address, sizeof(address)) != 0) + return HSOCKET_CAN_NOT_CONNECT; - *dsock = sock; - return HSOCKET_OK; + *dsock = sock; + return HSOCKET_OK; } /*-------------------------------------------------- - FUNCTION: hsocket_close +FUNCTION: hsocket_close ----------------------------------------------------*/ int hsocket_bind(hsocket_t *dsock, int port) { - int sock; - struct sockaddr_in addr; - - /* create socket */ - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock == -1) { - log_error2("Can not create socket: '%s'", strerror(errno)); - return HSOCKET_CAN_NOT_CREATE; - } - - /* bind socket */ - addr.sin_family = AF_INET; - addr.sin_port = htons(port); /* short, network byte order */ - addr.sin_addr.s_addr = INADDR_ANY; - memset(&(addr.sin_zero), '\0', 8); /* zero the rest of the struct */ - - if (bind(sock, (struct sockaddr *)&addr, - sizeof(struct sockaddr)) == -1) { - log_error2("Can not bind: '%s'", strerror(errno)); - return HSOCKET_CAN_NOT_BIND; - } - - *dsock = sock; - return HSOCKET_OK; +#ifdef WIN32 + SOCKET sock; +#else + int sock; +#endif + struct sockaddr_in addr; + + /* create socket */ + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) { + log_error2("Can not create socket: '%s'", strerror(errno)); + return HSOCKET_CAN_NOT_CREATE; + } + + /* bind socket */ + addr.sin_family = AF_INET; + addr.sin_port = htons(port); /* short, network byte order */ + addr.sin_addr.s_addr = INADDR_ANY; + memset(&(addr.sin_zero), '\0', 8); /* zero the rest of the struct */ + + if (bind(sock, (struct sockaddr *)&addr, + sizeof(struct sockaddr)) == -1) { + log_error2("Can not bind: '%s'", strerror(errno)); + return HSOCKET_CAN_NOT_BIND; + } + + *dsock = sock; +#ifdef WIN32 + // setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)true, sizeof(BOOL)); + // setsockopt(sock, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (char*)true, sizeof(BOOL)); +#endif + return HSOCKET_OK; } /*-------------------------------------------------- - FUNCTION: hsocket_listen +FUNCTION: hsocket_listen ----------------------------------------------------*/ int hsocket_listen(hsocket_t sock, int n) { - if (listen(sock, n) == -1) { - log_error2("Can not listen: '%s'", strerror(errno)); - return HSOCKET_CAN_NOT_LISTEN; - } - return HSOCKET_OK; + if (listen(sock, n) == -1) { + log_error2("Can not listen: '%s'", strerror(errno)); + return HSOCKET_CAN_NOT_LISTEN; + } + return HSOCKET_OK; } /*-------------------------------------------------- - FUNCTION: hsocket_listen +FUNCTION: hsocket_listen ----------------------------------------------------*/ int hsocket_accept(hsocket_t sock, hsocket_t *dest) { - socklen_t asize; - int sockfd; - struct sockaddr_in addr; - - asize = sizeof(struct sockaddr_in); - sockfd = accept(sock, (struct sockaddr *)&addr, &asize); - - if (sockfd == -1) { - //httpd_log("httpd_run(): '%s'\n", strerror(errno)); - return HSOCKET_CAN_NOT_ACCEPT; - } - - log_verbose3("accept new socket (%d) from '%s'", sockfd, - SAVE_STR(((char*)inet_ntoa(addr.sin_addr))) ); - - *dest = sockfd; - return HSOCKET_OK; + socklen_t asize; + SOCKET sockfd; + struct sockaddr_in addr; + + asize = sizeof(struct sockaddr_in); +#ifdef WIN32 + while(1) + { + sockfd = accept(sock, (struct sockaddr *)&addr, &asize); + if (sockfd == -1) { + if(WSAGetLastError()!=WSAEWOULDBLOCK) + { + return HSOCKET_CAN_NOT_ACCEPT; + } + } + else + { + break; + } + } +#else + sockfd = accept(sock, (struct sockaddr *)&addr, &asize); + if (sockfd == -1) { + //httpd_log("httpd_run(): '%s'\n", strerror(errno)); + return HSOCKET_CAN_NOT_ACCEPT; + } +#endif + log_verbose3("accept new socket (%d) from '%s'", sockfd, + SAVE_STR(((char*)inet_ntoa(addr.sin_addr))) ); + + *dest = sockfd; + return HSOCKET_OK; } /*-------------------------------------------------- - FUNCTION: hsocket_close +FUNCTION: hsocket_close ----------------------------------------------------*/ void hsocket_close(hsocket_t sock) { - close(sock); + close(sock); +#ifdef WIN32 + WSACleanup(); +#endif } /*-------------------------------------------------- - FUNCTION: hsocket_send +FUNCTION: hsocket_send ----------------------------------------------------*/ int hsocket_nsend(hsocket_t sock, const char* buffer, int n) { - int size; + int size; - size = send((int)sock, buffer, n, 0); - if (size == -1) - return HSOCKET_CAN_NOT_SEND; + size = send((int)sock, buffer, n, 0); + if (size == -1) + return HSOCKET_CAN_NOT_SEND; - return HSOCKET_OK; + return HSOCKET_OK; } /*-------------------------------------------------- - FUNCTION: hsocket_send +FUNCTION: hsocket_send ----------------------------------------------------*/ int hsocket_send(hsocket_t sock, const char* buffer) { - int size; - size = send((int)sock, buffer, strlen(buffer), 0); - if (size == -1) - return HSOCKET_CAN_NOT_SEND; + int size; + size = send((int)sock, buffer, strlen(buffer), 0); + if (size == -1) + return HSOCKET_CAN_NOT_SEND; - return HSOCKET_OK; + return HSOCKET_OK; } int hsocket_read(hsocket_t sock, char* buffer, int total, int force) { - int status; - int totalRead; - - totalRead = 0; - - do { - status = recv(sock, &buffer[totalRead], total - totalRead, 0); - if (!force) return status; - if (status > 0) { - totalRead += status; - } else { - return status; - } - if (totalRead >= total) - return 0; - } while (1); + int status; + int totalRead; + + totalRead = 0; + + do { + status = recv(sock, &buffer[totalRead], total - totalRead, 0); + if (!force) + { +#ifdef WIN32 + if(WSAGetLastError()!=WSAEWOULDBLOCK) + { + return status; + } +#else + return status; +#endif + } + if (status > 0) { + totalRead += status; + } else { +#ifdef WIN32 + if(WSAGetLastError()!=WSAEWOULDBLOCK) + { + return status; + } +#else + return status; +#endif + } + if (totalRead >= total) + return 0; + } while (1); } /*-------------------------------------------------- - FUNCTION: hsocket_recv +FUNCTION: hsocket_recv ----------------------------------------------------*/ int hsocket_recv(hsocket_t sock, char** buffer, int *totalSize) { - ssize_t size; - int chunk=1; - char tmp[HSOCKET_MAX_BUFSIZE+1]; - int fsize; - int bufSize; - - if (*totalSize > 0) { - bufSize = *totalSize; - } else { - bufSize = HSOCKET_MAX_BUFSIZE; - } - - *totalSize = 0; - - /* calculate first size for realloc */ - if (*buffer) { - fsize = strlen(*buffer); - } else { - fsize = 0; - } - - do { - - size = recv(sock, tmp, bufSize, 0); - bufSize = HSOCKET_MAX_BUFSIZE; - - if (size == -1) { - log_error1("Error reading from socket"); - return HSOCKET_CAN_NOT_RECEIVE; - } - - if (size == 0) { - break; - } - - *totalSize += size; - if (*buffer) { - log_verbose2("reallocation %d bytes",*totalSize+fsize+1); - *buffer = (char*)realloc((char*)*buffer, - (*totalSize)+fsize+HSOCKET_MAX_BUFSIZE); - strcat(*buffer, tmp); - } else { - *buffer = (char*)realloc(NULL, *totalSize+1); - strcpy(*buffer, tmp); - } - - (*buffer)[*totalSize+fsize] = '\0'; - chunk++; - } while (size > 0); - - return HSOCKET_OK; + ssize_t size; + int chunk=1; + char tmp[HSOCKET_MAX_BUFSIZE+1]; + int fsize; + int bufSize; + + if (*totalSize > 0) { + bufSize = *totalSize; + } else { + bufSize = HSOCKET_MAX_BUFSIZE; + } + + *totalSize = 0; + + /* calculate first size for realloc */ + if (*buffer) { + fsize = strlen(*buffer); + } else { + fsize = 0; + } + + do { + + size = recv(sock, tmp, bufSize, 0); + bufSize = HSOCKET_MAX_BUFSIZE; + + if (size == -1) { + log_error1("Error reading from socket"); + return HSOCKET_CAN_NOT_RECEIVE; + } + + if (size == 0) { + break; + } + + *totalSize += size; + if (*buffer) { + log_verbose2("reallocation %d bytes",*totalSize+fsize+1); + *buffer = (char*)realloc((char*)*buffer, + (*totalSize)+fsize+HSOCKET_MAX_BUFSIZE); + strcat(*buffer, tmp); + } else { + *buffer = (char*)realloc(NULL, *totalSize+1); + strcpy(*buffer, tmp); + } + + (*buffer)[*totalSize+fsize] = '\0'; + chunk++; + } while (size > 0); + + return HSOCKET_OK; } /*-------------------------------------------------- - FUNCTION: hsocket_recv +FUNCTION: hsocket_recv ----------------------------------------------------*/ int hsocket_recv_cb(hsocket_t sock, - hsocket_recv_callback cb, void *userdata) + hsocket_recv_callback cb, void *userdata) { - ssize_t size; - char tmp[HSOCKET_MAX_BUFSIZE+1]; - - do { - - size = recv(sock, tmp, HSOCKET_MAX_BUFSIZE, 0); - - if (size == -1) { - log_error1("Error reading from socket"); - return HSOCKET_CAN_NOT_RECEIVE; - } - - if (size == 0) { - break; - } - - tmp[size]='\0'; - if (!cb(sock, tmp, size, userdata)) { - break; - } - - } while (size > 0); - - return HSOCKET_OK; + ssize_t size; + char tmp[HSOCKET_MAX_BUFSIZE+1]; + + do { + + size = recv(sock, tmp, HSOCKET_MAX_BUFSIZE, 0); + + if (size == -1) { + log_error1("Error reading from socket"); + return HSOCKET_CAN_NOT_RECEIVE; + } + + if (size == 0) { + break; + } + + tmp[size]='\0'; + if (!cb(sock, tmp, size, userdata)) { + break; + } + + } while (size > 0); + + return HSOCKET_OK; } /*-------------------------------------------------- - FUNCTION: hbufsocket_read +FUNCTION: hbufsocket_read ----------------------------------------------------*/ int hbufsocket_read(hbufsocket_t *bufsock, char *buffer, int size) { - int status; - int tmpsize; - - if (bufsock->bufsize - bufsock->cur >= size) { - - log_verbose1("no need to read from socket"); - strncpy(buffer, &(bufsock->buffer[bufsock->cur]), size); - bufsock->cur += size; - return HSOCKET_OK; - - } else { - - tmpsize = bufsock->bufsize - bufsock->cur; - log_verbose2("tmpsize = %d", tmpsize); - - if (tmpsize > 0) - strncpy(buffer, &(bufsock->buffer[bufsock->cur]), tmpsize); - - size -= tmpsize; - - free(bufsock->buffer); - - 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; - } -} + int status; + int tmpsize; + if (bufsock->bufsize - bufsock->cur >= size) { + log_verbose1("no need to read from socket"); + strncpy(buffer, &(bufsock->buffer[bufsock->cur]), size); + bufsock->cur += size; + return HSOCKET_OK; + } else { + tmpsize = bufsock->bufsize - bufsock->cur; + log_verbose2("tmpsize = %d", tmpsize); + if (tmpsize > 0) + strncpy(buffer, &(bufsock->buffer[bufsock->cur]), tmpsize); + size -= tmpsize; + free(bufsock->buffer); + 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; + } +} |