// Content-Type bool HttpMime::parseContentType(const char *field, size_t fieldLen) { static const char s_contentType[] = "content-type"; static const size_t s_contentTypeLen = strlen(s_contentType); if (fieldLen == s_contentTypeLen && strncasecmp(field, s_contentType, fieldLen) == 0) { const char *value = NULL; size_t valueLen = 0; if (getValue(&value, &valueLen)) { m_contentTypePos = value; m_contentType = getContentTypePrivate(value, valueLen); } return true; } return false; }
// returns false on bad mime bool HttpMime::parse ( char *mime , long mimeLen , Url *url ) { // reset locUrl to 0 m_locUrl.reset(); // return if we have no valid complete mime if ( mimeLen == 0 ) return false; // status is on first line m_status = -1; // skip HTTP/x.x till we hit a space char *p = mime; char *pend = mime + mimeLen; while ( p < pend && !is_wspace_a(*p) ) p++; // then skip over spaces while ( p < pend && is_wspace_a(*p) ) p++; // return false on a problem if ( p == pend ) return false; // then read in the http status m_status = atol2 ( p , pend - p ); // if no Content-Type: mime field was provided, assume html m_contentType = CT_HTML; // assume default charset m_charset = NULL; m_charsetLen = 0; // set contentLen, lastModifiedDate, m_cookie p = mime; while ( p < pend ) { // compute the length of the string starting at p and ending // at a \n or \r long len = 0; while ( &p[len] < pend && p[len]!='\n' && p[len]!='\r' ) len++; // . if we could not find a \n or \r there was an error // . MIMEs must always end in \n or \r if ( &p[len] >= pend ) return false; // . stick a NULL at the end of the line // . overwrites \n or \r TEMPORARILY char c = p [ len ]; p [ len ] = '\0'; // parse out some meaningful data if ( strncasecmp ( p , "Content-Length:" ,15) == 0 ) { m_contentLengthPos = p + 15; m_contentLen = atol( m_contentLengthPos); } else if ( strncasecmp ( p , "Last-Modified:" ,14) == 0 ) { m_lastModifiedDate=atotime(p+14); // do not let them exceed current time for purposes // of sorting by date using datedb (see Msg16.cpp) time_t now = time(NULL); if (m_lastModifiedDate > now) m_lastModifiedDate = now; } else if ( strncasecmp ( p , "Content-Type:" ,13) == 0 ) m_contentType = getContentTypePrivate ( p + 13 ); else if ( strncasecmp ( p , "Set-Cookie: " ,11) == 0 ) { m_cookie = p + 11; m_cookieLen = gbstrlen ( p + 11 ); } else if ( strncasecmp ( p , "Location:" , 9) == 0 ) { // point to it char *tt = p + 9; // skip if space if ( *tt == ' ' ) tt++; if ( *tt == ' ' ) tt++; // at least set this for Msg13.cpp to use m_locationField = tt; m_locationFieldLen = gbstrlen(tt); // . we don't add the "www." because of slashdot.com // . we skip initial spaces in this Url::set() routine if(url) m_locUrl.set ( url, p + 9, len - 9, false/*addWWW?*/); } else if ( strncasecmp ( p , "Content-Encoding:", 17) == 0 ) { //only support gzip now, it doesn't seem like servers //implement the other types much m_contentEncodingPos = p+17; if(strstr(m_contentEncodingPos, "gzip")) { m_contentEncoding = ET_GZIP; } else if(strstr(m_contentEncodingPos, "deflate")) { //zlib's compression m_contentEncoding = ET_DEFLATE; } } //else if ( strncasecmp ( p, "Cookie:", 7) == 0 ) // log (LOG_INFO, "mime: Got Cookie = %s", (p+7)); // re-insert the character that we replaced with a '\0' p [ len ] = c; // go to next line p += len; // skip over the cruft at the end of this line while ( p < pend && ( *p=='\r' || *p=='\n' ) ) p++; } return true; }