http.lua updated. still needs proxy support.

code.lua updated. looks neat.
This commit is contained in:
Diego Nehab 2004-01-16 07:06:31 +00:00
parent 3febb302ad
commit 89f3ecf782
10 changed files with 445 additions and 358 deletions

View file

@ -72,6 +72,14 @@ void sock_listen(p_sock ps, int backlog)
listen(*ps, backlog);
}
/*-------------------------------------------------------------------------*\
*
\*-------------------------------------------------------------------------*/
void sock_shutdown(p_sock ps, int how)
{
shutdown(*ps, how);
}
/*-------------------------------------------------------------------------*\
* Accept with timeout
\*-------------------------------------------------------------------------*/
@ -100,39 +108,47 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len,
/*-------------------------------------------------------------------------*\
* Send with timeout
* Here we exchanged the order of the calls to write and select
* The idea is that the outer loop (whoever is calling sock_send)
* will call the function again if we didn't time out, so we can
* call write and then select only if it fails.
* Should speed things up!
* We are also treating EINTR and EPIPE errors.
\*-------------------------------------------------------------------------*/
int sock_send(p_sock ps, const char *data, size_t count, size_t *sent,
int timeout)
{
t_sock sock = *ps;
struct timeval tv;
fd_set fds;
ssize_t put = 0;
int err;
ssize_t put;
int ret;
/* avoid making system calls on closed sockets */
if (sock == SOCK_INVALID) return IO_CLOSED;
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
FD_ZERO(&fds);
FD_SET(sock, &fds);
ret = select(sock+1, NULL, &fds, NULL, timeout >= 0 ? &tv : NULL);
if (ret > 0) {
put = write(sock, data, count);
if (put <= 0) {
err = IO_CLOSED;
#ifdef __CYGWIN__
/* this is for CYGWIN, which is like Unix but has Win32 bugs */
if (errno == EWOULDBLOCK) err = IO_DONE;
#endif
*sent = 0;
} else {
*sent = put;
err = IO_DONE;
}
return err;
} else {
/* make sure we repeat in case the call was interrupted */
do put = write(sock, data, count);
while (put <= 0 && errno == EINTR);
/* deal with failure */
if (put <= 0) {
/* in any case, nothing has been sent */
*sent = 0;
return IO_TIMEOUT;
/* run select to avoid busy wait */
if (errno != EPIPE) {
struct timeval tv;
fd_set fds;
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
FD_ZERO(&fds);
FD_SET(sock, &fds);
ret = select(sock+1, NULL, &fds, NULL, timeout >= 0 ? &tv : NULL);
/* tell the caller to call us again because there is more data */
if (ret > 0) return IO_DONE;
/* tell the caller there was no data before timeout */
else return IO_TIMEOUT;
/* here we know the connection has been closed */
} else return IO_CLOSED;
/* here we sent successfully sent something */
} else {
*sent = put;
return IO_DONE;
}
}
@ -176,32 +192,36 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
/*-------------------------------------------------------------------------*\
* Receive with timeout
* Here we exchanged the order of the calls to write and select
* The idea is that the outer loop (whoever is calling sock_send)
* will call the function again if we didn't time out, so we can
* call write and then select only if it fails.
* Should speed things up!
* We are also treating EINTR errors.
\*-------------------------------------------------------------------------*/
int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout)
{
t_sock sock = *ps;
struct timeval tv;
fd_set fds;
int ret;
ssize_t taken = 0;
ssize_t taken;
if (sock == SOCK_INVALID) return IO_CLOSED;
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
FD_ZERO(&fds);
FD_SET(sock, &fds);
ret = select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL);
if (ret > 0) {
taken = read(sock, data, count);
if (taken <= 0) {
*got = 0;
return IO_CLOSED;
} else {
*got = taken;
return IO_DONE;
}
} else {
do taken = read(sock, data, count);
while (taken <= 0 && errno == EINTR);
if (taken <= 0) {
struct timeval tv;
fd_set fds;
int ret;
*got = 0;
return IO_TIMEOUT;
if (taken == 0) return IO_CLOSED;
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
FD_ZERO(&fds);
FD_SET(sock, &fds);
ret = select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL);
if (ret > 0) return IO_DONE;
else return IO_TIMEOUT;
} else {
*got = taken;
return IO_DONE;
}
}