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.c453
1 files changed, 160 insertions, 293 deletions
diff --git a/nanohttp/nanohttp-socket.c b/nanohttp/nanohttp-socket.c
index 77d4d9c..e1ee807 100644
--- a/nanohttp/nanohttp-socket.c
+++ b/nanohttp/nanohttp-socket.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: nanohttp-socket.c,v 1.53 2006/02/27 22:26:02 snowdrop Exp $
+* $Id: nanohttp-socket.c,v 1.54 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -87,12 +87,26 @@ typedef int ssize_t;
#include "nanohttp-common.h"
#include "nanohttp-ssl.h"
-#ifdef HAVE_SSL
-/*SSL_CTX *SSLctx = NULL;
-char *SSLCert = NULL;
-char *SSLPass = NULL;
-char *SSLCA = NULL;
-int SSLCertLess = 0;*/
+#ifdef WIN32
+static inline void
+_hsocket_module_sys_init(int argc, char **argv)
+{
+ struct WSAData info;
+ WSAStartup(MAKEWORD(2, 2), &info);
+
+ return;
+}
+
+static inline void
+_hsocket_module_sys_destroy(void)
+{
+ WSACleanup();
+
+ return;
+}
+#else
+static inline void _hsocket_module_sys_init(int argc, char **argv) { return; }
+static inline void _hsocket_module_sys_destroy(void) { return; }
#endif
/*--------------------------------------------------
@@ -101,29 +115,20 @@ NOTE: This will be called from httpd_init()
for server and from httpc_init() for client
----------------------------------------------------*/
herror_t
-hsocket_module_init()
+hsocket_module_init(int argc, char **argv)
{
-#ifdef WIN32
- struct WSAData info;
- WSAStartup(MAKEWORD(2, 2), &info);
-#endif
+ _hsocket_module_sys_init(argc, argv);
-#ifdef HAVE_SSL
- start_ssl();
-#endif
-
- return H_OK;
+ return hssl_module_init(argc, argv);
}
/*--------------------------------------------------
FUNCTION: hsocket_module_destroy
----------------------------------------------------*/
void
-hsocket_module_destroy()
+hsocket_module_destroy(void)
{
-#ifdef WIN32
- WSACleanup();
-#endif
+ _hsocket_module_sys_destroy();
return;
}
@@ -132,9 +137,8 @@ hsocket_module_destroy()
FUNCTION: hsocket_init
----------------------------------------------------*/
herror_t
-hsocket_init(hsocket_t * sock)
+hsocket_init(hsocket_t *sock)
{
- log_verbose1("Starting hsocket init");
memset(sock, 0, sizeof(hsocket_t));
sock->sock = HSOCKET_FREE;
@@ -143,38 +147,13 @@ hsocket_init(hsocket_t * sock)
}
/*--------------------------------------------------
-FUNCTION: hsocket_init_ssl
-----------------------------------------------------*/
-#ifdef HAVE_SSL
-herror_t
-hsocket_init_ssl(hsocket_t * sock,
- const char* sslCert,
- const char* sslPass,
- const char* sslCA)
-{
- hsocket_init(sock);
-
- log_verbose1("calling initialize_ctx()");
- sock->sslCtx = initialize_ctx(sslCert, sslPass, sslCA);
- if (sock->sslCtx == NULL)
- {
- return herror_new("hsocket_init_ctx", HSOCKET_ERROR_SSLCTX,
- "Unable to initialize SSL CTX");
- }
-
- return H_OK;
-}
-
-#endif
-
-
-/*--------------------------------------------------
FUNCTION: hsocket_free
----------------------------------------------------*/
void
-hsocket_free(hsocket_t sock)
+hsocket_free(hsocket_t *sock)
{
- /* nothing to free for unix sockets */
+ /* nop */
+
return;
}
@@ -182,21 +161,20 @@ hsocket_free(hsocket_t sock)
FUNCTION: hsocket_open
----------------------------------------------------*/
herror_t
-hsocket_open(hsocket_t * dsock, const char *hostname, int port)
+hsocket_open(hsocket_t * dsock, const char *hostname, int port, int ssl)
{
- hsocket_t sock;
- char *ip;
struct sockaddr_in address;
struct hostent *host;
+ char *ip;
- if ((sock.sock = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
+ if ((dsock->sock = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
return herror_new("hsocket_open", HSOCKET_ERROR_CREATE,
- "Socket error: %d", errno);
+ "Socket error (%s)", strerror(errno));
/* Get host data */
if (!(host = gethostbyname(hostname)))
return herror_new("hsocket_open", HSOCKET_ERROR_GET_HOSTNAME,
- "Socket error: %d", errno);
+ "Socket error (%s)", strerror(errno));
ip = inet_ntoa(*(struct in_addr *) *host->h_addr_list);
address.sin_addr.s_addr = inet_addr(ip);
@@ -205,31 +183,23 @@ hsocket_open(hsocket_t * dsock, const char *hostname, int port)
address.sin_family = host->h_addrtype;
address.sin_port = htons((unsigned short) port);
+ log_debug4("Opening %s://%s:%i", ssl ? "https" : "http", hostname, port);
+
/* connect to the server */
- if (connect(sock.sock, (struct sockaddr *) &address, sizeof(address)) != 0)
+ if (connect(dsock->sock, (struct sockaddr *) &address, sizeof(address)) != 0)
return herror_new("hsocket_open", HSOCKET_ERROR_CONNECT,
- "Socket error: %d", errno);
+ "Socket error (%s)", strerror(errno));
-#ifdef HAVE_SSL
- if (!dsock->sslCtx)
- {
-#endif
- log_verbose1("Using HTTP");
- dsock->sock = sock.sock;
-#ifdef HAVE_SSL
- }
- else
+ if (ssl)
{
herror_t status;
- log_verbose1("Using HTTPS");
- dsock->ssl = init_ssl(dsock->sslCtx, sock.sock, SSL_CLIENT);
- if ((status = hsocket_block(*dsock, dsock->block)) != H_OK)
+
+ if ((status = hssl_client_ssl(dsock)) != H_OK)
{
- log_error1("Cannot make socket non-blocking");
+ log_error2("hssl_client_ssl failed (%s)", herror_message(status));
return status;
}
}
-#endif
return H_OK;
}
@@ -247,9 +217,9 @@ hsocket_bind(hsocket_t * dsock, int port)
/* create socket */
if ((sock.sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
- log_error3("Can not create socket: '%s'", "Socket error: %d", errno);
+ log_error2("Cannot create socket (%s)", strerror(errno));
return herror_new("hsocket_bind", HSOCKET_ERROR_CREATE,
- "Socket error: %d", errno);
+ "Socket error (%s)", strerror(errno));
}
setsockopt(sock.sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
@@ -262,59 +232,83 @@ hsocket_bind(hsocket_t * dsock, int port)
if (bind(sock.sock, (struct sockaddr *) &addr, sizeof(struct sockaddr)) ==
-1)
{
- log_error3("Can not bind: '%s'", "Socket error: %d", errno);
- return herror_new("hsocket_bind", HSOCKET_ERROR_BIND, "Socket error: %d",
- errno);
+ log_error2("Cannot bind socket (%s)", strerror(errno));
+ return herror_new("hsocket_bind", HSOCKET_ERROR_BIND, "Socket error (%s)",
+ strerror(errno));
}
dsock->sock = sock.sock;
return H_OK;
}
-/*----------------------------------------------------------
-FUNCTION: hsocket_accept
-----------------------------------------------------------*/
-herror_t
-hsocket_accept(hsocket_t sock, hsocket_t * dest)
+#ifdef WIN32
+static herror_t
+_hsocket_sys_accept(hsocket_t *sock, hsocket_t *dest)
{
socklen_t asize;
hsocket_t sockfd;
- struct sockaddr_in addr;
-
- if (sock.sock <= 0)
- return herror_new("hsocket_accept", HSOCKET_ERROR_NOT_INITIALIZED,
- "Called hsocket_listen() before initializing!");
asize = sizeof(struct sockaddr_in);
-#ifdef WIN32
while (1)
{
- sockfd.sock = accept(sock.sock, (struct sockaddr *) &addr, &asize);
+ sockfd.sock = accept(sock->sock, (struct sockaddr *) &(dest->addr), &asize);
if (sockfd.sock == INVALID_SOCKET)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
return herror_new("hsocket_accept", HSOCKET_ERROR_ACCEPT,
- "Socket error: %d", errno);
+ "Socket error (%s)", strerror(errno));
}
else
{
break;
}
}
+
+ dest->sock = sockfd.sock;
+
+ return H_OK;
+}
#else
-/* TODO (#1#): why not a loop like in win32? */
- sockfd.sock = accept(sock.sock, (struct sockaddr *) &addr, &asize);
- if (sockfd.sock == -1)
+static herror_t
+_hsocket_sys_accept(hsocket_t *sock, hsocket_t *dest)
+{
+ socklen_t len;
+
+ len = sizeof(struct sockaddr_in);
+
+ if ((dest->sock = accept(sock->sock, (struct sockaddr *) &(dest->addr), &len)) == -1)
{
- return herror_new("hsocket_accept", HSOCKET_ERROR_ACCEPT,
- "Socket error: %d", errno);
+ log_warn2("accept failed (%s)", strerror(errno));
+ return herror_new("hsocket_accept", HSOCKET_ERROR_ACCEPT, "Cannot accept network connection (%s)", strerror(errno));
}
+
+ return H_OK;
+}
#endif
-/* TODO (#1#): Write to access.log file */
- log_verbose3("accept new socket (%d) from '%s'", sockfd.sock,
- SAVE_STR(((char *) inet_ntoa(addr.sin_addr))));
+/*----------------------------------------------------------
+FUNCTION: hsocket_accept
+----------------------------------------------------------*/
+herror_t
+hsocket_accept(hsocket_t *sock, hsocket_t *dest)
+{
+ herror_t status;
+
+ if (sock->sock < 0)
+ return herror_new("hsocket_accept", HSOCKET_ERROR_NOT_INITIALIZED,
+ "hsocket_t not initialized");
+
+ if ((status = _hsocket_sys_accept(sock, dest)) != H_OK)
+ return status;
+
+ if ((status = hssl_server_ssl(dest)) != H_OK)
+ {
+ log_warn("hsocket_accept", "SSL startup failed (%s)", herror_message(status));
+ return status;
+ }
+
+ log_debug3("accepting connection from '%s' socket=%d",
+ SAVE_STR(((char *) inet_ntoa(dest->addr.sin_addr))), dest->sock);
- dest->sock = sockfd.sock;
return H_OK;
}
@@ -322,17 +316,17 @@ hsocket_accept(hsocket_t sock, hsocket_t * dest)
FUNCTION: hsocket_listen
----------------------------------------------------*/
herror_t
-hsocket_listen(hsocket_t sock)
+hsocket_listen(hsocket_t *sock)
{
- if (sock.sock <= 0)
+ if (sock->sock < 0)
return herror_new("hsocket_listen", HSOCKET_ERROR_NOT_INITIALIZED,
- "Called hsocket_listen() before initializing!");
+ "Called hsocket_listen before initializing!");
- if (listen(sock.sock, 15) == -1)
+ if (listen(sock->sock, 15) == -1)
{
- log_error3("Can not listen: '%s'", "Socket error: %d", errno);
+ log_error2("listen failed (%s)", strerror(errno));
return herror_new("hsocket_listen", HSOCKET_ERROR_LISTEN,
- "Socket error: %d", errno);
+ "Cannot listen on this socket (%s)", strerror(errno));
}
return H_OK;
@@ -360,6 +354,8 @@ _hsocket_sys_close(hsocket_t *sock)
shutdown(sock->sock, SHUT_RDWR);
+ close(sock->sock);
+
return;
}
#endif
@@ -372,14 +368,7 @@ hsocket_close(hsocket_t *sock)
{
log_verbose3("closing socket %p (%d)...", sock, sock->sock);
-#ifdef HAVE_SSL
- if (sock->ssl)
- {
- log_verbose1("Closing SSL");
- ssl_cleanup(sock->ssl);
- sock->ssl = NULL;
- }
-#endif
+ hssl_cleanup(sock);
_hsocket_sys_close(sock);
@@ -392,68 +381,34 @@ hsocket_close(hsocket_t *sock)
FUNCTION: hsocket_send
----------------------------------------------------*/
herror_t
-hsocket_nsend(hsocket_t sock, const byte_t * bytes, int n)
+hsocket_nsend(hsocket_t *sock, const byte_t * bytes, int n)
{
- int size;
- int total = 0;
+ herror_t status;
+ size_t total = 0;
+ size_t size;
log_verbose2("Starting to send on sock=%p", &sock);
- if (sock.sock <= 0)
+ if (sock->sock < 0)
return herror_new("hsocket_nsend", HSOCKET_ERROR_NOT_INITIALIZED,
- "Called hsocket_listen() before initializing!");
+ "hsocket not initialized");
/* log_verbose2( "SENDING %s", bytes );*/
- /* TODO (#1#): check return value and send again until n bytes sent */
while (1)
{
-#ifdef HAVE_SSL
- log_verbose2("ssl = %p", sock.ssl);
- if (sock.ssl)
- {
- size = SSL_write(sock.ssl, bytes + total, n);
- }
- else
- {
-#endif
- size = send((int) sock.sock, bytes + total, n, 0);
-#ifdef HAVE_SSL
- }
-#endif
- log_verbose2("Sent %d", size);
- /* size = _test_send_to_file(filename, bytes, n); */
-#ifdef WIN32
- if (size == INVALID_SOCKET)
- {
- if (WSAGetLastError() == WSAEWOULDBLOCK)
- {
- continue;
- }
- else
- {
- return herror_new("hsocket_nsend", HSOCKET_ERROR_SEND,
- "Socket error: %d", errno);
- }
- }
-#else
- if (size == -1)
+
+ if ((status = hssl_write(sock, bytes + total, n, &size)) != H_OK)
{
-#ifdef HAVE_SSL
- if (sock.ssl)
- {
- log_error1("Send error");
- log_ssl_error(sock.ssl, size);
- }
-#endif
- return herror_new("hsocket_nsend", HSOCKET_ERROR_SEND,
- "Socket error: %d", errno);
+ log_warn("hssl_write failed (%s)", herror_message(status));
+ return status;
}
-#endif
+
n -= size;
total += size;
if (n <= 0)
break;
}
+
return H_OK;
}
@@ -461,125 +416,39 @@ hsocket_nsend(hsocket_t sock, const byte_t * bytes, int n)
FUNCTION: hsocket_send
----------------------------------------------------*/
herror_t
-hsocket_send(hsocket_t sock, const char *str)
+hsocket_send(hsocket_t *sock, const char *str)
{
return hsocket_nsend(sock, str, strlen(str));
}
-/*
- return: -1 is error. read bytes otherwise
-*/
herror_t
-hsocket_read(hsocket_t sock, byte_t * buffer, int total, int force,
- int *received)
+hsocket_read(hsocket_t *sock, byte_t * buffer, int total, int force, int *received)
{
- int status;
- int totalRead;
-#ifdef WIN32
- int wsa_error = 0;
-#endif
+ herror_t status;
+ size_t totalRead;
+ size_t count;
+
+// log_verbose3("Entering hsocket_read(total=%d,force=%d)", total, force);
+
totalRead = 0;
-/*
- log_verbose3("Entering hsocket_read(total=%d,force=%d)", total, force);
-*/
do
{
-#ifdef HAVE_SSL
- if (sock.ssl)
- {
- struct timeval timeout;
- /*int i = 0;*/
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(sock.sock, &fds);
- timeout.tv_sec = 10;
- timeout.tv_usec = 0;
-#ifndef WIN32
- fcntl(sock.sock, F_SETFL, O_NONBLOCK);
-#endif
- status = SSL_read(sock.ssl, &buffer[totalRead], total - totalRead);
-
- if(ssl_checkFatal( sock.ssl, status )){
- log_verbose1("SSL Error");
- return herror_new("hsocket_read", HSOCKET_ERROR_SSLCLOSE, "SSL Error");
- }
- if (SSL_get_shutdown(sock.ssl) == SSL_RECEIVED_SHUTDOWN) {
- log_verbose1("SSL shutdown error");
- return herror_new("hsocket_read", HSOCKET_ERROR_SSLCLOSE, "SSL shutdown error");
- }
-
- if (status < 1)
- {
- int ret = select(sock.sock + 1, &fds, NULL, NULL, &timeout);
-#ifdef WIN32
- if (ret == SOCKET_ERROR)
- {
- wsa_error = WSAGetLastError();
- log_error2("WSAGetLastError()=%d", wsa_error);
- return herror_new("hsocket_read", HSOCKET_ERROR_RECEIVE,
- "Socket error: %d", errno);
-
- }
-#endif
- if (ret == 0)
- {
- log_verbose1("Socket timeout");
- return herror_new("hsocket_read", HSOCKET_ERROR_SSLCLOSE, "Timeout");
- }
- else
- {
- status = SSL_read(sock.ssl, &buffer[totalRead], total - totalRead);
- if(ssl_checkFatal( sock.ssl, status )){
- log_verbose1("SSL Error");
- return herror_new("hsocket_read", HSOCKET_ERROR_SSLCLOSE, "SSL Error");
- }
- }
- }
-#ifndef WIN32
- fcntl(sock.sock, F_SETFL, 0);
-#endif
- }
- else
- {
-#else /* HAVE_SSL */
- {
-#endif /* HAVE_SSL */
- status = recv(sock.sock, &buffer[totalRead], total - totalRead, 0);
-#ifdef WIN32
- if (status == INVALID_SOCKET)
- {
- wsa_error = WSAGetLastError();
- switch (wsa_error)
- {
- case WSAEWOULDBLOCK:
- /* case WSAEALREADY: case WSAEINPROGRESS: */
- continue;
- default:
- log_error2("WSAGetLastError()=%d", wsa_error);
- return herror_new("hsocket_read", HSOCKET_ERROR_RECEIVE,
- "Socket error: %d", errno);
- }
- }
- }
-#else
+ if ((status = hssl_read(sock, &buffer[totalRead], (size_t)total - totalRead, &count)) != H_OK)
+ {
+ log_warn("hssl_read failed (%s)", herror_message(status));
+ return status;
}
- if (status == -1)
- return herror_new("hsocket_read", HSOCKET_ERROR_RECEIVE,
- "Socket error: %d", errno);
-#endif
-
if (!force)
{
- *received = status;
- /*
- log_verbose3("Leaving !force (received=%d)(status=%d)", *received,
- status); */
+ /* log_verbose3("Leaving !force (received=%d)(status=%d)", *received, status);
+ */
+ *received = count;
return H_OK;
}
- totalRead += status;
+ totalRead += count;
if (totalRead == total)
{
@@ -595,34 +464,32 @@ hsocket_read(hsocket_t sock, byte_t * buffer, int total, int force,
}
-herror_t
-hsocket_block(hsocket_t sock, int block)
-{
-#ifdef WIN32
- unsigned long iMode;
-#endif
-
- if (sock.sock <= 0)
- return herror_new("hsocket_block", HSOCKET_ERROR_NOT_INITIALIZED,
- "Called hsocket_listen() before initializing!");
-
-#ifdef WIN32
-/*#define HSOCKET_BLOCKMODE 0
-#define HSOCKET_NONBLOCKMODE 1
-*/
-
- iMode = (block == 0) ? 1 : 0; /* Non block mode */
- if (ioctlsocket(sock.sock, FIONBIO, (u_long FAR *) & iMode) ==
- INVALID_SOCKET)
- {
- int err = WSAGetLastError();
- log_error2("ioctlsocket error %d", err);
- return herror_new("hsocket_block", HSOCKET_ERROR_IOCTL,
- "Socket error: %d", err);
- }
-#else /* fcntl(sock, F_SETFL, O_NONBLOCK); */
-/* TODO (#1#): check for *nix the non blocking sockets */
-
-#endif
- return H_OK;
-}
+// #ifdef WIN32
+// herror_t
+// hsocket_block(hsocket_t *sock, int block)
+// {
+// unsigned long iMode;
+//
+// if (sock->sock < 0)
+// return herror_new("hsocket_block", HSOCKET_ERROR_NOT_INITIALIZED,
+// "Called hsocket_listen() before initializing!");
+//
+// iMode = (block == 0) ? 1 : 0; /* Non block mode */
+// if (ioctlsocket(sock.sock, FIONBIO, (u_long FAR *) & iMode) ==
+// INVALID_SOCKET)
+// {
+// int err = WSAGetLastError();
+// log_error2("ioctlsocket error %d", err);
+// return herror_new("hsocket_block", HSOCKET_ERROR_IOCTL,
+// "Socket error %d", err);
+// }
+//
+// return H_OK;
+// }
+// #else
+// herror_t
+// hsocket_block(hsocket_t *sock, int block)
+// {
+// return H_OK;
+// }
+// #endif