📄 httpd.c
字号:
if ((conn->servlet == NULL) || (conn->session == NULL))
return -1;
hsl_printf(slobj, "<input type=\"hidden\" name=\"" HTTP_SESSIONIDNAME
"\" value=\"%08x\">\n", conn->session->id);
return 0;
}
/* create a new link container
*/
sint_t hsl_linkCreate(SERVLET_t *slobj, const char* url, u32_t flags)
{
HTTPCONN_t *conn = (HTTPCONN_t*) slobj;
char *u, *d;
if (conn == NULL)
return -1;
if (conn->servlet == NULL)
return -1;
u = (char*) url;
d = conn->linkbuf;
if (u == NULL)
{
u = conn->servlet->filename;
if (*u != '/')
*d++ = '/';
}
if ((sysStrlen(u) + 1 + 1 + HTTP_MAXSIDLENGTH) > HTTP_MAXSTRLEN)
return -1;
sysStrcpy(d, u);
conn->linkflags = flags;
if (((flags & HSL_LINK_SID) != 0) && (conn->session != NULL))
{
sprintf(conn->linkbuf + sysStrlen(conn->linkbuf),
"?" HTTP_SESSIONIDNAME "=%08x", conn->session->id);
}
else
{
conn->linkflags |= HSL_LINK_QM;
}
return 0;
}
/* add a string value to the parameter list of a link
*/
sint_t hsl_linkAddStringVal(SERVLET_t *slobj, const char *name,
const char* val)
{
HTTPCONN_t *conn = (HTTPCONN_t*) slobj;
sint_t i;
if ((conn == NULL) || (name == NULL) || (val == NULL))
return -1;
if ((sysStrlen(conn->linkbuf) + sysStrlen(name) + sysStrlen(val) + 2) >
HTTP_MAXSTRLEN)
return -1;
i = sysStrlen(conn->linkbuf);
if (i == 0)
return -1;
if (conn->linkbuf[i-1] != '&')
{
conn->linkbuf[i] = (conn->linkflags & HSL_LINK_QM) ? '?' : '&';
conn->linkbuf[i+1] = 0;
conn->linkflags &= ~HSL_LINK_QM;
}
sysStrcat(conn->linkbuf, name);
sysStrcat(conn->linkbuf, "=");
i = sysStrlen(conn->linkbuf);
ht_doEscape(val, conn->linkbuf + i, HTTP_MAXSTRLEN - i);
return 0;
}
/* add a dezimal value to the parameter list of a link
*/
sint_t hsl_linkAddNumberVal(SERVLET_t *slobj, const char *name, u32_t val)
{
HTTPCONN_t *conn = (HTTPCONN_t*) slobj;
sint_t i;
if ((conn == NULL) || (name == NULL))
return -1;
if ((sysStrlen(conn->linkbuf) + sysStrlen(name) + 10 + 2) >
HTTP_MAXSTRLEN)
return -1;
i = sysStrlen(conn->linkbuf);
if (i == 0)
return -1;
if (conn->linkbuf[i-1] != '&')
{
conn->linkbuf[i] = (conn->linkflags & HSL_LINK_QM) ? '?' : '&';
conn->linkbuf[i+1] = 0;
conn->linkflags &= ~HSL_LINK_QM;
}
sysStrcat(conn->linkbuf, name);
sysStrcat(conn->linkbuf, "=");
sprintf(conn->linkbuf + sysStrlen(conn->linkbuf), "%u", val);
return 0;
}
/* insert a link into the servlet output stream
*/
sint_t hsl_linkInsert(SERVLET_t *slobj, const char *linktext)
{
HTTPCONN_t *conn = (HTTPCONN_t*) slobj;
if (conn == NULL)
return -1;
if ((conn->linkflags & HSL_LINK_RAW) == 0)
{
if (linktext == NULL)
return -1;
hsl_printf(slobj, "<a href=\"%s\">%s</a>", conn->linkbuf, linktext);
}
else
{
hsl_printf(slobj, "%s", conn->linkbuf);
}
return 0;
}
/* add session id as hidden parameter to a form
*/
sint_t hsl_addSessionIdToForm(SERVLET_t *slobj)
{
HTTPCONN_t *conn = (HTTPCONN_t*) slobj;
if (conn == NULL)
return -1;
if (conn->session == NULL)
return -1;
hsl_printf(slobj, "<input type=\"hidden\" name=\"" HTTP_SESSIONIDNAME
"\" value=\"%08x\">", conn->session->id);
return 0;
}
/* calculate a pseudo random number
*/
static u32_t ht_random(sint_t init)
{
static u16_t r1 = 0x15a6;
static u16_t r2 = 0xa26f;
u16_t r, i, time = (u16_t) COUNTERVAR;
if (init != 0)
{
r1 += time & 0x55AA;
r2 += time & 0xAA55;
if (r1 == 43690) r1++;
if (r2 == 43690) r2--;
}
for (i = 1 + (time & 1); i > 0; i--)
{
r = (1 ^ r1 ^ (r1 >> 12) ^ (r1 >> 3)) & 1;
r1 = (r1 >> 1) | (r << 15);
}
for (i = ((r1 & 3) == 0) ? 2 : 1; i > 0; i--)
{
r = (1 ^ r2 ^ (r2 >> 12) ^ (r2 >> 5)) & 1;
r2 = (r2 >> 1) | (r << 15);
}
return (u32_t)r1 + ((u32_t)r2 << 16) + time;
}
/* create a new session id
*/
static u32_t ht_newSessionId(void)
{
SESSION_t *ss;
u32_t id;
do
{
id = ht_random(0);
for (ss = FIRST_LIST_ELEM(&sessionListHead_g, SESSION_t*);
!END_OF_LIST(&sessionListHead_g, ss);
ss = NEXT_LIST_ELEM(ss, SESSION_t*))
{
if (ss->id == id)
break;
}
}
while (!END_OF_LIST(&sessionListHead_g, ss));
return id;
}
/* destroy a servlet session
*/
static void ht_destroySession(SESSION_t *ss)
{
if (ss != NULL)
{
ht_listDel(&ss->list);
allocatedSessionMem_g -= ss->userMemSize + sizeof(SESSION_t);
sysMemFree(ss);
}
}
/* try to assign a session to a HTTP servlet connection
*/
static sint_t ht_assignSession(HTTPCONN_t *conn)
{
SESSION_t *ss;
char *p;
u32_t sid;
p = hsl_getParameterByName((SERVLET_t) conn, HTTP_SESSIONIDNAME);
if (p == NULL)
return 0;
if (sscanf(p, "%08x", &sid) != 1)
return 0;
for (ss = FIRST_LIST_ELEM(&sessionListHead_g, SESSION_t*);
!END_OF_LIST(&sessionListHead_g, ss);
ss = NEXT_LIST_ELEM(ss, SESSION_t*))
{
if (ss->id == sid)
{
conn->session = ss;
return 0;
}
}
return -1;
}
/* This function destorys a servlet session.
* It should be called when the user logs out.
*/
sint_t hsl_destroySession(SERVLET_t *slobj)
{
HTTPCONN_t *conn = (HTTPCONN_t*) slobj;
if (conn == NULL)
return -1;
if (conn->session == NULL)
return -1;
ht_destroySession(conn->session);
conn->session = NULL;
return 0;
}
/* This function returns a pointer to the servlets session memory.
*/
void* hsl_getSession(SERVLET_t *slobj)
{
HTTPCONN_t *conn = (HTTPCONN_t*) slobj;
if (conn == NULL)
return NULL;
if (conn->session == NULL)
return NULL;
conn->session->lastUsed = COUNTERVAR;
return (void*) conn->session->userData;
}
/* This function returns the own name (name of the servlet).
*/
char* hsl_getOwnName(SERVLET_t *slobj)
{
HTTPCONN_t *conn = (HTTPCONN_t*) slobj;
char *n;
if (conn == NULL)
return NULL;
n = conn->servlet->filename;
if (*n == '/')
n++;
return n;
}
/* This function creates a new session.
*/
void* hsl_newSession(SERVLET_t *slobj, u32_t memsize, u32_t timeout)
{
HTTPCONN_t *conn = (HTTPCONN_t*) slobj;
SESSION_t *ss;
u32_t size;
if (conn == NULL)
return NULL;
if (timeout == 0)
timeout = 300;
size = sizeof(SESSION_t) + memsize;
if ((allocatedSessionMem_g + size) > maxSessionMem_g)
return NULL;
ss = (SESSION_t*) sysMemAlloc(size);
if (ss == NULL)
return NULL;
allocatedSessionMem_g += size;
sysMemSet(&ss->userData, 0, memsize);
ss->id = ht_newSessionId();
ss->userMemSize = memsize;
ss->lastUsed = COUNTERVAR;
ss->timeout = timeout * COUNTERTPS;
ht_listAddTail(&sessionListHead_g, &ss->list);
conn->session = ss;
return (void*) ss->userData;
}
/* allocate a servlet buffer
*/
static SLBUF_t *ht_allocServletBuffer(void)
{
SLBUF_t *b;
b = freeServletBufList_g;
if (b != NULL)
{
freeServletBufList_g = b->nextbuf;
return b;
}
if ((allocatedServletMem_g + HTTP_SERVLETMINBUF) > maxServletMem_g)
return NULL;
b = (SLBUF_t*) sysMemAlloc(sizeof(SLBUF_t));
if (b != NULL)
allocatedServletMem_g += sizeof(SLBUF_t);
return b;
}
/* free a servlet buffer
*/
static void ht_freeServletBuffer(SLBUF_t *buf)
{
HTTPCONN_t *conn;
if (buf != NULL)
{
buf->nextbuf = freeServletBufList_g;
freeServletBufList_g = buf;
/* new memory available, try to handle the next waiting servlet */
if (!IS_LIST_EMPTY(&memWaitingList_g))
{
conn = GET_TRUE_ELEM( FIRST_LIST_ELEM(&memWaitingList_g, lelem_t*),
HTTPCONN_t*, mwlist );
if (ht_tryAllocateBuffers(conn) == 0)
{
ht_handleServlet(conn);
}
}
}
}
/* free a servlet buffer chain
*/
static void ht_freeServletBufferChain(SLBUF_t *firstbuf)
{
SLBUF_t *nextbuf, *buf = firstbuf;
while (buf != NULL)
{
nextbuf = buf->nextbuf;
buf->nextbuf = freeServletBufList_g;
freeServletBufList_g = buf;
buf = nextbuf;
}
}
/* try to allocate requested sl-buffers
*/
static sint_t ht_tryAllocateBuffers(HTTPCONN_t *conn)
{
HTTPCONN_t *mcon;
SLBUF_t *buf;
if (conn->neededBufs == 0)
return 0;
if (!IS_ON_LIST(&conn->mwlist))
{
ht_listAddTail(&memWaitingList_g, &conn->mwlist);
}
mcon = GET_TRUE_ELEM( FIRST_LIST_ELEM(&memWaitingList_g, lelem_t*),
HTTPCONN_t*, mwlist );
while (mcon->neededBufs > 0)
{
buf = ht_allocServletBuffer();
if (buf == NULL)
break;
if (mcon->stdoutbuf == NULL)
{
buf->nextbuf = NULL;
mcon->stdoutbuf = buf;
mcon->curoutbuf = buf;
}
else
{
buf->nextbuf = mcon->freeSlBufs;
mcon->freeSlBufs = buf;
}
mcon->outbufsize += HTTP_SERVLETMINBUF;
mcon->neededBufs--;
}
if (mcon->neededBufs == 0)
{
ht_listDel(&mcon->mwlist);
if (conn == mcon)
{
/* all buffers allocated, enable write again and return */
ht_addWrSocket(conn->socket);
return 0;
}
}
/* failed to allocate buffer, must wait */
/* disable write for the socket */
FD_CLR(conn->socket, &globalWrSocketSet);
/*
if (conn->wrDisabled == 0)
{
ht_disableWrite(conn);
}
*/
return -1;
}
/* handle a servlet
*/
static void ht_handleServlet(HTTPCONN_t *conn)
{
sint_t rc;
if (conn->servlet == NULL)
return;
if (conn->state != STATE_INIT)
return;
SYS_MTASK_LOCK(servletLock_g);
if (ht_tryAllocateBuffers(conn) != 0)
{
/* memory allocation failed, try later again */
SYS_MTASK_UNLOCK(servletLock_g);
#ifdef _MYDEBUG
if (conn->neededBufs == 1)
printf("connection %i: failed to allocated 1 buffer\n", conn->socket);
#endif
return;
}
/* call servlet */
rc = (conn->servlet->func)((SERVLET_t) conn);
SYS_MTASK_UNLOCK(servletLock_g);
if (rc == SLERR_NEEDMEM)
{
return; /* try later again */
}
if (rc != SLERR_OK)
{
/* other errors */
switch (rc)
{
case SLERR_BADREQUEST: rc = ht_sendStatus(conn, status_400); break;
case SLERR_NOTFOUND: rc = ht_sendStatus(conn, status_404); break;
case SLERR_CREATED: rc = ht_sendStatus(conn, status_201); break;
case SLERR_ACCEPTED: rc = ht_sendStatus(conn, status_202); break;
case SLERR_PARTIAL: rc = ht_sendStatus(conn, status_206); break;
case SLERR_FORBIDDEN: rc = ht_sendStatus(conn, status_403); break;
case SLERR_TOOLARGE: rc = ht_sendStatus(conn, status_413); break;
case SLERR_UNAVAILABLE: rc = ht_sendStatus(conn, status_503); break;
case SLERR_BUSY: rc = ht_sendStatus(conn, status_busy); break;
case SLERR_SERVER:
default:
rc = ht_sendStatus(conn, status_500); /* Internal Server Error */
}
if (rc == 0)
ht_nextTransfer(conn);
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -