229 lines
5.7 KiB
C
229 lines
5.7 KiB
C
#include "mio-http.h"
|
|
#include "mio-htrd.h"
|
|
#include "mio-prv.h"
|
|
|
|
struct mio_svc_htts_t
|
|
{
|
|
MIO_SVC_HEADER;
|
|
|
|
mio_dev_sck_t* lsck;
|
|
};
|
|
|
|
struct mio_svc_httc_t
|
|
{
|
|
MIO_SVC_HEADER;
|
|
};
|
|
|
|
struct sck_xtn_t
|
|
{
|
|
mio_svc_htts_t* htts;
|
|
mio_htrd_t* htrd; /* used by clients only */
|
|
};
|
|
typedef struct sck_xtn_t sck_xtn_t;
|
|
|
|
struct htrd_xtn_t
|
|
{
|
|
mio_dev_sck_t* sck;
|
|
};
|
|
typedef struct htrd_xtn_t htrd_xtn_t;
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
static int client_on_read (mio_dev_sck_t* sck, const void* buf, mio_iolen_t len, const mio_skad_t* srcaddr)
|
|
{
|
|
sck_xtn_t* sckxtn = mio_dev_sck_getxtn(sck);
|
|
printf ("** HTTS - client read %p %d -> htts:%p\n", sck, (int)len, sckxtn->htts);
|
|
if (len <= 0)
|
|
{
|
|
mio_dev_sck_halt (sck);
|
|
}
|
|
else if (mio_htrd_feed(sckxtn->htrd, buf, len) <= -1)
|
|
{
|
|
mio_dev_sck_halt (sck);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int client_on_write (mio_dev_sck_t* sck, mio_iolen_t wrlen, void* wrctx, const mio_skad_t* dstaddr)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int client_on_disconnect (mio_dev_sck_t* sck)
|
|
{
|
|
printf ("** HTTS - client disconnect %p\n", sck);
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
static int listener_on_read (mio_dev_sck_t* sck, const void* buf, mio_iolen_t len, const mio_skad_t* srcaddr)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int listener_on_write (mio_dev_sck_t* sck, mio_iolen_t wrlen, void* wrctx, const mio_skad_t* dstaddr)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static void listener_on_connect (mio_dev_sck_t* sck)
|
|
{
|
|
sck_xtn_t* sckxtn = mio_dev_sck_getxtn(sck); /* the contents came from the listening socket */
|
|
|
|
if (sck->state & MIO_DEV_SCK_ACCEPTED)
|
|
{
|
|
/* accepted a new client */
|
|
htrd_xtn_t* htrdxtn;
|
|
|
|
printf ("** HTTS(%p) - accepted... %p %d \n", sckxtn->htts, sck, sck->sck);
|
|
|
|
/* the accepted socket inherits various event callbacks. switch some of them to avoid sharing */
|
|
sck->on_read = client_on_read;
|
|
sck->on_write = client_on_write;
|
|
sck->on_disconnect = client_on_disconnect;
|
|
|
|
sckxtn->htrd = mio_htrd_open(sck->mio, MIO_SIZEOF(*htrdxtn));
|
|
if (MIO_UNLIKELY(!sckxtn->htrd))
|
|
{
|
|
MIO_INFO2 (sck->mio, "UNABLE TO OPEN HTTP READER FOR ACCEPTED SOCKET %p %d\n", sck, (int)sck->sck);
|
|
mio_dev_sck_halt (sck);
|
|
}
|
|
else
|
|
{
|
|
htrdxtn = mio_htrd_getxtn(sckxtn->htrd);
|
|
htrdxtn->sck = sck;
|
|
}
|
|
}
|
|
else if (sck->state & MIO_DEV_SCK_CONNECTED)
|
|
{
|
|
/* this will never be triggered as the listing socket never call mio_dev_sck_connect() */
|
|
printf ("** HTTS(%p) - connected... %p %d \n", sckxtn->htts, sck, sck->sck);
|
|
}
|
|
|
|
/* MIO_DEV_SCK_CONNECTED must not be seen here as this is only for the listener socket */
|
|
}
|
|
|
|
static void listener_on_disconnect (mio_dev_sck_t* sck)
|
|
{
|
|
sck_xtn_t* sckxtn = mio_dev_sck_getxtn(sck);
|
|
|
|
switch (MIO_DEV_SCK_GET_PROGRESS(sck))
|
|
{
|
|
case MIO_DEV_SCK_CONNECTING:
|
|
MIO_INFO1 (sck->mio, "OUTGOING SESSION DISCONNECTED - FAILED TO CONNECT (%d) TO REMOTE SERVER\n", (int)sck->sck);
|
|
break;
|
|
|
|
case MIO_DEV_SCK_CONNECTING_SSL:
|
|
MIO_INFO1 (sck->mio, "OUTGOING SESSION DISCONNECTED - FAILED TO SSL-CONNECT (%d) TO REMOTE SERVER\n", (int)sck->sck);
|
|
break;
|
|
|
|
case MIO_DEV_SCK_LISTENING:
|
|
MIO_INFO1 (sck->mio, "SHUTTING DOWN THE SERVER SOCKET(%d)...\n", (int)sck->sck);
|
|
break;
|
|
|
|
case MIO_DEV_SCK_CONNECTED:
|
|
MIO_INFO1 (sck->mio, "OUTGOING CLIENT CONNECTION GOT TORN DOWN(%d).......\n", (int)sck->sck);
|
|
break;
|
|
|
|
case MIO_DEV_SCK_ACCEPTING_SSL:
|
|
MIO_INFO1 (sck->mio, "INCOMING SSL-ACCEPT GOT DISCONNECTED(%d) ....\n", (int)sck->sck);
|
|
break;
|
|
|
|
case MIO_DEV_SCK_ACCEPTED:
|
|
MIO_INFO1 (sck->mio, "INCOMING CLIENT BEING SERVED GOT DISCONNECTED(%d).......\n", (int)sck->sck);
|
|
break;
|
|
|
|
default:
|
|
MIO_INFO1 (sck->mio, "DISCONNECTED AFTER ALL(%d).......\n", (int)sck->sck);
|
|
break;
|
|
}
|
|
|
|
if (sckxtn->htrd)
|
|
{
|
|
mio_htrd_close (sckxtn->htrd);
|
|
sckxtn->htrd = 0;
|
|
}
|
|
}
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
mio_svc_htts_t* mio_svc_htts_start (mio_t* mio, const mio_skad_t* bind_addr)
|
|
{
|
|
mio_svc_htts_t* htts = MIO_NULL;
|
|
union
|
|
{
|
|
mio_dev_sck_make_t m;
|
|
mio_dev_sck_bind_t b;
|
|
mio_dev_sck_listen_t l;
|
|
} info;
|
|
sck_xtn_t* sckxtn;
|
|
|
|
htts = (mio_svc_htts_t*)mio_callocmem(mio, MIO_SIZEOF(*htts));
|
|
if (MIO_UNLIKELY(!htts)) goto oops;
|
|
|
|
htts->mio = mio;
|
|
htts->svc_stop = mio_svc_htts_stop;
|
|
|
|
MIO_MEMSET (&info, 0, MIO_SIZEOF(info));
|
|
switch (mio_skad_family(bind_addr))
|
|
{
|
|
case MIO_AF_INET:
|
|
info.m.type = MIO_DEV_SCK_TCP4;
|
|
break;
|
|
|
|
case MIO_AF_INET6:
|
|
info.m.type = MIO_DEV_SCK_TCP6;
|
|
break;
|
|
|
|
default:
|
|
mio_seterrnum (mio, MIO_EINVAL);
|
|
goto oops;
|
|
}
|
|
|
|
MIO_MEMSET (&info, 0, MIO_SIZEOF(info));
|
|
info.m.on_write = listener_on_write;
|
|
info.m.on_read = listener_on_read;
|
|
info.m.on_connect = listener_on_connect;
|
|
info.m.on_disconnect = listener_on_disconnect;
|
|
htts->lsck = mio_dev_sck_make(mio, MIO_SIZEOF(*sckxtn), &info.m);
|
|
if (!htts->lsck) goto oops;
|
|
|
|
sckxtn = (sck_xtn_t*)mio_dev_sck_getxtn(htts->lsck);
|
|
sckxtn->htts = htts;
|
|
|
|
MIO_MEMSET (&info, 0, MIO_SIZEOF(info));
|
|
info.b.localaddr = *bind_addr;
|
|
info.b.options = MIO_DEV_SCK_BIND_REUSEADDR | MIO_DEV_SCK_BIND_REUSEPORT;
|
|
MIO_INIT_NTIME (&info.b.accept_tmout, 5, 1);
|
|
if (mio_dev_sck_bind(htts->lsck, &info.b) <= -1) goto oops;
|
|
|
|
info.l.backlogs = 255;
|
|
if (mio_dev_sck_listen(htts->lsck, &info.l) <= -1) goto oops;
|
|
|
|
printf ("** HTTS LISTENER SOCKET %p\n", htts->lsck);
|
|
MIO_SVCL_APPEND_SVC (&mio->actsvc, (mio_svc_t*)htts);
|
|
return htts;
|
|
|
|
oops:
|
|
if (htts)
|
|
{
|
|
if (htts->lsck) mio_dev_sck_kill (htts->lsck);
|
|
mio_freemem (mio, htts);
|
|
}
|
|
return MIO_NULL;
|
|
}
|
|
|
|
void mio_svc_htts_stop (mio_svc_htts_t* htts)
|
|
{
|
|
mio_t* mio = htts->mio;
|
|
|
|
if (htts->lsck) mio_dev_sck_kill (htts->lsck);
|
|
/*if (dnc->lsck) mio_dev_sck_kill (dnc->lsck);
|
|
while (dnc->pending_req) release_dns_msg (dnc, dnc->pending_req);*/
|
|
|
|
MIO_SVCL_UNLINK_SVC (htts);
|
|
mio_freemem (mio, htts);
|
|
}
|
|
|
|
|