Example #1
0
int HttpClient::skipResponseHeaders()
{
    // Just keep reading until we finish reading the headers or time out
    unsigned long timeoutStart = millis();
    // Whilst we haven't timed out & haven't reached the end of the headers
    while ((!endOfHeadersReached()) && 
           ( (millis() - timeoutStart) < iHttpResponseTimeout ))
    {
        if (available())
        {
            (void)readHeader();
            // We read something, reset the timeout counter
            timeoutStart = millis();
        }
        else
        {
            // We haven't got any data, so let's pause to allow some to
            // arrive
            delay(kHttpWaitForDataDelay);
        }
    }
    if (endOfHeadersReached())
    {
        // Success
        return HTTP_SUCCESS;
    }
    else
    {
        // We must've timed out
        return HTTP_ERROR_TIMED_OUT;
    }
}
Example #2
0
int HttpClient::read()
{
#if 0 // Fails on WiFi because multi-byte read seems to be broken
    uint8_t b[1];
    int ret = read(b, 1);
    if (ret == 1)
    {
        return b[0];
    }
    else
    {
        return -1;
    }
#else
    int ret = iClient->read();
    if (ret >= 0)
    {
        if (endOfHeadersReached() && iContentLength > 0)
	{
            // We're outputting the body now and we've seen a Content-Length header
            // So keep track of how many bytes are left
            iBodyLengthConsumed++;
	}
    }
    return ret;
#endif
}
Example #3
0
bool HttpClient::headerAvailable()
{
    // clear the currently store header line
    iHeaderLine = "";

    while (!endOfHeadersReached())
    {
        // read a byte from the header
        int c = readHeader();

        if (c == '\r' || c == '\n')
        {
            if (iHeaderLine.length())
            {
                // end of the line, all done
                break;
            } 
            else
            {
                // ignore any CR or LF characters
                continue;
            }
        }

        // append byte to header line
        iHeaderLine += (char)c;
    }

    return (iHeaderLine.length() > 0);
}
Example #4
0
int HttpClient::read()
{
    if (iIsChunked && !available())
    {
        return -1;
    }

    int ret = iClient->read();
    if (ret >= 0)
    {
        if (endOfHeadersReached() && iContentLength > 0)
        {
            // We're outputting the body now and we've seen a Content-Length header
            // So keep track of how many bytes are left
            iBodyLengthConsumed++;
        }

        if (iState == eReadingBodyChunk)
        {
            iChunkLength--;

            if (iChunkLength == 0)
            {
                iState = eReadingChunkLength;
            }
        }
    }
    return ret;
}
Example #5
0
bool HttpClient::endOfBodyReached()
{
    if (endOfHeadersReached() && (contentLength() != kNoContentLengthHeader))
    {
        // We've got to the body and we know how long it will be
        return (iBodyLengthConsumed >= contentLength());
    }
    return false;
}
Example #6
0
int HttpClient::contentLength()
{
    // skip the response headers, if they haven't been read already 
    if (!endOfHeadersReached())
    {
        skipResponseHeaders();
    }

    return iContentLength;
}
Example #7
0
int HttpClient::read(uint8_t *buf, size_t size)
{
    int ret =iClient->read(buf, size);
    if (endOfHeadersReached() && iContentLength > 0)
    {
        // We're outputting the body now and we've seen a Content-Length header
        // So keep track of how many bytes are left
        if (ret >= 0)
	{
            iBodyLengthConsumed += ret;
	}
    }
    return ret;
}
Example #8
0
int HttpClient::readHeader()
{
    char c = read();

    if (endOfHeadersReached())
    {
        // We've passed the headers, but rather than return an error, we'll just
        // act as a slightly less efficient version of read()
        return c;
    }

    // Whilst reading out the headers to whoever wants them, we'll keep an
    // eye out for the "Content-Length" header
    switch(iState)
    {
    case eStatusCodeRead:
        // We're at the start of a line, or somewhere in the middle of reading
        // the Content-Length prefix
        if (*iContentLengthPtr == c)
        {
            // This character matches, just move along
            iContentLengthPtr++;
            if (*iContentLengthPtr == '\0')
            {
                // We've reached the end of the prefix
                iState = eReadingContentLength;
                // Just in case we get multiple Content-Length headers, this
                // will ensure we just get the value of the last one
                iContentLength = 0;
            }
        }
        else if ((iContentLengthPtr == kContentLengthPrefix) && (c == '\r'))
        {
            // We've found a '\r' at the start of a line, so this is probably
            // the end of the headers
            iState = eLineStartingCRFound;
        }
        else
        {
            // This isn't the Content-Length header, skip to the end of the line
            iState = eSkipToEndOfHeader;
        }
        break;
    case eReadingContentLength:
        if (isdigit(c))
        {
            iContentLength = iContentLength*10 + (c - '0');
        }
        else
        {
            // We've reached the end of the content length
            // We could sanity check it here or double-check for "\r\n"
            // rather than anything else, but let's be lenient
            iState = eSkipToEndOfHeader;
        }
        break;
    case eLineStartingCRFound:
        if (c == '\n')
        {
            iState = eReadingBody;
        }
        break;
    default:
        // We're just waiting for the end of the line now
        break;
    };

    if ( (c == '\n') && !endOfHeadersReached() )
    {
        // We've got to the end of this line, start processing again
        iState = eStatusCodeRead;
        iContentLengthPtr = kContentLengthPrefix;
    }
    // And return the character read to whoever wants it
    return c;
}