ant-http/lib/handle.c

888 lines
23 KiB
C
Raw Normal View History

#include "handle.h"
2019-12-15 12:10:06 +01:00
#define HTML_TPL "<HTML><HEAD><TITLE>%s</TITLE></HEAD><BODY><h2>%s</h2></BODY></HTML>"
2019-12-15 15:04:37 +01:00
static const char* S_100 = "Continue";
static const char* S_101 = "Switching Protocols";
static const char* S_102 = "Processing";
static const char* S_103 = "Early Hints";
static const char* S_200 = "OK";
static const char* S_201 = "Created";
static const char* S_202 = "Accepted";
static const char* S_203 = "Non-Authoritative Information";
static const char* S_204 = "No Content";
static const char* S_205 = "Reset Content";
static const char* S_206 = "Partial Content";
static const char* S_207 = "Multi-Status";
static const char* S_208 = "Already Reported";
static const char* S_226 = "IM Used";
static const char* S_300 = "Multiple Choices";
static const char* S_301 = "Moved Permanently";
static const char* S_302 = "Found";
static const char* S_303 = "See Other";
static const char* S_304 = "Not Modified";
static const char* S_305 = "Use Proxy";
static const char* S_306 = "Switch Proxy";
static const char* S_307 = "Temporary Redirect";
static const char* S_308 = "Permanent Redirect";
static const char* S_400 = "Bad Request";
static const char* S_401 = "Unauthorized";
static const char* S_402 = "Payment Required";
static const char* S_403 = "Forbidden";
static const char* S_404 = "Not Found";
static const char* S_405 = "Method Not Allowed";
static const char* S_406 = "Not Acceptable";
static const char* S_407 = "Proxy Authentication Required";
static const char* S_408 = "Request Timeout";
static const char* S_409 = "Conflict";
static const char* S_410 = "Gone";
static const char* S_411 = "Length Required";
static const char* S_412 = "Precondition Failed";
static const char* S_413 = "Payload Too Large";
static const char* S_414 = "URI Too Long";
static const char* S_415 = "Unsupported Media Type";
static const char* S_416 = "Range Not Satisfiable";
static const char* S_417 = "Expectation Failed";
static const char* S_421 = "Misdirected Request";
static const char* S_422 = "Unprocessable Entity";
static const char* S_423 = "Locked";
static const char* S_424 = "Failed Dependency";
static const char* S_425 = "Too Early";
static const char* S_426 = "Upgrade Required";
static const char* S_428 = "Precondition Required";
static const char* S_429 = "Too Many Requests";
static const char* S_431 = "Request Header Fields Too Large";
static const char* S_451 = "Unavailable For Legal Reasons";
static const char* S_500 = "Internal Server Error";
static const char* S_501 = "Not Implemented";
static const char* S_502 = "Bad Gateway";
static const char* S_503 = "Service Unavailable";
static const char* S_504 = "Gateway Timeout";
static const char* S_505 = "HTTP Version Not Supported";
static const char* S_506 = "Variant Also Negotiates";
static const char* S_507 = "Insufficient Storage";
static const char* S_508 = "Loop Detected";
static const char* S_510 = "Not Extended";
static const char* S_511 = "Network Authentication Required";
static const char* S_UNOF = "Unofficial Status";
2017-07-29 22:00:34 +02:00
2020-01-03 10:14:04 +01:00
int require_plugin(const char* name)
{
UNUSED(name);
return 0;
}
2020-01-08 19:17:51 +01:00
int compressable(char* ctype)
{
UNUSED(ctype);
return 0;
}
void htdocs(antd_request_t* rq, char* dest)
{
dictionary_t xheader = (dictionary_t)dvalue(rq->request, "REQUEST_HEADER");
char* www = (char*)dvalue(xheader, "SERVER_WWW_ROOT");
if(www)
{
strcpy(dest,www);
}
}
void dbdir(char* dest)
{
UNUSED(dest);
}
void tmpdir(char* dest)
{
UNUSED(dest);
}
void plugindir(char* dest)
{
UNUSED(dest);
}
2019-12-15 12:10:06 +01:00
const char* get_status_str(int stat)
2017-07-29 22:00:34 +02:00
{
2019-12-15 12:10:06 +01:00
switch(stat)
{
2019-12-15 15:04:37 +01:00
case 100: return S_100;
case 101: return S_101;
case 102: return S_102;
case 103: return S_103;
2019-12-15 12:10:06 +01:00
2019-12-15 15:04:37 +01:00
case 200: return S_200;
case 201: return S_201;
case 202: return S_202;
case 203: return S_203;
case 204: return S_204;
case 205: return S_205;
case 206: return S_206;
case 207: return S_207;
case 208: return S_208;
case 226: return S_226;
2019-12-15 12:10:06 +01:00
2019-12-15 15:04:37 +01:00
case 300: return S_300;
case 301: return S_301;
case 302: return S_302;
case 303: return S_303;
case 304: return S_304;
case 305: return S_305;
case 306: return S_306;
case 307: return S_307;
case 308: return S_308;
2019-12-15 12:10:06 +01:00
2019-12-15 15:04:37 +01:00
case 400: return S_400;
case 401: return S_401;
case 402: return S_402;
case 403: return S_403;
case 404: return S_404;
case 405: return S_405;
case 406: return S_406;
case 407: return S_407;
case 408: return S_408;
case 409: return S_409;
case 410: return S_410;
case 411: return S_411;
case 412: return S_412;
case 413: return S_413;
case 414: return S_414;
case 415: return S_415;
case 416: return S_416;
case 417: return S_417;
case 421: return S_421;
case 422: return S_422;
case 423: return S_423;
case 424: return S_424;
case 425: return S_425;
case 426: return S_426;
case 428: return S_428;
case 429: return S_429;
case 431: return S_431;
case 451: return S_451;
2019-12-15 12:10:06 +01:00
2019-12-15 15:04:37 +01:00
case 500: return S_500;
case 501: return S_501;
case 502: return S_502;
case 503: return S_503;
case 504: return S_504;
case 505: return S_505;
case 506: return S_506;
case 507: return S_507;
case 508: return S_508;
case 510: return S_510;
case 511: return S_511;
default: return S_UNOF;
2019-12-15 12:10:06 +01:00
}
2017-07-29 22:00:34 +02:00
}
2019-12-15 12:10:06 +01:00
2020-01-08 19:17:51 +01:00
void antd_send_header(void* cl, antd_response_header_t* res)
2019-12-15 12:10:06 +01:00
{
if(!res->header)
res->header = dict();
2020-01-08 19:17:51 +01:00
antd_client_t* client = (antd_client_t*) cl;
#ifdef USE_ZLIB
2020-01-08 22:04:10 +01:00
antd_compress_t current_zlevel = client->z_level;
2020-01-08 19:17:51 +01:00
char* str = dvalue(res->header,"Content-Encoding");
if(!str)
{
// check for compress
str = dvalue(res->header,"Content-Type");
if(str)
{
2020-01-08 22:04:10 +01:00
if(compressable(str) && client->z_level != ANTD_CNONE)
2020-01-08 19:17:51 +01:00
{
2020-01-08 22:04:10 +01:00
client->zstream = (z_stream *) malloc(sizeof(z_stream));
if(client->zstream)
2020-01-08 19:17:51 +01:00
{
2020-01-08 22:04:10 +01:00
((z_stream*)client->zstream)->zalloc = Z_NULL;
((z_stream*)client->zstream)->zfree = Z_NULL;
((z_stream*)client->zstream)->opaque = Z_NULL;
if(client->z_level == ANTD_CGZ)
2020-01-08 19:17:51 +01:00
{
if(deflateInit2(client->zstream,Z_BEST_COMPRESSION,Z_DEFLATED,15 | 16, 8,Z_DEFAULT_STRATEGY) != Z_OK)
{
ERROR("Cannot init gzip stream");
free(client->zstream);
client->zstream = NULL;
}
else
{
client->status = Z_NO_FLUSH;
dput(res->header,"Content-Encoding", strdup("gzip"));
}
}
2020-01-08 22:04:10 +01:00
else
2020-01-08 19:17:51 +01:00
{
if(deflateInit(client->zstream, Z_BEST_COMPRESSION) != Z_OK)
{
ERROR("Cannot init deflate stream");
free(client->zstream);
client->zstream = NULL;
}
else
{
client->status = Z_NO_FLUSH;
dput(res->header,"Content-Encoding", strdup("deflate"));
}
}
}
}
}
}
2020-01-08 22:04:10 +01:00
client->z_level = ANTD_CNONE;
2020-01-08 19:17:51 +01:00
#endif
2019-12-15 12:10:06 +01:00
dput(res->header,"Server", strdup(SERVER_NAME));
const char* stat_str = get_status_str(res->status);
__t(client, "HTTP/1.1 %d %s", res->status, stat_str);
chain_t it;
for_each_assoc(it, res->header)
{
__t(client,"%s: %s", it->key, (const char*)it->value);
}
// send out cookie
if(res->cookie)
{
2019-12-22 17:33:35 +01:00
item_t el;
list_for_each(el, res->cookie)
2019-12-15 12:10:06 +01:00
{
2019-12-22 17:33:35 +01:00
if(el->type == LIST_TYPE_POINTER && el->value.ptr)
{
__t(client,"Set-Cookie: %s", (char*)el->value.ptr);
}
2019-12-15 12:10:06 +01:00
}
list_free(&res->cookie);
res->cookie = NULL;
}
__b(client, (unsigned char*)"\r\n", 2);
2020-01-08 22:04:10 +01:00
#ifdef USE_ZLIB
client->z_level = current_zlevel;
#endif
2019-12-15 12:10:06 +01:00
freedict(res->header);
res->header = NULL;
2017-07-29 22:00:34 +02:00
}
2019-12-15 12:10:06 +01:00
/*
2018-02-10 11:22:41 +01:00
void octstream(void* client, char* name)
2017-07-29 22:00:34 +02:00
{
set_status(client,200,"OK");
__t(client,"Content-Type: application/octet-stream");
__t(client,"Content-Disposition: attachment; filename=\"%s\"", name);
response(client,"");
//Content-Disposition: attachment; filename="fname.ext"
2019-12-15 12:10:06 +01:00
}*/
2017-07-29 22:00:34 +02:00
2020-01-08 19:17:51 +01:00
int antd_send(void *src, const void* data_in, int len_in)
{
uint8_t* data = (uint8_t*)data_in;
int len = len_in;
2018-02-10 11:22:41 +01:00
antd_client_t * source = (antd_client_t *) src;
2020-01-08 19:17:51 +01:00
#ifdef USE_ZLIB
if(source->zstream && source->z_level != ANTD_CNONE)
{
2020-01-08 22:04:10 +01:00
antd_compress_t current_zlevel = source->z_level;
source->z_level = ANTD_CNONE;
uint8_t buf[BUFFLEN];
z_stream* zstream = (z_stream*) source->zstream;
zstream->avail_in = (uInt)len;
zstream->next_in = (Bytef *)data_in;
len = 0;
int have = 0;
do
2020-01-08 19:17:51 +01:00
{
2020-01-08 22:04:10 +01:00
zstream->avail_out = BUFFLEN;
zstream->next_out = buf;
if(deflate(zstream, source->status) == Z_STREAM_ERROR)
{
source->z_level = current_zlevel;
data = NULL;
return -1;
}
else
{
have = BUFFLEN - zstream->avail_out;
antd_send(source, buf, have);
len += have;
}
} while(zstream->avail_out == 0);
source->z_level = current_zlevel;
//printf("data length %d\n", len);
return len;
2020-01-08 19:17:51 +01:00
}
#endif
if(!src || !data)
2020-01-08 22:04:10 +01:00
{
2020-01-08 19:17:51 +01:00
return -1;
}
2020-01-08 22:04:10 +01:00
2020-01-08 19:17:51 +01:00
int written;
2018-10-27 12:58:12 +02:00
char* ptr;
2019-12-15 12:10:06 +01:00
int writelen = 0;
2018-10-27 12:58:12 +02:00
int count;
2020-01-08 19:17:51 +01:00
2018-02-10 11:22:41 +01:00
#ifdef USE_OPENSSL
2020-01-08 19:17:51 +01:00
if(source->ssl)
2018-02-10 11:22:41 +01:00
{
2018-02-10 12:24:01 +01:00
//LOG("SSL WRITE\n");
2018-10-09 17:24:00 +02:00
//ret = SSL_write((SSL*) source->ssl, data, len);
2018-10-27 12:58:12 +02:00
ptr = (char* )data;
writelen = len > BUFFLEN?BUFFLEN:len;
2018-10-09 17:24:00 +02:00
written = 0;
fd_set fds;
struct timeval timeout;
2018-10-15 12:28:04 +02:00
while (writelen > 0) //source->attempt < MAX_ATTEMPT
2018-10-09 17:24:00 +02:00
{
2019-12-13 09:52:28 +01:00
// clear the error queue
ERR_clear_error();
2018-10-09 17:24:00 +02:00
count = SSL_write (source->ssl, ptr+written, writelen);
2019-12-15 17:13:25 +01:00
int err = SSL_get_error(source->ssl, count);
2018-10-09 17:24:00 +02:00
if (count > 0)
{
written += count;
writelen = (len - written) > BUFFLEN?BUFFLEN:(len-written);
2019-12-21 15:02:33 +01:00
time(&source->last_io);
2018-10-09 17:24:00 +02:00
}
else
{
2019-12-21 15:02:33 +01:00
if(difftime( time(NULL), source->last_io) > MAX_IO_WAIT_TIME)
{
if(written == 0)
written = count;
break;
}
2018-10-09 17:24:00 +02:00
//printf(" received equal to or less than 0\n")
switch (err)
{
case SSL_ERROR_NONE:
{
// no real error, just try again...
//LOG("SSL_ERROR_NONE \n");
2018-10-15 12:28:04 +02:00
//source->attempt++;
2018-10-09 17:24:00 +02:00
continue;
}
case SSL_ERROR_ZERO_RETURN:
{
// peer disconnected...
2019-12-20 16:49:41 +01:00
// ERROR("SSLWRITE: SSL_ERROR_ZERO_RETURN: peer disconected: %d", source->sock);
2018-10-09 17:24:00 +02:00
break;
}
case SSL_ERROR_WANT_READ:
{
// no data available right now, wait a few seconds in case new data arrives...
//printf("SSL_ERROR_WANT_READ\n");
int sock = SSL_get_rfd(source->ssl);
FD_ZERO(&fds);
FD_SET(sock, &fds);
timeout.tv_sec = 0;
timeout.tv_usec = 500;
err = select(sock+1, &fds, NULL, NULL, &timeout);
if (err == 0 || (err > 0 && FD_ISSET(sock, &fds)))
2018-10-14 10:57:09 +02:00
{
2018-10-15 12:28:04 +02:00
//source->attempt++;
2018-10-09 17:24:00 +02:00
continue; // more data to read...
2018-10-14 10:57:09 +02:00
}
2019-12-15 16:24:15 +01:00
//ERROR("SSL WRITE: want read but select error on the socket %d: %s", source->sock, strerror(errno));
2018-10-14 10:57:09 +02:00
break;
2018-10-09 17:24:00 +02:00
}
case SSL_ERROR_WANT_WRITE:
{
// socket not writable right now, wait a few seconds and try again...
//printf("SSL_ERROR_WANT_WRITE \n");
int sock = SSL_get_wfd(source->ssl);
FD_ZERO(&fds);
FD_SET(sock, &fds);
timeout.tv_sec = 0;
timeout.tv_usec = 500;
err = select(sock+1, NULL, &fds, NULL, &timeout);
if (err == 0 || (err > 0 && FD_ISSET(sock, &fds)))
2018-10-14 10:57:09 +02:00
{
2018-10-15 12:28:04 +02:00
//source->attempt++;
2018-10-09 17:24:00 +02:00
continue; // can write more data now...
2018-10-14 10:57:09 +02:00
}
2019-12-15 16:24:15 +01:00
//ERROR("SSL WRITE: want write but select error on the socket %d: %s", source->sock, strerror(errno));
2018-10-14 10:57:09 +02:00
break;
2018-10-09 17:24:00 +02:00
}
default:
{
2019-12-11 23:17:42 +01:00
// other error
2019-12-15 16:24:15 +01:00
//ERROR("SSL WRITE: Unknown error on %d: %s", source->sock, ERR_error_string(ERR_get_error(), NULL) );
2018-10-09 17:24:00 +02:00
break;
}
}
2019-12-15 16:38:58 +01:00
if(written == 0)
written = count;
2019-12-19 09:52:56 +01:00
break;
2018-10-09 17:24:00 +02:00
}
}
2018-10-15 21:35:57 +02:00
//source->attempt = 0;
2018-02-10 11:22:41 +01:00
}
else
{
#endif
2018-10-27 16:15:25 +02:00
ptr = (char* )data;
2018-10-27 12:58:12 +02:00
writelen = len > BUFFLEN?BUFFLEN:len;
written = 0;
while (writelen > 0)
{
2018-10-27 16:15:25 +02:00
count = send(source->sock, ptr+written, writelen, 0);
2018-10-27 12:58:12 +02:00
if (count > 0)
{
written += count;
writelen = (len - written) > BUFFLEN?BUFFLEN:(len-written);
2019-12-21 15:02:33 +01:00
time(&source->last_io);
2018-10-27 12:58:12 +02:00
}
2019-12-21 15:02:33 +01:00
else if(difftime( time(NULL), source->last_io) > MAX_IO_WAIT_TIME || (count == -1 && errno != EAGAIN && errno != EWOULDBLOCK))
2018-10-27 12:58:12 +02:00
{
2019-12-15 16:38:58 +01:00
if(written == 0)
written = count;
2019-12-21 15:02:33 +01:00
//ERROR("Error while writing: %s", strerror(errno));
2019-12-15 12:10:06 +01:00
break;
//return written;
2018-10-27 12:58:12 +02:00
}
}
2018-02-10 11:22:41 +01:00
#ifdef USE_OPENSSL
}
#endif
2018-06-26 13:40:53 +02:00
/*if(ret <= 0)
2018-05-03 15:10:44 +02:00
{
antd_close(src);
2018-06-26 13:40:53 +02:00
}*/
2020-01-08 19:17:51 +01:00
#ifdef USE_ZLIB
if(source->zstream && source->z_level != ANTD_CNONE && data)
free(data);
#endif
2018-10-09 17:24:00 +02:00
return written;
2018-02-10 11:22:41 +01:00
}
2018-05-03 15:12:10 +02:00
int antd_recv(void *src, void* data, int len)
2018-02-10 11:22:41 +01:00
{
2018-02-10 12:24:01 +01:00
if(!src) return -1;
2018-10-27 16:15:25 +02:00
int read=0;
char* ptr = NULL;
int received=0;
int readlen=0;
2018-02-10 11:22:41 +01:00
antd_client_t * source = (antd_client_t *) src;
#ifdef USE_OPENSSL
2020-01-08 19:17:51 +01:00
if(source->ssl)
2018-02-10 11:22:41 +01:00
{
2018-10-27 12:58:12 +02:00
ptr = (char* )data;
readlen = len > BUFFLEN?BUFFLEN:len;
2018-10-07 13:57:52 +02:00
read = 0;
fd_set fds;
struct timeval timeout;
2018-10-15 12:28:04 +02:00
while (readlen > 0 )//&& source->attempt < MAX_ATTEMPT
2018-10-07 13:57:52 +02:00
{
2019-12-13 09:52:28 +01:00
ERR_clear_error();
2018-10-07 13:57:52 +02:00
received = SSL_read (source->ssl, ptr+read, readlen);
2019-12-15 17:13:25 +01:00
int err = SSL_get_error(source->ssl, received);
2018-10-07 13:57:52 +02:00
if (received > 0)
{
read += received;
readlen = (len - read) > BUFFLEN?BUFFLEN:(len-read);
2019-12-21 15:02:33 +01:00
time(&source->last_io);
2018-10-07 13:57:52 +02:00
}
else
{
2019-12-21 15:02:33 +01:00
// Timeout, quit
if(difftime( time(NULL), source->last_io) > MAX_IO_WAIT_TIME)
{
if(read == 0)
read = received;
break;
}
2018-10-07 13:57:52 +02:00
//printf(" received equal to or less than 0\n")
switch (err)
{
case SSL_ERROR_NONE:
{
// no real error, just try again...
//LOG("SSL_ERROR_NONE \n");
2018-10-15 12:28:04 +02:00
//source->attempt++;
2018-10-07 13:57:52 +02:00
continue;
}
case SSL_ERROR_ZERO_RETURN:
{
// peer disconnected...
2019-12-15 16:24:15 +01:00
//ERROR("SSL READ: SSL_ERROR_ZERO_RETURN, peer disconnected %d", source->sock);
2018-10-07 13:57:52 +02:00
break;
}
case SSL_ERROR_WANT_READ:
{
// no data available right now, wait a few seconds in case new data arrives...
//printf("SSL_ERROR_WANT_READ\n");
int sock = SSL_get_rfd(source->ssl);
FD_ZERO(&fds);
FD_SET(sock, &fds);
timeout.tv_sec = 0;
timeout.tv_usec = 500;
err = select(sock+1, &fds, NULL, NULL, &timeout);
if (err == 0 || (err > 0 && FD_ISSET(sock, &fds)))
2018-10-14 10:57:09 +02:00
{
2018-10-15 12:28:04 +02:00
//source->attempt++;
2018-10-07 13:57:52 +02:00
continue; // more data to read...
2018-10-14 10:57:09 +02:00
}
2019-12-15 16:24:15 +01:00
//ERROR("SSL READ: want read but select error on the socket %d: %s", source->sock, strerror(errno));
2018-10-14 10:57:09 +02:00
break;
2018-10-07 13:57:52 +02:00
}
case SSL_ERROR_WANT_WRITE:
{
// socket not writable right now, wait a few seconds and try again...
//printf("SSL_ERROR_WANT_WRITE \n");
int sock = SSL_get_wfd(source->ssl);
FD_ZERO(&fds);
FD_SET(sock, &fds);
timeout.tv_sec = 0;
timeout.tv_usec = 500;
err = select(sock+1, NULL, &fds, NULL, &timeout);
if (err == 0 || (err > 0 && FD_ISSET(sock, &fds)))
2018-10-14 10:57:09 +02:00
{
2018-10-15 12:28:04 +02:00
//source->attempt++;
2018-10-07 13:57:52 +02:00
continue; // can write more data now...
2018-10-14 10:57:09 +02:00
}
2019-12-15 16:24:15 +01:00
//ERROR("SSL READ: want write but select error on the socket %d: %s", source->sock, strerror(errno));
2018-10-14 10:57:09 +02:00
break;
2018-10-07 13:57:52 +02:00
}
default:
{
// other error
2019-12-15 16:24:15 +01:00
//ERROR("SSL READ: unkown error on %d: %s", source->sock, ERR_error_string(ERR_get_error(), NULL));
2018-10-07 13:57:52 +02:00
break;
}
}
2019-12-20 16:49:41 +01:00
if(read == 0)
2019-12-15 16:38:58 +01:00
read = received;
2018-10-07 13:57:52 +02:00
break;
}
}
2018-10-15 21:35:57 +02:00
//source->attempt = 0;
2018-10-07 01:03:05 +02:00
/*
int stat, r, st;
do{
ret = SSL_read((SSL*) source->ssl, data, len);
stat = SSL_get_error((SSL*)source->ssl, r);
} while(ret == -1 &&
(
stat == SSL_ERROR_WANT_READ ||
stat == SSL_ERROR_WANT_WRITE ||
stat == SSL_ERROR_NONE ||
(stat == SSL_ERROR_SYSCALL && r== 0 && !ERR_get_error())
));
if(ret == -1)
{
LOG("Problem reading %d %d %d\n", ret, stat, r);
}
//set_nonblock(source->sock);
*/
2018-02-10 11:22:41 +01:00
}
else
{
#endif
2018-10-27 12:58:12 +02:00
ptr = (char* )data;
readlen = len > BUFFLEN?BUFFLEN:len;
read = 0;
2019-12-21 15:02:33 +01:00
while (readlen > 0 )
2018-10-27 12:58:12 +02:00
{
2018-10-27 16:15:25 +02:00
received = recv(((int) source->sock), ptr+read, readlen, 0);
2018-10-27 16:21:12 +02:00
//LOG("Read : %c\n", *ptr);
2018-10-27 12:58:12 +02:00
if (received > 0)
{
read += received;
readlen = (len - read) > BUFFLEN?BUFFLEN:(len-read);
2019-12-21 15:02:33 +01:00
time(&source->last_io);
2018-10-27 16:21:12 +02:00
//LOG("Read len is %d\n", readlen);
2018-10-27 12:58:12 +02:00
}
2019-12-21 15:02:33 +01:00
else if( difftime( time(NULL), source->last_io) > MAX_IO_WAIT_TIME || (errno != EAGAIN && errno != EWOULDBLOCK))
2018-10-27 12:58:12 +02:00
{
2019-12-21 00:22:45 +01:00
//ERROR("Error while reading: %s", strerror(errno));
2019-12-15 16:38:58 +01:00
if(read ==0)
read = received;
2018-10-27 16:15:25 +02:00
break;
2018-10-27 12:58:12 +02:00
}
}
2018-10-27 16:15:25 +02:00
//read = recv(((int) source->sock), data, len, 0);
2018-02-10 11:22:41 +01:00
#ifdef USE_OPENSSL
}
#endif
2018-10-27 16:15:25 +02:00
//LOG("Received %d bytes\n", read);
2018-06-26 13:40:53 +02:00
/*if(ret == 0)
2018-05-03 15:10:44 +02:00
{
antd_close(src);
2018-06-26 13:40:53 +02:00
}*/
2018-10-07 13:57:52 +02:00
return read;
2018-02-10 11:22:41 +01:00
}
2018-10-07 01:03:05 +02:00
void set_nonblock(int socket) {
int flags;
flags = fcntl(socket,F_GETFL,0);
//assert(flags != -1);
fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}
2018-10-07 14:20:36 +02:00
/*void set_block()
2018-10-07 01:03:05 +02:00
{
int flags;
flags = fcntl(socket,F_GETFL,0);
//assert(flags != -1);
fcntl(socket, F_SETFL, flags & (~O_NONBLOCK));
2018-10-07 14:20:36 +02:00
}*/
2018-02-10 11:22:41 +01:00
int antd_close(void* src)
{
2018-02-10 12:24:01 +01:00
if(!src) return -1;
2018-02-10 11:22:41 +01:00
antd_client_t * source = (antd_client_t *) src;
2020-01-08 19:17:51 +01:00
#ifdef USE_ZLIB
//TODO: send finish data to the socket before quit
if(source->zstream)
{
2020-01-08 22:04:10 +01:00
if(source->status == Z_NO_FLUSH && source->z_level != ANTD_CNONE)
2020-01-08 19:17:51 +01:00
{
source->status = Z_FINISH;
2020-01-08 22:04:10 +01:00
antd_send(source, "", 0);
2020-01-08 19:17:51 +01:00
}
deflateEnd(source->zstream);
free(source->zstream);
2020-01-08 22:04:10 +01:00
source->zstream = NULL;
source->z_level = ANTD_CNONE;
2020-01-08 19:17:51 +01:00
}
#endif
2018-02-10 11:22:41 +01:00
#ifdef USE_OPENSSL
2020-01-08 19:17:51 +01:00
if(source->ssl){
2018-02-10 16:57:21 +01:00
//printf("SSL:Shutdown ssl\n");
//SSL_shutdown((SSL*) source->ssl);
SSL_set_shutdown((SSL*) source->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
//printf("SSL:Free ssl\n");
2018-02-10 11:22:41 +01:00
SSL_free((SSL*) source->ssl);
2018-10-09 12:15:48 +02:00
//EVP_cleanup();
//ENGINE_cleanup();
CRYPTO_cleanup_all_ex_data();
ERR_remove_state(0);
ERR_free_strings();
source->ssl = NULL;
2018-02-10 12:24:01 +01:00
//LOG("Freeing SSL\n");
2018-02-10 11:22:41 +01:00
}
#endif
2018-02-10 12:24:01 +01:00
//printf("Close sock %d\n", source->sock);
int ret = close(source->sock);
free(src);
2018-06-26 13:40:53 +02:00
src = NULL;
2018-02-10 12:24:01 +01:00
return ret;
2018-02-10 11:22:41 +01:00
}
2017-07-29 22:00:34 +02:00
2018-02-10 11:22:41 +01:00
int __t(void* client, const char* fstring,...)
2017-07-29 22:00:34 +02:00
{
int dlen;
2019-12-15 12:10:06 +01:00
int st;
2017-07-29 22:00:34 +02:00
va_list arguments;
char * data;
va_start( arguments, fstring);
2019-12-15 12:10:06 +01:00
dlen = vsnprintf(0,0,fstring,arguments)+1;
2017-07-29 22:00:34 +02:00
va_end(arguments);
if ((data = (char*)malloc(dlen*sizeof(char))) != 0)
{
va_start(arguments, fstring);
vsnprintf(data, dlen, fstring, arguments);
va_end(arguments);
2019-12-15 12:10:06 +01:00
st = __b(client, (const unsigned char*)data, strlen(data));
2019-12-15 16:24:15 +01:00
if(st)
__b(client, (unsigned char*)"\r\n", 2);
2017-07-29 22:00:34 +02:00
free(data);
2019-12-15 12:10:06 +01:00
return st;
2017-07-29 22:00:34 +02:00
}
2019-12-15 12:10:06 +01:00
return 0;
2017-07-29 22:00:34 +02:00
//
}
2018-02-10 11:22:41 +01:00
int __b(void* client, const unsigned char* data, int size)
2017-07-29 22:00:34 +02:00
{
int sent = 0;
int buflen = 0;
2019-12-15 12:10:06 +01:00
int nbytes = 0;
2020-01-08 22:04:10 +01:00
char* ptr = (char*)data;
2019-12-15 12:10:06 +01:00
/*if(size <= BUFFLEN)
2017-07-29 22:00:34 +02:00
{
2018-02-10 13:44:25 +01:00
nbytes = antd_send(client,data,size);
2017-07-29 22:00:34 +02:00
return (nbytes==-1?0:1);
}
else
2019-12-15 12:10:06 +01:00
{*/
2017-07-29 22:00:34 +02:00
while(sent < size)
{
if(size - sent > BUFFLEN)
buflen = BUFFLEN;
else
buflen = size - sent;
2020-01-08 22:04:10 +01:00
nbytes = antd_send(client,ptr,buflen);
2019-12-15 12:10:06 +01:00
if(nbytes == -1)
{
return 0;
}
2020-01-08 22:04:10 +01:00
sent += buflen;
ptr += buflen;
2017-07-29 22:00:34 +02:00
}
2019-12-15 12:10:06 +01:00
//}
2017-07-29 22:00:34 +02:00
return 1;
}
2019-11-30 20:40:40 +01:00
int __f(void* client, const char* file)
2017-07-29 22:00:34 +02:00
{
unsigned char buffer[BUFFLEN];
FILE *ptr;
ptr = fopen(file,"rb");
if(!ptr)
{
2019-12-11 23:17:42 +01:00
LOG("Cannot read : %s", file);
2017-07-29 22:00:34 +02:00
return 0;
}
size_t size;
while(!feof(ptr))
{
size = fread(buffer,1,BUFFLEN,ptr);
2020-01-08 22:04:10 +01:00
if(antd_send(client,buffer,size) == -1) return 0;
2017-07-29 22:00:34 +02:00
}
fclose(ptr);
return 1;
}
2019-12-15 12:10:06 +01:00
2017-07-29 22:00:34 +02:00
int upload(const char* tmp, const char* path)
{
return !rename(tmp, path);
}
2019-12-15 12:10:06 +01:00
/*
void set_cookie(void* client,const char* type, dictionary_t dic, const char* name)
2017-07-29 22:00:34 +02:00
{
set_status(client,200,"OK");
__t(client,"Content-Type: %s",type);
2019-12-15 12:10:06 +01:00
chain_t assoc;
2017-07-29 22:00:34 +02:00
for_each_assoc(assoc,dic){
__t(client,"Set-Cookie: %s=%s; Path=/%s",assoc->key, (char*)assoc->value, name);
}
response(client,"");
}
2019-12-15 12:10:06 +01:00
void clear_cookie(void* client, dictionary_t dic)
2017-07-29 22:00:34 +02:00
{
set_status(client,200,"OK");
__t(client,"Content-Type: text/html; charset=utf-8");
2019-12-15 12:10:06 +01:00
chain_t assoc;
2017-07-29 22:00:34 +02:00
for_each_assoc(assoc,dic){
2019-12-15 12:10:06 +01:00
__t(client,"Set-Cookie: %s=%s;expires=%s",assoc->key, (char*)assoc->value, server_time());
2017-07-29 22:00:34 +02:00
}
response(client,"");
}
2019-12-15 12:10:06 +01:00
*/
void antd_error(void* client, int status, const char* msg)
{
antd_response_header_t rsh;
rsh.header = dict();
rsh.cookie = NULL;
const char* stat_str = get_status_str(status);
rsh.status = status;
2020-01-08 22:04:10 +01:00
char* ctype = "text/html; charset=utf-8";
dput(rsh.header, "Content-Type", strdup(ctype));
2019-12-15 12:10:06 +01:00
char * res_str = __s(HTML_TPL, stat_str, msg);
int clen = 0;
if(res_str)
{
clen = strlen(res_str);
}
char ibuf[20];
snprintf (ibuf, sizeof(ibuf), "%d",clen);
2020-01-08 22:04:10 +01:00
if(((antd_client_t*)client)->z_level == ANTD_CNONE || !compressable(ctype))
dput(rsh.header, "Content-Length", strdup(ibuf));
2019-12-15 12:10:06 +01:00
antd_send_header(client, &rsh);
if(res_str)
{
//printf("%s\n", res_str);
__b(client, (unsigned char*)res_str, clen);
//__t(client, HTML_TPL, stat_str, msg);
free(res_str);
}
2017-07-29 22:00:34 +02:00
}
2019-12-15 12:10:06 +01:00
int ws_enable(dictionary_t dic)
2017-07-29 22:00:34 +02:00
{
2018-09-18 10:33:42 +02:00
if(!dic) return 0;
char*v = (char*)dvalue(dic, "__web_socket__");
if(!v) return 0;
return atoi(v) == 1;
2017-07-29 23:54:43 +02:00
}
2019-12-22 14:33:42 +01:00
2017-07-29 23:54:43 +02:00
/**
* Read the socket request in to a buffer or size
* The data is read until the buffer is full or
* there are a carrier return character
* @param sock socket
* @param buf buffer
* @param size size of buffer
* @return number of bytes read
*/
2018-02-10 11:22:41 +01:00
int read_buf(void* sock, char*buf,int size)
2017-07-29 23:54:43 +02:00
{
int i = 0;
char c = '\0';
int n;
while ((i < size - 1) && (c != '\n'))
{
2018-02-10 13:44:25 +01:00
n = antd_recv(sock, &c, 1);
2017-07-29 23:54:43 +02:00
if (n > 0)
{
2018-10-27 16:15:25 +02:00
//LOG("Data : %c\n", c);
2017-07-29 23:54:43 +02:00
buf[i] = c;
i++;
}
else
c = '\n';
}
buf[i] = '\0';
return i;
}
/*
We put it here since we want the plugin is able
to destroy the request if it want to
in this case, the plugin should return an empty
with no data
*/
void destroy_request(void *data)
{
if (!data)
return;
antd_request_t *rq = (antd_request_t *)data;
2019-12-20 16:49:41 +01:00
//LOG("Close request %d", rq->client->sock);
// free all other thing
if (rq->request)
{
2019-12-15 12:10:06 +01:00
dictionary_t tmp = dvalue(rq->request, "COOKIE");
if (tmp)
freedict(tmp);
tmp = dvalue(rq->request, "REQUEST_HEADER");
if (tmp)
freedict(tmp);
tmp = dvalue(rq->request, "REQUEST_DATA");
if (tmp)
freedict(tmp);
dput(rq->request, "REQUEST_HEADER", NULL);
dput(rq->request, "REQUEST_DATA", NULL);
dput(rq->request, "COOKIE", NULL);
freedict(rq->request);
}
antd_close(rq->client);
free(rq);
2017-07-29 22:00:34 +02:00
}