📄 webs.c
字号:
done += len; } bfree(B_L, asciiBuf); return done;}/******************************************************************************//* * Write a block of data of length "nChars" to the user's browser. Same as * websWriteBlock except that it expects straight ASCII or binary and does no * unicode conversion before writing the data. If the socket cannot hold all * the data, it will return the number of bytes flushed to the socket before * it would have blocked. This returns the number of chars processed or -1 * if socketWrite fails. */int websWriteDataNonBlock(webs_t wp, char *buf, int nChars){ int r; a_assert(wp); a_assert(websValid(wp)); a_assert(buf); a_assert(nChars >= 0);#ifdef WEBS_SSL_SUPPORT if (wp->flags & WEBS_SECURE) { r = websSSLWrite(wp->wsp, buf, nChars); websSSLFlush(wp->wsp); } else { r = socketWrite(wp->sid, buf, nChars); socketFlush(wp->sid); }#else r = socketWrite(wp->sid, buf, nChars); socketFlush(wp->sid);#endif return r;}/******************************************************************************//* * Decode a URL (or part thereof). Allows insitu decoding. */void websDecodeUrl(char_t *decoded, char_t *token, int len){ char_t *ip, *op; int num, i, c; a_assert(decoded); a_assert(token); op = decoded; for (ip = token; *ip && len > 0; ip++, op++) { if (*ip == '+') { *op = ' '; } else if (*ip == '%' && gisxdigit(ip[1]) && gisxdigit(ip[2])) {/* * Convert %nn to a single character */ ip++; for (i = 0, num = 0; i < 2; i++, ip++) { c = tolower(*ip); if (c >= 'a' && c <= 'f') { num = (num * 16) + 10 + c - 'a'; } else { num = (num * 16) + c - '0'; } } *op = (char_t) num; ip--; } else { *op = *ip; } len--; } *op = '\0';}/******************************************************************************/#ifdef WEBS_LOG_SUPPORT/* * Output a log message */static void websLog(webs_t wp, int code){ char_t *buf; char *abuf; int len;#define qAnlLog 1#if (defined(qAnlLog) && !defined(CE)) time_t timer; char_t* newLine = NULL; char_t* timeStr = NULL;#endif a_assert(websValid(wp)); buf = NULL;#if (defined(qAnlLog) && !defined(CE)) time(&timer); timeStr = ctime(&timer); newLine = gstrchr(timeStr, '\n'); if (newLine) { *newLine = '\0'; } fmtAlloc(&buf, WEBS_MAX_URL + 80, T("%s\t%s\t%s\tcode = %d\n"), timeStr, wp->ipaddr, wp->url, code);#else fmtAlloc(&buf, WEBS_MAX_URL + 80, T("%d %s %d %d\n"), time(0), wp->url, code, wp->written);#endif len = gstrlen(buf); abuf = ballocUniToAsc(buf, len+1); write(websLogFd, abuf, len); bfreeSafe(B_L, buf); bfreeSafe(B_L, abuf);}#endif /* WEBS_LOG_SUPPORT *//******************************************************************************//* * Request timeout. The timeout triggers if we have not read any data from * the users browser in the last WEBS_TIMEOUT period. If we have heard from * the browser, simply re-issue the timeout. */void websTimeout(void *arg, int id){ webs_t wp; int delay, tm; wp = (webs_t) arg; a_assert(websValid(wp)); tm = websGetTimeSinceMark(wp) * 1000; if (tm >= WEBS_TIMEOUT) { websStats.timeouts++; emfUnschedCallback(id);/* * Clear the timeout id */ wp->timeout = -1; websDone(wp, 404); } else { delay = WEBS_TIMEOUT - tm; a_assert(delay > 0); emfReschedCallback(id, delay); }}/******************************************************************************//* * Called when the request is done. */void websDone(webs_t wp, int code){ a_assert(websValid(wp));/* * Disable socket handler in case keep alive set. */ socketDeleteHandler(wp->sid); if (code != 200) { wp->flags &= ~WEBS_KEEP_ALIVE; }#ifdef WEBS_PROXY_SUPPORT if (! (wp->flags & WEBS_LOCAL_PAGE)) { websStats.activeNetRequests--; }#endif#ifdef WEBS_LOG_SUPPORT if (! (wp->flags & WEBS_REQUEST_DONE)) { websLog(wp, code); }#endif/* * Close any opened document by a handler */ websPageClose(wp);/* * Exit if secure. */#ifdef WEBS_SSL_SUPPORT if (wp->flags & WEBS_SECURE) { websTimeoutCancel(wp); websSSLFlush(wp->wsp); socketCloseConnection(wp->sid); websFree(wp); return; }#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));#ifdef 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -