writing the http server service

This commit is contained in:
hyung-hwan 2020-05-05 15:12:08 +00:00
parent 0087bf8b12
commit 2df338ee9a
9 changed files with 299 additions and 24 deletions

View File

@ -31,6 +31,7 @@
#include <mio-pro.h>
#include <mio-dns.h>
#include <mio-nwif.h>
#include <mio-http.h>
#include <stdlib.h>
#include <string.h>
@ -944,8 +945,10 @@ for (i = 0; i < 5; i++)
{
mio_svc_dnc_t* dnc;
mio_svc_htts_t* htts;
mio_ntime_t send_tmout, reply_tmout;
mio_skad_t servaddr;
mio_skad_t htts_bind_addr;
send_tmout.sec = 0;
send_tmout.nsec = 0;
@ -955,7 +958,12 @@ for (i = 0; i < 5; i++)
mio_bcstrtoskad (mio, "8.8.8.8:53", &servaddr);
//mio_bcstrtoskad (mio, "[fe80::c7e2:bd6e:1209:ac1b]:1153", &servaddr);
//mio_bcstrtoskad (mio, "[fe80::c7e2:bd6e:1209:ac1b%eno1]:1153", &servaddr);
//mio_bcstrtoskad (mio, "[::]:9988", &htts_bind_addr);
mio_bcstrtoskad (mio, "127.0.0.1:9988", &htts_bind_addr);
dnc = mio_svc_dnc_start(mio, &servaddr, MIO_NULL, &send_tmout, &reply_tmout, 2); /* option - send to all, send one by one */
htts = mio_svc_htts_start(mio, &htts_bind_addr);
#if 1
{
@ -1077,6 +1085,7 @@ if (!mio_svc_dnc_resolve(dnc, "google.com", MIO_DNS_RRT_SOA, MIO_SVC_DNC_RESOLVE
mio_loop (mio);
/* TODO: let mio close it ... dnc is svc. sck is dev. */
if (htts) mio_svc_htts_stop (htts);
mio_svc_dnc_stop (dnc);
}

View File

@ -54,6 +54,7 @@ libmio_la_SOURCES = \
htrd.c \
htre.c \
http.c \
http-svr.c \
mio-prv.h \
mio.c \
nwif.c \

View File

@ -141,12 +141,12 @@ libmio_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
am_libmio_la_OBJECTS = libmio_la-chr.lo libmio_la-dns.lo \
libmio_la-dns-cli.lo libmio_la-ecs.lo libmio_la-err.lo \
libmio_la-fmt.lo libmio_la-htb.lo libmio_la-htrd.lo \
libmio_la-htre.lo libmio_la-http.lo libmio_la-mio.lo \
libmio_la-nwif.lo libmio_la-path.lo libmio_la-pro.lo \
libmio_la-sck.lo libmio_la-skad.lo libmio_la-sys.lo \
libmio_la-sys-ass.lo libmio_la-sys-err.lo libmio_la-sys-log.lo \
libmio_la-sys-mux.lo libmio_la-sys-tim.lo libmio_la-tmr.lo \
libmio_la-utf8.lo libmio_la-utl.lo
libmio_la-htre.lo libmio_la-http.lo libmio_la-http-svr.lo \
libmio_la-mio.lo libmio_la-nwif.lo libmio_la-path.lo \
libmio_la-pro.lo libmio_la-sck.lo libmio_la-skad.lo \
libmio_la-sys.lo libmio_la-sys-ass.lo libmio_la-sys-err.lo \
libmio_la-sys-log.lo libmio_la-sys-mux.lo libmio_la-sys-tim.lo \
libmio_la-tmr.lo libmio_la-utf8.lo libmio_la-utl.lo
libmio_la_OBJECTS = $(am_libmio_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -175,10 +175,12 @@ am__depfiles_remade = ./$(DEPDIR)/libmio_la-chr.Plo \
./$(DEPDIR)/libmio_la-dns.Plo ./$(DEPDIR)/libmio_la-ecs.Plo \
./$(DEPDIR)/libmio_la-err.Plo ./$(DEPDIR)/libmio_la-fmt.Plo \
./$(DEPDIR)/libmio_la-htb.Plo ./$(DEPDIR)/libmio_la-htrd.Plo \
./$(DEPDIR)/libmio_la-htre.Plo ./$(DEPDIR)/libmio_la-http.Plo \
./$(DEPDIR)/libmio_la-mio.Plo ./$(DEPDIR)/libmio_la-nwif.Plo \
./$(DEPDIR)/libmio_la-path.Plo ./$(DEPDIR)/libmio_la-pro.Plo \
./$(DEPDIR)/libmio_la-sck.Plo ./$(DEPDIR)/libmio_la-skad.Plo \
./$(DEPDIR)/libmio_la-htre.Plo \
./$(DEPDIR)/libmio_la-http-svr.Plo \
./$(DEPDIR)/libmio_la-http.Plo ./$(DEPDIR)/libmio_la-mio.Plo \
./$(DEPDIR)/libmio_la-nwif.Plo ./$(DEPDIR)/libmio_la-path.Plo \
./$(DEPDIR)/libmio_la-pro.Plo ./$(DEPDIR)/libmio_la-sck.Plo \
./$(DEPDIR)/libmio_la-skad.Plo \
./$(DEPDIR)/libmio_la-sys-ass.Plo \
./$(DEPDIR)/libmio_la-sys-err.Plo \
./$(DEPDIR)/libmio_la-sys-log.Plo \
@ -375,6 +377,7 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@ -436,6 +439,7 @@ libmio_la_SOURCES = \
htrd.c \
htre.c \
http.c \
http-svr.c \
mio-prv.h \
mio.c \
nwif.c \
@ -560,6 +564,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-htb.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-htrd.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-htre.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-http-svr.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-http.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-nwif.Plo@am__quote@ # am--include-marker
@ -677,6 +682,13 @@ libmio_la-http.lo: http.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-http.lo `test -f 'http.c' || echo '$(srcdir)/'`http.c
libmio_la-http-svr.lo: http-svr.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-http-svr.lo -MD -MP -MF $(DEPDIR)/libmio_la-http-svr.Tpo -c -o libmio_la-http-svr.lo `test -f 'http-svr.c' || echo '$(srcdir)/'`http-svr.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-http-svr.Tpo $(DEPDIR)/libmio_la-http-svr.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http-svr.c' object='libmio_la-http-svr.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-http-svr.lo `test -f 'http-svr.c' || echo '$(srcdir)/'`http-svr.c
libmio_la-mio.lo: mio.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-mio.lo -MD -MP -MF $(DEPDIR)/libmio_la-mio.Tpo -c -o libmio_la-mio.lo `test -f 'mio.c' || echo '$(srcdir)/'`mio.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-mio.Tpo $(DEPDIR)/libmio_la-mio.Plo
@ -946,6 +958,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libmio_la-htb.Plo
-rm -f ./$(DEPDIR)/libmio_la-htrd.Plo
-rm -f ./$(DEPDIR)/libmio_la-htre.Plo
-rm -f ./$(DEPDIR)/libmio_la-http-svr.Plo
-rm -f ./$(DEPDIR)/libmio_la-http.Plo
-rm -f ./$(DEPDIR)/libmio_la-mio.Plo
-rm -f ./$(DEPDIR)/libmio_la-nwif.Plo
@ -1017,6 +1030,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libmio_la-htb.Plo
-rm -f ./$(DEPDIR)/libmio_la-htrd.Plo
-rm -f ./$(DEPDIR)/libmio_la-htre.Plo
-rm -f ./$(DEPDIR)/libmio_la-http-svr.Plo
-rm -f ./$(DEPDIR)/libmio_la-http.Plo
-rm -f ./$(DEPDIR)/libmio_la-mio.Plo
-rm -f ./$(DEPDIR)/libmio_la-nwif.Plo

View File

@ -123,7 +123,7 @@ static mio_dns_msg_t* make_dns_msg (mio_svc_dnc_t* dnc, mio_dns_bhdr_t* bdns, mi
dnc_dns_msg_xtn_t* msgxtn;
msg = mio_dns_make_msg(dnc->mio, bdns, qr, qr_count, rr, rr_count, edns, MIO_SIZEOF(*msgxtn) + xtnsize);
if (!msg) return MIO_NULL;
if (MIO_UNLIKELY(!msg)) return MIO_NULL;
if (bdns->id < 0)
{
@ -720,10 +720,10 @@ mio_svc_dnc_t* mio_svc_dnc_start (mio_t* mio, const mio_skad_t* serv_addr, const
dnc_sck_xtn_t* sckxtn;
dnc = (mio_svc_dnc_t*)mio_callocmem(mio, MIO_SIZEOF(*dnc));
if (!dnc) goto oops;
if (MIO_UNLIKELY(!dnc)) goto oops;
dnc->mio = mio;
dnc->stop = mio_svc_dnc_stop;
dnc->svc_stop = mio_svc_dnc_stop;
dnc->serv_addr = *serv_addr;
dnc->send_tmout = *send_tmout;
dnc->reply_tmout = *reply_tmout;

228
mio/lib/http-svr.c Normal file
View File

@ -0,0 +1,228 @@
#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);
}

View File

@ -26,6 +26,7 @@
#define _MIO_HTTP_H_
#include <mio-ecs.h>
#include <mio-sck.h>
/** \file
* This file provides basic data types and functions for the http protocol.
@ -153,6 +154,11 @@ enum mio_perenchttpstr_opt_t
};
typedef enum mio_perenchttpstr_opt_t mio_perenchttpstr_opt_t;
/* -------------------------------------------------------------- */
typedef struct mio_svc_htts_t mio_svc_htts_t;
typedef struct mio_svc_httc_t mio_svc_httc_t;
#if defined(__cplusplus)
extern "C" {
#endif
@ -236,6 +242,19 @@ MIO_EXPORT mio_bch_t* mio_perenchttpstrdup (
mio_mmgr_t* mmgr
);
/* ------------------------------------------------------------------------- */
/* HTTP SERVER SERVICE */
/* ------------------------------------------------------------------------- */
MIO_EXPORT mio_svc_htts_t* mio_svc_htts_start (
mio_t* mio,
const mio_skad_t* bind_addr
);
MIO_EXPORT void mio_svc_htts_stop (
mio_svc_htts_t* htts
);
#if defined(__cplusplus)
}
#endif

View File

@ -184,10 +184,10 @@ void mio_fini (mio_t* mio)
mio_svc_t* svc;
svc = MIO_SVCL_FIRST_SVC(&mio->actsvc);
if (svc->stop)
if (svc->svc_stop)
{
/* the stop callback must unregister itself */
svc->stop (svc);
svc->svc_stop (svc);
}
else
{
@ -670,8 +670,8 @@ mio_dev_t* mio_dev_make (mio_t* mio, mio_oow_t dev_size, mio_dev_mth_t* dev_mth,
return MIO_NULL;
}
dev = mio_callocmem(mio, dev_size);
if (!dev) return MIO_NULL;
dev = (mio_dev_t*)mio_callocmem(mio, dev_size);
if (MIO_UNLIKELY(!dev)) return MIO_NULL;
dev->mio = mio;
dev->dev_size = dev_size;

View File

@ -426,7 +426,7 @@ typedef void (*mio_svc_stop_t) (mio_svc_t* svc);
#define MIO_SVC_HEADER \
mio_t* mio; \
mio_svc_stop_t stop; \
mio_svc_stop_t svc_stop; \
mio_svc_t* svc_prev; \
mio_svc_t* svc_next

View File

@ -1289,7 +1289,7 @@ accept_done:
* extension area as big as that of the master sck device
* is created in the client sck device */
clidev = (mio_dev_sck_t*)mio_dev_make(mio, rdev->dev_size, &dev_mth_clisck, rdev->dev_evcb, &clisck);
if (!clidev)
if (MIO_UNLIKELY(!clidev))
{
close (clisck);
return -1;
@ -1347,6 +1347,10 @@ accept_done:
clidev->on_write = rdev->on_write;
clidev->on_read = rdev->on_read;
/* inherit the contents of the extension area */
MIO_ASSERT (mio, rdev->dev_size == clidev->dev_size);
MIO_MEMCPY (mio_dev_sck_getxtn(clidev), mio_dev_sck_getxtn(rdev), rdev->dev_size - MIO_SIZEOF(mio_dev_sck_t));
MIO_ASSERT (mio, clidev->tmrjob_index == MIO_TMRIDX_INVALID);
if (rdev->ssl_ctx)