summaryrefslogtreecommitdiffstats
path: root/nanohttp/nanohttp-socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'nanohttp/nanohttp-socket.c')
-rw-r--r--nanohttp/nanohttp-socket.c543
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;
+ }
+}