📄 webs.c
字号:
}#endif/* * If using Keep Alive (HTTP/1.1) we keep the socket open for a period * while waiting for another request on the socket. */ if (wp->flags & WEBS_KEEP_ALIVE) { if (socketFlush(wp->sid) == 0) { wp->state = WEBS_BEGIN; wp->flags |= WEBS_REQUEST_DONE; if (wp->header.buf) { ringqFlush(&wp->header); } socketCreateHandler(wp->sid, SOCKET_READABLE, websSocketEvent, (int) wp); websTimeoutCancel(wp); wp->timeout = emfSchedCallback(WEBS_TIMEOUT, websTimeout, (void *) wp); return; } } else { websTimeoutCancel(wp); socketSetBlock(wp->sid, 1); socketFlush(wp->sid); socketCloseConnection(wp->sid); } websFree(wp);}/******************************************************************************//* * Allocate a new webs structure */int websAlloc(int sid){ webs_t wp; int wid;/* * Allocate a new handle for this connection */ if ((wid = hAllocEntry((void***) &webs, &websMax, sizeof(struct websRec))) < 0) { return -1; } wp = webs[wid]; wp->wid = wid; wp->sid = sid; wp->state = WEBS_BEGIN; wp->docfd = -1; wp->timeout = -1; wp->dir = NULL; wp->authType = NULL; wp->protocol = NULL; wp->protoVersion = NULL; wp->password = NULL; wp->userName = NULL;#ifdef DIGEST_ACCESS_SUPPORT wp->realm = NULL; wp->nonce = NULL; wp->digest = NULL; wp->uri = NULL; wp->opaque = NULL; wp->nc = NULL; wp->cnonce = NULL; wp->qop = NULL;#endif#ifdef WEBS_SSL_SUPPORT wp->wsp = NULL;#endif ringqOpen(&wp->header, WEBS_HEADER_BUFINC, WEBS_MAX_HEADER);/* * Create storage for the CGI variables. We supply the symbol tables for * both the CGI variables and for the global functions. The function table * is common to all webs instances (ie. all browsers) */ wp->cgiVars = symOpen(WEBS_SYM_INIT); return wid;}/******************************************************************************//* * Free a webs structure */void websFree(webs_t wp){ a_assert(websValid(wp)); if (wp->path) bfree(B_L, wp->path); if (wp->url) bfree(B_L, wp->url); if (wp->host) bfree(B_L, wp->host); if (wp->lpath) bfree(B_L, wp->lpath); if (wp->query) bfree(B_L, wp->query); if (wp->decodedQuery) bfree(B_L, wp->decodedQuery); if (wp->authType) bfree(B_L, wp->authType); if (wp->password) bfree(B_L, wp->password); if (wp->userName) bfree(B_L, wp->userName); if (wp->cookie) bfree(B_L, wp->cookie); if (wp->userAgent) bfree(B_L, wp->userAgent); if (wp->dir) bfree(B_L, wp->dir); if (wp->protocol) bfree(B_L, wp->protocol); if (wp->protoVersion) bfree(B_L, wp->protoVersion); if (wp->cgiStdin) bfree(B_L, wp->cgiStdin);#ifdef DIGEST_ACCESS_SUPPORT if (wp->realm) bfree(B_L, wp->realm); if (wp->uri) bfree(B_L, wp->uri); if (wp->digest) bfree(B_L, wp->digest); if (wp->opaque) bfree(B_L, wp->opaque); if (wp->nonce) bfree(B_L, wp->nonce); if (wp->nc) bfree(B_L, wp->nc); if (wp->cnonce) bfree(B_L, wp->cnonce); if (wp->qop) bfree(B_L, wp->qop);#endif#ifdef WEBS_SSL_SUPPORT websSSLFree(wp->wsp);#endif symClose(wp->cgiVars); if (wp->header.buf) { ringqClose(&wp->header); } websMax = hFree((void***) &webs, wp->wid); bfree(B_L, wp); a_assert(websMax >= 0);}/******************************************************************************//* * Return the server address */char_t *websGetHost(){ return websHost;}/******************************************************************************//* * Return the the url to access the server. (ip address) */char_t *websGetIpaddrUrl(){ return websIpaddrUrl;}/******************************************************************************//* * Return the server address */char_t *websGetHostUrl(){ return websHostUrl;}/******************************************************************************//* * Return the listen port */int websGetPort(){ return websPort;}/******************************************************************************//* * Get the number of bytes to write */int websGetRequestBytes(webs_t wp){ a_assert(websValid(wp)); return wp->numbytes;}/******************************************************************************//* * Get the directory for this request */char_t *websGetRequestDir(webs_t wp){ a_assert(websValid(wp)); if (wp->dir == NULL) { return T(""); } return wp->dir;}/******************************************************************************//* * Get the flags for this request */int websGetRequestFlags(webs_t wp){ a_assert(websValid(wp)); return wp->flags;}/******************************************************************************//* * Return the IP address */char_t *websGetRequestIpaddr(webs_t wp){ a_assert(websValid(wp)); return wp->ipaddr;}/******************************************************************************//* * Set the local path for the request */char_t *websGetRequestLpath(webs_t wp){ a_assert(websValid(wp));#if WEBS_PAGE_ROM return wp->path;#else return wp->lpath;#endif}/******************************************************************************//* * Get the path for this request */char_t *websGetRequestPath(webs_t wp){ a_assert(websValid(wp)); if (wp->path == NULL) { return T(""); } return wp->path;}/******************************************************************************//* * Return the password */char_t *websGetRequestPassword(webs_t wp){ a_assert(websValid(wp)); return wp->password;}/******************************************************************************//* * Return the request type */char_t *websGetRequestType(webs_t wp){ a_assert(websValid(wp)); return wp->type;}/******************************************************************************//* * Return the username */char_t *websGetRequestUserName(webs_t wp){ a_assert(websValid(wp)); return wp->userName;}/******************************************************************************//* * Get the number of bytes written */int websGetRequestWritten(webs_t wp){ a_assert(websValid(wp)); return wp->written;}/******************************************************************************//* * Set the hostname */void websSetHost(char_t *host){ gstrncpy(websHost, host, TSZ(websHost));}/******************************************************************************//* * Set the host URL */void websSetHostUrl(char_t *url){ a_assert(url && *url); bfreeSafe(B_L, websHostUrl); websHostUrl = gstrdup(B_L, url);}/******************************************************************************//* * Set the IP address */void websSetIpaddr(char_t *ipaddr){ a_assert(ipaddr && *ipaddr); gstrncpy(websIpaddr, ipaddr, TSZ(websIpaddr));}/******************************************************************************//* * Set the number of bytes to write */void websSetRequestBytes(webs_t wp, int bytes){ a_assert(websValid(wp)); a_assert(bytes >= 0); wp->numbytes = bytes;}/******************************************************************************//* * Set the flags for this request */void websSetRequestFlags(webs_t wp, int flags){ a_assert(websValid(wp)); wp->flags = flags;}/******************************************************************************//* * Set the local path for the request */void websSetRequestLpath(webs_t wp, char_t *lpath){ a_assert(websValid(wp)); a_assert(lpath && *lpath); if (wp->lpath) { bfree(B_L, wp->lpath); } wp->lpath = bstrdup(B_L, lpath); websSetVar(wp, T("PATH_TRANSLATED"), wp->lpath);}/******************************************************************************//* * Update the URL path and the directory containing the web page */void websSetRequestPath(webs_t wp, char_t *dir, char_t *path){ char_t *tmp; a_assert(websValid(wp)); if (dir) { tmp = wp->dir; wp->dir = bstrdup(B_L, dir); if (tmp) { bfree(B_L, tmp); } } if (path) { tmp = wp->path; wp->path = bstrdup(B_L, path); websSetVar(wp, T("PATH_INFO"), wp->path); if (tmp) { bfree(B_L, tmp); } }}/******************************************************************************//* * Set the Write handler for this socket */void websSetRequestSocketHandler(webs_t wp, int mask, void (*fn)(webs_t wp)){ a_assert(websValid(wp)); wp->writeSocket = fn; socketCreateHandler(wp->sid, SOCKET_WRITABLE, websSocketEvent, (int) wp);}/******************************************************************************//* * Set the number of bytes written */void websSetRequestWritten(webs_t wp, int written){ a_assert(websValid(wp)); wp->written = written;}/******************************************************************************//* * Reurn true if the webs handle is valid */int websValid(webs_t wp){ int wid; for (wid = 0; wid < websMax; wid++) { if (wp == webs[wid]) { return 1; } } return 0;}/******************************************************************************//* * Build an ASCII time string. If sbuf is NULL we use the current time, * else we use the last modified time of sbuf; */char_t *websGetDateString(websStatType *sbuf){ char_t* cp, *r; time_t now; if (sbuf == NULL) { time(&now); } else { now = sbuf->mtime; } if ((cp = gctime(&now)) != NULL) { cp[gstrlen(cp) - 1] = '\0'; r = bstrdup(B_L, cp); return r; } return NULL;}/******************************************************************************//* * Mark time. Set a timestamp so that, later, we can return the number of * seconds since we made the mark. Note that the mark my not be a * "real" time, but rather a relative marker. */void websMarkTime(webs_t wp){ wp->timestamp = time(0);}/******************************************************************************//* * Get the number of seconds since the last mark. */static int websGetTimeSinceMark(webs_t wp){ return time(0) - wp->timestamp;}/******************************************************************************//* * Store the new realm name */void websSetRealm(char_t *realmName){ a_assert(realmName); gstrncpy(websRealm, realmName, TSZ(websRealm));}/******************************************************************************//* * Return the realm name (used for authorization) */char_t *websGetRealm(){ return websRealm;}#if WEBS_IF_MODIFIED_SUPPORT/******************************************************************************//* * These functions are intended to closely mirror the syntax for HTTP-date * from RFC 2616 (HTTP/1.1 spec). This code was submitted by Pete Bergstrom. *//* * RFC1123Date = wkday "," SP date1 SP time SP "GMT" * RFC850Date = weekday "," SP date2 SP time SP "GMT" * ASCTimeDate = wkday SP date3 SP time SP 4DIGIT * * Each of these functions tries to parse the value and update the index to * the point it leaves off parsing. */typedef enum { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC } MonthEnumeration;typedef enum { SUN, MON, TUE, WED, THU, FRI, SAT } WeekdayEnumeration;/******************************************************************************//* * Parse an N-digit value
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -