bool Str_Parse( TCHAR * pLine, TCHAR ** ppLine2, LPCTSTR pszSep ) { // Parse a list of args. Just get the next arg. // similar to strtok() // RETURN: true = the second arg is valid. if ( pszSep == NULL ) // default sep. pszSep = "=, \t"; // skip leading white space. TCHAR * pNonWhite = pLine; GETNONWHITESPACE(pNonWhite); if ( pNonWhite != pLine ) { memmove( pLine, pNonWhite, strlen( pNonWhite ) + 1 ); } TCHAR ch; bool bQuotes = false; for ( ; ; pLine++ ) { ch = *pLine; if ( ch == '"' ) // quoted argument { bQuotes = !bQuotes; continue; } if ( ch == '\0' ) // no args i guess. { if ( ppLine2 != NULL ) { *ppLine2 = pLine; } return false; } if ( strchr( pszSep, ch ) && (bQuotes == false)) break; } *pLine++ = '\0'; if ( IsSpace( ch )) // space separators might have other seps as well ? { GETNONWHITESPACE( pLine ); ch = *pLine; if ( ch && strchr( pszSep, ch )) { pLine++; } } // skip leading white space on args as well. if ( ppLine2 != NULL ) { *ppLine2 = Str_TrimWhitespace( pLine ); } return true; }
bool CScript::FindKey( LPCTSTR pszName ) // Find a key in the current section { ADDTOCALLSTACK("CScript::FindKey"); if ( strlen( pszName ) > SCRIPT_MAX_SECTION_LEN ) { DEBUG_ERR(( "Bad script key name\n" )); return( false ); } Seek( m_lSectionData ); while ( ReadKeyParse()) { if ( IsKey( pszName )) { m_pszArg = Str_TrimWhitespace( m_pszArg ); return true; } } return( false ); }
bool CClient::OnRxWebPageRequest( byte * pRequest, size_t iLen ) { ADDTOCALLSTACK("CClient::OnRxWebPageRequest"); // Seems to be a web browser pointing at us ? typical stuff : if ( GetConnectType() != CONNECT_HTTP ) return false; // ensure request is null-terminated (if the request is well-formed, we are overwriting a trailing \n here) pRequest[iLen - 1] = '\0'; if ( strlen(reinterpret_cast<char *>(pRequest)) > 1024 ) // too long request return false; if ( !strpbrk( reinterpret_cast<char *>(pRequest), " \t\012\015" ) ) // malformed request return false; tchar * ppLines[16]; size_t iQtyLines = Str_ParseCmds(reinterpret_cast<char *>(pRequest), ppLines, CountOf(ppLines), "\r\n"); if (( iQtyLines < 1 ) || ( iQtyLines >= 15 )) // too long request return false; // Look for what they want to do with the connection. bool fKeepAlive = false; CSTime dateIfModifiedSince; tchar * pszReferer = NULL; size_t stContentLength = 0; for ( size_t j = 1; j < iQtyLines; j++ ) { tchar *pszArgs = Str_TrimWhitespace(ppLines[j]); if ( !strnicmp(pszArgs, "Connection:", 11 ) ) { pszArgs += 11; GETNONWHITESPACE(pszArgs); if ( !strnicmp(pszArgs, "Keep-Alive", 10) ) fKeepAlive = true; } else if ( !strnicmp(pszArgs, "Referer:", 8) ) { pszReferer = pszArgs+8; } else if ( !strnicmp(pszArgs, "Content-Length:", 15) ) { pszArgs += 15; GETNONWHITESPACE(pszArgs); stContentLength = strtoul(pszArgs, NULL, 10); } else if ( ! strnicmp( pszArgs, "If-Modified-Since:", 18 )) { // If-Modified-Since: Fri, 17 Dec 1999 14:59:20 GMT\r\n pszArgs += 18; dateIfModifiedSince.Read(pszArgs); } } tchar * ppRequest[4]; size_t iQtyArgs = Str_ParseCmds(ppLines[0], ppRequest, CountOf(ppRequest), " "); if (( iQtyArgs < 2 ) || ( strlen(ppRequest[1]) >= _MAX_PATH )) return false; if ( strchr(ppRequest[1], '\r') || strchr(ppRequest[1], 0x0c) ) return false; // if the client hasn't requested a keep alive, we must act as if they had // when async networking is used, otherwise data may not be completely sent if ( fKeepAlive == false ) { fKeepAlive = m_net->isAsyncMode(); // must switch to a blocking socket when the connection is not being kept // alive, or else pending data will be lost when the socket shuts down if ( fKeepAlive == false ) m_net->m_socket.SetNonBlocking(false); } linger llinger; llinger.l_onoff = 1; llinger.l_linger = 500; // in mSec m_net->m_socket.SetSockOpt(SO_LINGER, reinterpret_cast<char *>(&llinger), sizeof(linger)); char nbool = true; m_net->m_socket.SetSockOpt(SO_KEEPALIVE, &nbool, sizeof(char)); // disable NAGLE algorythm for data compression nbool = true; m_net->m_socket.SetSockOpt( TCP_NODELAY, &nbool, sizeof(char), IPPROTO_TCP); if ( memcmp(ppLines[0], "POST", 4) == 0 ) { if ( stContentLength > strlen(ppLines[iQtyLines-1]) ) return false; // POST /--WEBBOT-SELF-- HTTP/1.1 // Referer: http://127.0.0.1:2593/spherestatus.htm // Content-Type: application/x-www-form-urlencoded // Host: 127.0.0.1:2593 // Content-Length: 29 // T1=stuff1&B1=Submit&T2=stuff2 g_Log.Event(LOGM_HTTP|LOGL_EVENT, "%x:HTTP Page Post '%s'\n", GetSocketID(), static_cast<lpctstr>(ppRequest[1])); CWebPageDef *pWebPage = g_Cfg.FindWebPage(ppRequest[1]); if ( !pWebPage ) pWebPage = g_Cfg.FindWebPage(pszReferer); if ( pWebPage ) { if ( pWebPage->ServPagePost(this, ppRequest[1], ppLines[iQtyLines-1], stContentLength) ) { if ( fKeepAlive ) return true; return false; } return false; } } else if ( !memcmp(ppLines[0], "GET", 3) ) { // GET /pagename.htm HTTP/1.1\r\n // If-Modified-Since: Fri, 17 Dec 1999 14:59:20 GMT\r\n // Host: localhost:2593\r\n // \r\n tchar szPageName[_MAX_PATH]; if ( !Str_GetBare( szPageName, Str_TrimWhitespace(ppRequest[1]), sizeof(szPageName), "!\"#$%&()*,:;<=>?[]^{|}-+'`" ) ) return false; g_Log.Event(LOGM_HTTP|LOGL_EVENT, "%x:HTTP Page Request '%s', alive=%d\n", GetSocketID(), static_cast<lpctstr>(szPageName), fKeepAlive); if ( CWebPageDef::ServPage(this, szPageName, &dateIfModifiedSince) ) { if ( fKeepAlive ) return true; return false; } } return false; }