working on http server
This commit is contained in:
		| @ -100,7 +100,7 @@ static MIO_INLINE int push_content (mio_htrd_t* htrd, const mio_bch_t* ptr, mio_ | |||||||
| { | { | ||||||
| 	MIO_ASSERT (htrd->mio, len > 0); | 	MIO_ASSERT (htrd->mio, len > 0); | ||||||
|  |  | ||||||
| 	if (htrd->recbs->push_content) return htrd->recbs->push_content(htrd, &htrd->re, ptr, len); | 	if (htrd->recbs.push_content) return htrd->recbs.push_content(htrd, &htrd->re, ptr, len); | ||||||
|  |  | ||||||
| 	if (mio_htre_addcontent(&htrd->re, ptr, len) <= -1)  | 	if (mio_htre_addcontent(&htrd->re, ptr, len) <= -1)  | ||||||
| 	{ | 	{ | ||||||
| @ -497,12 +497,12 @@ void mio_htrd_setopt (mio_htrd_t* htrd, int opts) | |||||||
|  |  | ||||||
| const mio_htrd_recbs_t* mio_htrd_getrecbs (mio_htrd_t* htrd) | const mio_htrd_recbs_t* mio_htrd_getrecbs (mio_htrd_t* htrd) | ||||||
| { | { | ||||||
| 	return htrd->recbs; | 	return &htrd->recbs; | ||||||
| } | } | ||||||
|  |  | ||||||
| void mio_htrd_setrecbs (mio_htrd_t* htrd, const mio_htrd_recbs_t* recbs) | void mio_htrd_setrecbs (mio_htrd_t* htrd, const mio_htrd_recbs_t* recbs) | ||||||
| { | { | ||||||
| 	htrd->recbs = recbs; | 	htrd->recbs = *recbs; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int capture_connection (mio_htrd_t* htrd, mio_htb_pair_t* pair) | static int capture_connection (mio_htrd_t* htrd, mio_htb_pair_t* pair) | ||||||
| @ -556,7 +556,7 @@ static int capture_content_length (mio_htrd_t* htrd, mio_htb_pair_t* pair) | |||||||
| 	ptr = val->ptr; | 	ptr = val->ptr; | ||||||
| 	while (off < val->len) | 	while (off < val->len) | ||||||
| 	{ | 	{ | ||||||
| 		int num = digit_to_num (ptr[off]); | 		int num = digit_to_num(ptr[off]); | ||||||
| 		if (num <= -1) | 		if (num <= -1) | ||||||
| 		{ | 		{ | ||||||
| 			/* the length contains a non-digit */ | 			/* the length contains a non-digit */ | ||||||
| @ -1024,8 +1024,7 @@ static const mio_bch_t* getchunklen (mio_htrd_t* htrd, const mio_bch_t* ptr, mio | |||||||
| 	return ptr; | 	return ptr; | ||||||
| } | } | ||||||
|  |  | ||||||
| static const mio_bch_t* get_trailing_headers ( | static const mio_bch_t* get_trailing_headers (mio_htrd_t* htrd, const mio_bch_t* req, const mio_bch_t* end) | ||||||
| 	mio_htrd_t* htrd, const mio_bch_t* req, const mio_bch_t* end) |  | ||||||
| { | { | ||||||
| 	const mio_bch_t* ptr = req; | 	const mio_bch_t* ptr = req; | ||||||
|  |  | ||||||
| @ -1053,12 +1052,8 @@ static const mio_bch_t* get_trailing_headers ( | |||||||
| 					MIO_ASSERT (htrd->mio, htrd->fed.s.crlf <= 3); | 					MIO_ASSERT (htrd->mio, htrd->fed.s.crlf <= 3); | ||||||
| 					htrd->fed.s.crlf = 0; | 					htrd->fed.s.crlf = 0; | ||||||
|  |  | ||||||
| 					if (push_to_buffer ( | 					if (push_to_buffer(htrd, &htrd->fed.b.tra, req, ptr - req) <= -1 || | ||||||
| 						htrd, &htrd->fed.b.tra, req, ptr - req) <= -1) | 					    push_to_buffer(htrd, &htrd->fed.b.tra, &NUL, 1) <= -1) return MIO_NULL; | ||||||
| 						return MIO_NULL; |  | ||||||
| 					if (push_to_buffer ( |  | ||||||
| 						htrd, &htrd->fed.b.tra, &NUL, 1) <= -1)  |  | ||||||
| 						return MIO_NULL; |  | ||||||
|  |  | ||||||
| 					p = MIO_BECS_PTR(&htrd->fed.b.tra); | 					p = MIO_BECS_PTR(&htrd->fed.b.tra); | ||||||
|  |  | ||||||
| @ -1070,11 +1065,8 @@ static const mio_bch_t* get_trailing_headers ( | |||||||
| 						/* TODO: return error if protocol is 0.9. | 						/* TODO: return error if protocol is 0.9. | ||||||
| 						 * HTTP/0.9 must not get headers... */ | 						 * HTTP/0.9 must not get headers... */ | ||||||
|  |  | ||||||
| 						p = parse_header_field ( | 						p = parse_header_field(htrd, p, ((htrd->option & MIO_HTRD_TRAILERS)? &htrd->re.trailers: &htrd->re.hdrtab)); | ||||||
| 							htrd, p,  | 						if (MIO_UNLIKELY(!p)) return MIO_NULL; | ||||||
| 							((htrd->option & MIO_HTRD_TRAILERS)? &htrd->re.trailers: &htrd->re.hdrtab) |  | ||||||
| 						); |  | ||||||
| 						if (p == MIO_NULL) return MIO_NULL; |  | ||||||
| 					} | 					} | ||||||
| 					while (1); | 					while (1); | ||||||
|  |  | ||||||
| @ -1212,7 +1204,7 @@ int mio_htrd_feed (mio_htrd_t* htrd, const mio_bch_t* req, mio_oow_t len, mio_oo | |||||||
| 					header_completed_during_this_feed = 1; | 					header_completed_during_this_feed = 1; | ||||||
|  |  | ||||||
| //////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
| 					if (htrd->recbs->peek(htrd, &htrd->re) <= -1) | 					if (htrd->recbs.peek(htrd, &htrd->re) <= -1) | ||||||
| 					{ | 					{ | ||||||
| 						/* need to clear request on error?  | 						/* need to clear request on error?  | ||||||
| 						clear_feed (htrd); */ | 						clear_feed (htrd); */ | ||||||
| @ -1455,7 +1447,7 @@ XXXXXXXX | |||||||
| 					mio_htre_completecontent (&htrd->re); | 					mio_htre_completecontent (&htrd->re); | ||||||
|  |  | ||||||
| #if 0 // XXXX | #if 0 // XXXX | ||||||
| 					if (header_completed_during_this_feed && htrd->recbs->peek) | 					if (header_completed_during_this_feed && htrd->recbs.peek) | ||||||
| 					{ | 					{ | ||||||
| 						/* the peek handler has not been executed. | 						/* the peek handler has not been executed. | ||||||
| 						 * this can happen if this function is fed with | 						 * this can happen if this function is fed with | ||||||
| @ -1463,12 +1455,9 @@ XXXXXXXX | |||||||
| 						 * plus complete content body and the header  | 						 * plus complete content body and the header  | ||||||
| 						 * of the next request. */ | 						 * of the next request. */ | ||||||
| 						int n; | 						int n; | ||||||
| 						htrd->errnum = MIO_HTRD_ENOERR; | 						n = htrd->recbs.peek(htrd, &htrd->re); | ||||||
| 						n = htrd->recbs->peek(htrd, &htrd->re); |  | ||||||
| 						if (n <= -1) | 						if (n <= -1) | ||||||
| 						{ | 						{ | ||||||
| 							if (htrd->errnum == MIO_HTRD_ENOERR) |  | ||||||
| 								htrd->errnum = MIO_HTRD_ERECBS; |  | ||||||
| 							/* need to clear request on error?  | 							/* need to clear request on error?  | ||||||
| 							clear_feed (htrd); */ | 							clear_feed (htrd); */ | ||||||
| 							return -1; | 							return -1; | ||||||
| @ -1478,15 +1467,12 @@ XXXXXXXX | |||||||
| 					} | 					} | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| 					if (htrd->recbs->poke) | 					if (htrd->recbs.poke) | ||||||
| 					{ | 					{ | ||||||
| 						int n; | 						int n; | ||||||
| 						htrd->errnum = MIO_HTRD_ENOERR; | 						n = htrd->recbs.poke(htrd, &htrd->re); | ||||||
| 						n = htrd->recbs->poke(htrd, &htrd->re); |  | ||||||
| 						if (n <= -1) | 						if (n <= -1) | ||||||
| 						{ | 						{ | ||||||
| 							if (htrd->errnum == MIO_HTRD_ENOERR) |  | ||||||
| 								htrd->errnum = MIO_HTRD_ERECBS; |  | ||||||
| 							/* need to clear request on error?  | 							/* need to clear request on error?  | ||||||
| 							clear_feed (htrd); */ | 							clear_feed (htrd); */ | ||||||
| 							return -1; | 							return -1; | ||||||
| @ -1565,15 +1551,12 @@ mio_printf (MIO_T("CONTENT_LENGTH %d, RAW HEADER LENGTH %d\n"), | |||||||
|  |  | ||||||
| feedme_more: | feedme_more: | ||||||
| #if 0 //XXXX | #if 0 //XXXX | ||||||
| 	if (header_completed_during_this_feed && htrd->recbs->peek) | 	if (header_completed_during_this_feed && htrd->recbs.peek) | ||||||
| 	{ | 	{ | ||||||
| 		int n; | 		int n; | ||||||
| 		htrd->errnum = MIO_HTRD_ENOERR; | 		n = htrd->recbs.peek(htrd, &htrd->re); | ||||||
| 		n = htrd->recbs->peek(htrd, &htrd->re); |  | ||||||
| 		if (n <= -1) | 		if (n <= -1) | ||||||
| 		{ | 		{ | ||||||
| 			if (htrd->errnum == MIO_HTRD_ENOERR) |  | ||||||
| 				htrd->errnum = MIO_HTRD_ERECBS; |  | ||||||
| 			/* need to clear request on error?  | 			/* need to clear request on error?  | ||||||
| 			clear_feed (htrd); */ | 			clear_feed (htrd); */ | ||||||
| 			return -1; | 			return -1; | ||||||
| @ -1591,15 +1574,12 @@ int mio_htrd_halt (mio_htrd_t* htrd) | |||||||
| 	{ | 	{ | ||||||
| 		mio_htre_completecontent (&htrd->re); | 		mio_htre_completecontent (&htrd->re); | ||||||
|  |  | ||||||
| 		if (htrd->recbs->poke) | 		if (htrd->recbs.poke) | ||||||
| 		{ | 		{ | ||||||
| 			int n; | 			int n; | ||||||
| 			htrd->errnum = MIO_HTRD_ENOERR; | 			n = htrd->recbs.poke(htrd, &htrd->re); | ||||||
| 			n = htrd->recbs->poke (htrd, &htrd->re); |  | ||||||
| 			if (n <= -1) | 			if (n <= -1) | ||||||
| 			{ | 			{ | ||||||
| 				if (htrd->errnum == MIO_HTRD_ENOERR) |  | ||||||
| 					htrd->errnum = MIO_HTRD_ERECBS; |  | ||||||
| 				/* need to clear request on error?  | 				/* need to clear request on error?  | ||||||
| 				clear_feed (htrd); */ | 				clear_feed (htrd); */ | ||||||
| 				return -1; | 				return -1; | ||||||
| @ -1680,15 +1660,9 @@ int mio_htrd_scanqparam (mio_htrd_t* htrd, const mio_bcs_t* cstr) | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			/* set request parameter string callback before scanning */ | 			/* set request parameter string callback before scanning */ | ||||||
| 			MIO_ASSERT (htrd->mio, htrd->recbs->qparamstr != MIO_NULL); | 			MIO_ASSERT (htrd->mio, htrd->recbs.qparamstr != MIO_NULL); | ||||||
|  |  | ||||||
| 			htrd->errnum = MIO_HTRD_ENOERR; | 			if (htrd->recbs.qparamstr(htrd, &key, &val) <= -1) return -1; | ||||||
| 			if (htrd->recbs->qparamstr(htrd, &key, &val) <= -1)  |  | ||||||
| 			{ |  | ||||||
| 				if (htrd->errnum == MIO_HTRD_ENOERR) |  | ||||||
| 					htrd->errnum = MIO_HTRD_ERECBS;	 |  | ||||||
| 				return -1; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 		next_octet: | 		next_octet: | ||||||
| 			if (p >= end) break; | 			if (p >= end) break; | ||||||
|  | |||||||
| @ -758,17 +758,24 @@ static void cgi_state_halt (cgi_state_t* cgi_state) | |||||||
| /* TODO: when to destroy cgi_state? */ | /* TODO: when to destroy cgi_state? */ | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static void cgi_state_on_kill (cgi_state_t* cgi_state) | static void cgi_state_on_kill (cgi_state_t* cgi_state) | ||||||
| { | { | ||||||
| printf ("**** CGI_STATE_ON_KILL \n"); | printf ("**** CGI_STATE_ON_KILL \n"); | ||||||
| 	if (cgi_state->peer) | 	if (cgi_state->peer) | ||||||
| 	{ | 	{ | ||||||
|  | 		cgi_peer_xtn_t* cgi_peer = mio_dev_pro_getxtn(cgi_state->peer); | ||||||
|  | 		cgi_peer->state = MIO_NULL; | ||||||
|  |  | ||||||
| 		mio_dev_pro_kill (cgi_state->peer); | 		mio_dev_pro_kill (cgi_state->peer); | ||||||
| 		cgi_state->peer = MIO_NULL; | 		cgi_state->peer = MIO_NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (cgi_state->peer_htrd) | 	if (cgi_state->peer_htrd) | ||||||
| 	{ | 	{ | ||||||
|  | 		cgi_peer_xtn_t* cgi_peer = mio_htrd_getxtn(cgi_state->peer_htrd); | ||||||
|  | 		cgi_peer->state = MIO_NULL; | ||||||
|  |  | ||||||
| 		mio_htrd_close (cgi_state->peer_htrd); | 		mio_htrd_close (cgi_state->peer_htrd); | ||||||
| 		cgi_state->peer_htrd = MIO_NULL; | 		cgi_state->peer_htrd = MIO_NULL; | ||||||
| 	} | 	} | ||||||
| @ -785,6 +792,8 @@ printf ("**** CGI_STATE_ON_KILL \n"); | |||||||
| 		cgi_state->cli_org_on_write = MIO_NULL; | 		cgi_state->cli_org_on_write = MIO_NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	cgi_state->cli->htrd->recbs.push_content = MIO_NULL; | ||||||
|  |  | ||||||
| 	if (MIO_BECS_LEN(&cgi_state->cli->rbuf) > 0) | 	if (MIO_BECS_LEN(&cgi_state->cli->rbuf) > 0) | ||||||
| 	{ | 	{ | ||||||
| 		mio_svc_htts_cli_t* cli = cgi_state->cli; | 		mio_svc_htts_cli_t* cli = cgi_state->cli; | ||||||
| @ -797,13 +806,33 @@ printf ("**** CGI_STATE_ON_KILL \n"); | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int cgi_send_simple_status_to_client (cgi_state_t* cgi_state, int status_code) | ||||||
|  | { | ||||||
|  | 	mio_svc_htts_cli_t* cli = cgi_state->cli; | ||||||
|  | 	mio_bch_t dtbuf[64]; | ||||||
|  |  | ||||||
|  | 	mio_svc_htts_fmtgmtime (cli->htts, MIO_NULL, dtbuf, MIO_COUNTOF(dtbuf)); | ||||||
|  |  | ||||||
|  | 	if (mio_becs_fmt(cli->sbuf, "HTTP/%d.%d %d %hs\r\nServer: %hs\r\nDate: %s\r\nConnection: close\r\nContent-Length: 0\r\n\r\n", | ||||||
|  | 		cgi_state->req_version.major, cgi_state->req_version.minor, | ||||||
|  | 		status_code, mio_http_status_to_bcstr(status_code), | ||||||
|  | 		cli->htts->server_name, dtbuf) == (mio_oow_t)-1) return -1; | ||||||
|  |  | ||||||
|  | 	return mio_dev_sck_write(cli->sck, MIO_BECS_PTR(cli->sbuf), MIO_BECS_LEN(cli->sbuf), MIO_NULL, MIO_NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
| static void cgi_peer_on_close (mio_dev_pro_t* pro, mio_dev_pro_sid_t sid) | static void cgi_peer_on_close (mio_dev_pro_t* pro, mio_dev_pro_sid_t sid) | ||||||
| { | { | ||||||
| 	mio_t* mio = pro->mio; | 	mio_t* mio = pro->mio; | ||||||
| 	cgi_peer_xtn_t* cgi_peer = mio_dev_pro_getxtn(pro); | 	cgi_peer_xtn_t* cgi_peer = mio_dev_pro_getxtn(pro); | ||||||
| 	cgi_state_t* cgi_state = cgi_peer->state; | 	cgi_state_t* cgi_state = cgi_peer->state; | ||||||
|  |  | ||||||
| 	MIO_ASSERT (mio, cgi_state->peer == pro); | 	if (!cgi_state) return; /* cgi state already gone */ | ||||||
|  |  | ||||||
|  | printf (">> cgi_state %p\n", cgi_state); | ||||||
|  | printf (">> cgi_state->peer %p\n", cgi_state->peer); | ||||||
|  | printf (">> cgi_state->cli %p\n", cgi_state->cli); | ||||||
|  | printf (">> cgi_state->cli->htts %p\n", cgi_state->cli->htts); | ||||||
|  |  | ||||||
| 	if (sid == MIO_DEV_PRO_MASTER) | 	if (sid == MIO_DEV_PRO_MASTER) | ||||||
| 	{ | 	{ | ||||||
| @ -812,6 +841,8 @@ static void cgi_peer_on_close (mio_dev_pro_t* pro, mio_dev_pro_sid_t sid) | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
|  | 		MIO_ASSERT (mio, cgi_state->peer == pro); | ||||||
|  |  | ||||||
| 		MIO_DEBUG4 (mio, "HTTS(%p) - peer %p(pid=%d) closing slave[%d]\n", cgi_state->cli->htts, pro, (int)pro->child_pid, sid); | 		MIO_DEBUG4 (mio, "HTTS(%p) - peer %p(pid=%d) closing slave[%d]\n", cgi_state->cli->htts, pro, (int)pro->child_pid, sid); | ||||||
| 		if (sid == MIO_DEV_PRO_OUT) | 		if (sid == MIO_DEV_PRO_OUT) | ||||||
| 		{ | 		{ | ||||||
| @ -852,6 +883,7 @@ printf ( "QQQQQQQQQQQQQQQQQQ>>>>>>>>>>>>>>>>>> feeding to peer htrd.... dlen => | |||||||
| 		if (mio_htrd_feed(cgi_state->peer_htrd, data, dlen, &rem) <= -1)  | 		if (mio_htrd_feed(cgi_state->peer_htrd, data, dlen, &rem) <= -1)  | ||||||
| 		{ | 		{ | ||||||
| printf ( "FEEDING FAILURE TO PEER HTDDRD.. dlen => %d\n", (int)dlen); | printf ( "FEEDING FAILURE TO PEER HTDDRD.. dlen => %d\n", (int)dlen); | ||||||
|  | 			cgi_send_simple_status_to_client (cgi_state, 500); /* don't care about error */ | ||||||
| 			goto oops; | 			goto oops; | ||||||
| 		} | 		} | ||||||
| 		if (rem > 0)  | 		if (rem > 0)  | ||||||
| @ -877,7 +909,8 @@ static int cgi_peer_capture_header (mio_htre_t* req, const mio_bch_t* key, const | |||||||
| 	if (mio_comp_bcstr(key, "Status", 1) != 0 && | 	if (mio_comp_bcstr(key, "Status", 1) != 0 && | ||||||
| 	    mio_comp_bcstr(key, "Connection", 1) != 0 && | 	    mio_comp_bcstr(key, "Connection", 1) != 0 && | ||||||
| 	    mio_comp_bcstr(key, "Transfer-Encoding", 1) != 0 && | 	    mio_comp_bcstr(key, "Transfer-Encoding", 1) != 0 && | ||||||
| 	    mio_comp_bcstr(key, "Server", 1) != 0) | 	    mio_comp_bcstr(key, "Server", 1) != 0 && | ||||||
|  | 	    mio_comp_bcstr(key, "Date", 1) != 0) | ||||||
| 	{ | 	{ | ||||||
| 		do | 		do | ||||||
| 		{ | 		{ | ||||||
| @ -901,6 +934,7 @@ static int cgi_peer_htrd_peek (mio_htrd_t* htrd, mio_htre_t* req) | |||||||
| 	cgi_peer_xtn_t* cgi_peer = mio_htrd_getxtn(htrd); | 	cgi_peer_xtn_t* cgi_peer = mio_htrd_getxtn(htrd); | ||||||
| 	cgi_state_t* cgi_state = cgi_peer->state; | 	cgi_state_t* cgi_state = cgi_peer->state; | ||||||
| 	mio_svc_htts_cli_t* cli = cgi_state->cli; | 	mio_svc_htts_cli_t* cli = cgi_state->cli; | ||||||
|  | 	mio_bch_t dtbuf[64]; | ||||||
| 	int status_code; | 	int status_code; | ||||||
|  |  | ||||||
| 	if (req->attr.content_length) | 	if (req->attr.content_length) | ||||||
| @ -919,9 +953,12 @@ static int cgi_peer_htrd_peek (mio_htrd_t* htrd, mio_htre_t* req) | |||||||
| 	status_code = 200; | 	status_code = 200; | ||||||
|  |  | ||||||
| printf ("CGI PEER HTRD PEEK...\n"); | printf ("CGI PEER HTRD PEEK...\n"); | ||||||
| 	if (mio_becs_fmt(cli->sbuf, "HTTP/%d.%d %d %hs\r\n", | 	mio_svc_htts_fmtgmtime (cli->htts, MIO_NULL, dtbuf, MIO_COUNTOF(dtbuf)); | ||||||
|  |  | ||||||
|  | 	if (mio_becs_fmt(cli->sbuf, "HTTP/%d.%d %d %hs\r\nServer: %hs\r\nDate: %hs\r\n", | ||||||
| 		cgi_state->req_version.major, cgi_state->req_version.minor, | 		cgi_state->req_version.major, cgi_state->req_version.minor, | ||||||
| 		status_code, mio_http_status_to_bcstr(status_code)) == (mio_oow_t)-1) return -1; | 		status_code, mio_http_status_to_bcstr(status_code), | ||||||
|  | 		cli->htts->server_name, dtbuf) == (mio_oow_t)-1) return -1; | ||||||
|  |  | ||||||
| 	if (mio_htre_walkheaders(req, cgi_peer_capture_header, cli) <= -1) return -1; | 	if (mio_htre_walkheaders(req, cgi_peer_capture_header, cli) <= -1) return -1; | ||||||
|  |  | ||||||
| @ -961,7 +998,7 @@ static int cgi_peer_htrd_push_content (mio_htrd_t* htrd, mio_htre_t* req, const | |||||||
| 			mio_bch_t lbuf[16]; | 			mio_bch_t lbuf[16]; | ||||||
| 			mio_oow_t llen; | 			mio_oow_t llen; | ||||||
|  |  | ||||||
| 			llen = mio_fmt_uintmax_to_bcstr(lbuf, MIO_COUNTOF(lbuf) - 2, dlen, 16, 0, '\0', MIO_NULL); | 			llen = mio_fmt_uintmax_to_bcstr(lbuf, MIO_COUNTOF(lbuf) - 2, dlen, 16 | MIO_FMT_UINTMAX_UPPERCASE, 0, '\0', MIO_NULL); | ||||||
| 			lbuf[llen++] = '\r'; | 			lbuf[llen++] = '\r'; | ||||||
| 			lbuf[llen++] = '\n'; | 			lbuf[llen++] = '\n'; | ||||||
|  |  | ||||||
| @ -1009,6 +1046,35 @@ static mio_htrd_recbs_t cgi_peer_htrd_recbs = | |||||||
| 	cgi_peer_htrd_push_content | 	cgi_peer_htrd_push_content | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | static int cgi_client_htrd_push_content (mio_htrd_t* htrd, mio_htre_t* req, const mio_bch_t* data, mio_oow_t dlen) | ||||||
|  | { | ||||||
|  | 	htrd_xtn_t* htrdxtn = mio_htrd_getxtn(htrd); | ||||||
|  | 	mio_dev_sck_t* sck = htrdxtn->sck; | ||||||
|  | 	mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); | ||||||
|  | 	cgi_state_t* cgi_state = RSRCL_FIRST_RSRC(&cli->rsrc); | ||||||
|  |  | ||||||
|  | 	MIO_ASSERT (sck->mio, cli->sck == sck); | ||||||
|  |  | ||||||
|  | 	cgi_state->num_pending_writes_to_peer++; | ||||||
|  | 	if (mio_dev_pro_write(cgi_state->peer, data, dlen, MIO_NULL) <= -1)  | ||||||
|  | 	{ | ||||||
|  | 		cgi_state->num_pending_writes_to_peer--; | ||||||
|  | 		goto oops; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
|  | 	if (cgi_state->num_pending_writes_to_peer > CGI_STATE_PENDING_IO_THRESHOLD) | ||||||
|  | 	{ | ||||||
|  | 		if (mio_dev_sck_read(cli->sck, 0) <= -1) goto oops; /* disable input watching */ | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  |  | ||||||
|  | oops: | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
| static int cgi_peer_on_write (mio_dev_pro_t* pro, mio_iolen_t wrlen, void* wrctx) | static int cgi_peer_on_write (mio_dev_pro_t* pro, mio_iolen_t wrlen, void* wrctx) | ||||||
| { | { | ||||||
| 	mio_t* mio = pro->mio; | 	mio_t* mio = pro->mio; | ||||||
| @ -1026,7 +1092,8 @@ static int cgi_peer_on_write (mio_dev_pro_t* pro, mio_iolen_t wrlen, void* wrctx | |||||||
| 	cgi_state->num_pending_writes_to_peer--; | 	cgi_state->num_pending_writes_to_peer--; | ||||||
| 	if (cgi_state->num_pending_writes_to_peer == CGI_STATE_PENDING_IO_THRESHOLD) | 	if (cgi_state->num_pending_writes_to_peer == CGI_STATE_PENDING_IO_THRESHOLD) | ||||||
| 	{ | 	{ | ||||||
| 		if (mio_dev_sck_read(cgi_state->cli->sck, 0) <= -1) goto oops; | 		// TODO: check if (cli has anything to read...) if so ... | ||||||
|  | 		if (mio_dev_sck_read(cgi_state->cli->sck, 1) <= -1) goto oops; | ||||||
| 	} | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
| @ -1062,28 +1129,22 @@ printf ("** HTTS - cgi client read   %p  %d -> htts:%p\n", sck, (int)len, cli->h | |||||||
| 	if (len == 0) | 	if (len == 0) | ||||||
| 	{ | 	{ | ||||||
| 		/* EOF on the client side. arrange to close */ | 		/* EOF on the client side. arrange to close */ | ||||||
|  | printf ("asking pro to close...\n"); | ||||||
| 		if (mio_dev_pro_write(cgi_state->peer, MIO_NULL, 0, MIO_NULL) <= -1) goto oops; | 		if (mio_dev_pro_write(cgi_state->peer, MIO_NULL, 0, MIO_NULL) <= -1) goto oops; | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| #if 0 |  | ||||||
| 		mio_oow_t rem; | 		mio_oow_t rem; | ||||||
| 		if (mio_htrd_feed(cli->htrd, buf, len, &rem) <= -1) goto oops; | /* EOF if it got content as long as cgi_state->req_content_length??? */ | ||||||
| 		if (rem > 0) | 		if (mio_htrd_feed(cli->htrd, buf, len, &rem) <= -1) | ||||||
| 		{ | 		{ | ||||||
| 			/* TODO: there is left-over data */ | printf ("FAILED TO FEED TH CLIENT HTRD......\n"); | ||||||
| 		} |  | ||||||
| #endif |  | ||||||
| 		cgi_state->num_pending_writes_to_peer++; |  | ||||||
| 		if (mio_dev_pro_write(cgi_state->peer, buf, len, MIO_NULL) <= -1)  |  | ||||||
| 		{ |  | ||||||
| 			cgi_state->num_pending_writes_to_peer--; |  | ||||||
| 			goto oops; | 			goto oops; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (cgi_state->num_pending_writes_to_peer > CGI_STATE_PENDING_IO_THRESHOLD) | 		if (rem > 0) | ||||||
| 		{ | 		{ | ||||||
| 			if (mio_dev_sck_read(sck, 0) <= -1) goto oops; /* disable input watching */ | /* giving excessive data... */ | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -1111,6 +1172,7 @@ printf ("MANAGED TO WRITE TO CLIENT>... %d\n", (int)wrlen); | |||||||
| 	cgi_state->num_pending_writes_to_client--; | 	cgi_state->num_pending_writes_to_client--; | ||||||
| 	if (cgi_state->peer && cgi_state->num_pending_writes_to_client == CGI_STATE_PENDING_IO_THRESHOLD) | 	if (cgi_state->peer && cgi_state->num_pending_writes_to_client == CGI_STATE_PENDING_IO_THRESHOLD) | ||||||
| 	{ | 	{ | ||||||
|  | 		// TODO: check if there is anything to read... */ | ||||||
| 		if (mio_dev_pro_read(cgi_state->peer, MIO_DEV_PRO_OUT, 1) <= -1) goto oops; | 		if (mio_dev_pro_read(cgi_state->peer, MIO_DEV_PRO_OUT, 1) <= -1) goto oops; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -1243,8 +1305,12 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r | |||||||
| 			 *  corresponding request, or if the framing indicates that there is | 			 *  corresponding request, or if the framing indicates that there is | ||||||
| 			 *  no message body. | 			 *  no message body. | ||||||
| 			 */ | 			 */ | ||||||
|  | 			mio_bch_t msgbuf[64]; | ||||||
|  | 			mio_oow_t msglen; | ||||||
|  |  | ||||||
|  | 			msglen = mio_fmttobcstr(mio, msgbuf, MIO_COUNTOF(msgbuf), "HTTP/%d.%d 100 Continue\r\n\r\n", cgi_state->req_version.major, cgi_state->req_version.minor); | ||||||
| 			cgi_state->num_pending_writes_to_client++; | 			cgi_state->num_pending_writes_to_client++; | ||||||
| 			if (mio_dev_sck_write(csck, "HTTP/1.1 100 Continue\r\n", 23, MIO_NULL, MIO_NULL) <= -1) | 			if (mio_dev_sck_write(csck, msgbuf, msglen, MIO_NULL, MIO_NULL) <= -1) | ||||||
| 			{ | 			{ | ||||||
| 				cgi_state->num_pending_writes_to_client--; | 				cgi_state->num_pending_writes_to_client--; | ||||||
| 				goto oops; | 				goto oops; | ||||||
| @ -1262,6 +1328,7 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r | |||||||
| 	{ | 	{ | ||||||
| 		if (mio_htre_getcontentlen(req) > 0) | 		if (mio_htre_getcontentlen(req) > 0) | ||||||
| 		{ | 		{ | ||||||
|  | 			/* this means that it's called from the peek context */ | ||||||
| 			cgi_state->num_pending_writes_to_peer++; | 			cgi_state->num_pending_writes_to_peer++; | ||||||
| 			if (mio_dev_pro_write(cgi_state->peer, mio_htre_getcontentptr(req), mio_htre_getcontentlen(req), MIO_NULL) <= -1)  | 			if (mio_dev_pro_write(cgi_state->peer, mio_htre_getcontentptr(req), mio_htre_getcontentlen(req), MIO_NULL) <= -1)  | ||||||
| 			{ | 			{ | ||||||
| @ -1276,6 +1343,13 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r | |||||||
| 		/* disable input watching from the client */ | 		/* disable input watching from the client */ | ||||||
| 		if (mio_dev_sck_read(csck, 0) <= -1) goto oops; | 		if (mio_dev_sck_read(csck, 0) <= -1) goto oops; | ||||||
| 	} | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		if (req_content_length > 0) | ||||||
|  | 		{ | ||||||
|  | 			cgi_state->cli->htrd->recbs.push_content = cgi_client_htrd_push_content; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	/* this may change later if Content-Length is included in the cgi output */ | 	/* this may change later if Content-Length is included in the cgi output */ | ||||||
| 	cgi_state->res_mode_to_cli = (req->flags & MIO_HTRE_ATTR_KEEPALIVE)? CGI_STATE_RES_MODE_CHUNKED: CGI_STATE_RES_MODE_CLOSE; | 	cgi_state->res_mode_to_cli = (req->flags & MIO_HTRE_ATTR_KEEPALIVE)? CGI_STATE_RES_MODE_CHUNKED: CGI_STATE_RES_MODE_CLOSE; | ||||||
|  | |||||||
| @ -41,8 +41,6 @@ enum mio_htrd_errnum_t | |||||||
| 	MIO_HTRD_ENOMEM, | 	MIO_HTRD_ENOMEM, | ||||||
| 	MIO_HTRD_EBADRE, | 	MIO_HTRD_EBADRE, | ||||||
| 	MIO_HTRD_EBADHDR, | 	MIO_HTRD_EBADHDR, | ||||||
| 	MIO_HTRD_ERECBS, |  | ||||||
| 	MIO_HTRD_ECONCB, |  | ||||||
| 	MIO_HTRD_ESUSPENDED | 	MIO_HTRD_ESUSPENDED | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -82,7 +80,7 @@ struct mio_htrd_t | |||||||
| 	int option; | 	int option; | ||||||
| 	int flags; | 	int flags; | ||||||
|  |  | ||||||
| 	const mio_htrd_recbs_t* recbs; | 	mio_htrd_recbs_t recbs; | ||||||
|  |  | ||||||
| 	struct | 	struct | ||||||
| 	{ | 	{ | ||||||
|  | |||||||
| @ -362,6 +362,14 @@ MIO_EXPORT void mio_svc_htts_rsrc_kill ( | |||||||
| 	mio_svc_htts_rsrc_t*         rsrc | 	mio_svc_htts_rsrc_t*         rsrc | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | MIO_EXPORT void mio_svc_htts_fmtgmtime ( | ||||||
|  | 	mio_svc_htts_t*    htts,  | ||||||
|  | 	const mio_ntime_t* nt, | ||||||
|  | 	mio_bch_t*         buf, | ||||||
|  | 	mio_oow_t          len | ||||||
|  | ); | ||||||
|  |  | ||||||
| #if defined(__cplusplus) | #if defined(__cplusplus) | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user