Пример #1
0
/**
 * Send a GET request to retrieve a byte range from the given URL.
 *
 * \param[out] buffer The buffer where the response will be written.
 * \param[in] bufferSize The size of the output buffer.
 * \param[in] host The remote host where the resource is located.
 * \param[in] path The path of the desired resource on the host.
 * \param[in] firstByte Index of the first byte of the requested range.
 * \param[in] lastByte Index of the last byte of the requested range.
 *
 * \return true is returned if the right amount of data is successfully
 * received, false in case of failure.
 *
 * \note host can be either the domain name or the IP address of the host.
 */
bool HttpClient::getRange(char* buffer, size_t bufferSize, const char* host,
    const char* path, uint32_t firstByte, uint32_t lastByte) {
    // generate the HTTP request
    if (!createGetRequest(buffer, bufferSize, host, path,
        (F_GET | F_KEEP_ALIVE), firstByte, lastByte)) {
        return false;
    }

    // try to send the request and wait for a response from the host
    wifly_->clear();
    if (!wifly_->print(buffer))
        return false;
    wifly_->flush();
    // clear the buffer since it still holds the HTTP request
    memset(buffer, 0x00, bufferSize);

    if (!wifly_->awaitResponse())
        return false;

    // look for the right HTTP status code in the response header
    if (!wifly_->findUntil_P(HTTP_PARTIAL, HTTP_END_OF_HEADER))
        return false;
    // skip the rest of the header
    if (!wifly_->find_P(HTTP_END_OF_HEADER))
        return false;

    // write incoming data
    int nBytes = wifly_->readBytes(buffer, bufferSize);
    return (nBytes == (lastByte - firstByte + 1));
}
Пример #2
0
QNetworkReply * TwitterQueryUtil::get(QNetworkAccessManager &network, const QString &path,
                                      const std::map<QByteArray, QByteArray> &parameters,
                                      const Account &account)
{
    QNetworkRequest request {createGetRequest(path, parameters, account)};
    return network.get(request);
}
Пример #3
0
/**
 * Send a HEAD request to retrieve the size of the resource located at the
 * given URL.
 * \param[out] buffer The buffer where the response will be written.
 * \param[in] bufferSize The size of the output buffer.
 * \param[in] host The remote host where the resource is located.
 * \param[in] path The path of the desired resource on the host.
 */
uint32_t HttpClient::getContentLength(char* buffer, size_t bufferSize,
    const char* host, const char* path) {
    if (!createGetRequest(buffer, bufferSize, host, path,
        (F_HEAD | F_KEEP_ALIVE)))
        return 0;
    wifly_->clear();
    if (!wifly_->print(buffer))
        return 0;
    wifly_->flush();
    memset(buffer, 0x00, bufferSize);
    if (!wifly_->awaitResponse())
        return 0;
    if (!wifly_->findUntil_P(HTTP_CONTENT_LENGTH, HTTP_END_OF_HEADER))
        return 0;
    uint8_t nBytes = wifly_->readBytesUntil_P(HTTP_CRLF, buffer, 32);
    return atol(buffer);
}
Пример #4
0
/*
 * Determine the size of the resource located at the given URL.
 *
 * \param[out] buffer The buffer where the response will be written.
 * \param[in] bufferSize The size of the output buffer.
 * \param[in] host The remote host where the resource is located.
 * \param[in] path The path of the desired resource on the host.
 *
 * \return The size of the file (in bytes) is returned. If an error occurs, the
 * value 0 is returned.
 *
 * \note This method is a workaround for determining the size of a file on the
 * SoundCloud servers.
 *
 * SoundCloud songs are hosted either on ec-media.soundcloud.com or on
 * ak-media.soundcloud.com, and the latter does not support HEAD requests.
 *
 * In order to retrieve a Content-Length header from ak-media.soundcloud.com,
 * we send a partial GET request with a very small range (only a few bytes) so
 * that we get the response headers.
 */
uint32_t SoundCloud::getLengthFromHeader(char* buffer, size_t bufferSize,
    url_t& url) {
    // create a partial GET request asking for only two bytes
    uint8_t flags = (F_GET | F_KEEP_ALIVE);
    if (!createGetRequest(buffer, bufferSize, url.host, url.path, flags, 0, 1))
        return false;
    wifly_->clear();
    if (!wifly_->print(buffer))
        return 0;
    memset(buffer, 0x00, bufferSize);
    if (!wifly_->awaitResponse())
        return 0;
    // parse the size of the file from the Content-Range header
    if (!wifly_->findUntil_P(HTTP_CONTENT_RANGE, HTTP_END_OF_HEADER))
        return 0;
    memset(buffer, 0x00, 33);
    uint8_t nBytes = wifly_->readBytesUntil_P(HTTP_CRLF, buffer, 32);
    return atol(buffer);
}
Пример #5
0
/**
 * Connect to host and send a GET request to retrieve the given URL.
 *
 * \param[out] buffer The buffer where the response will be written.
 * \param[in] bufferSize The size of the output buffer.
 * \param[in] host The remote host where the resource is located.
 * \param[in] path The path of the desired resource on the host.
 *
 * \return The number of bytes actually received, -1 in case of failure.
 *
 * \note host can be either the domain name or the IP address of the host.
 */
int HttpClient::get(char* buffer, size_t bufferSize, const char* host,
    const char* path) {
    // generate the HTTP request
    if (!createGetRequest(buffer, bufferSize, host, path,
        (F_GET | F_KEEP_ALIVE))) {
        return -1;
    }

    // try to send the request and wait for a response from the host
    wifly_->clear();
    if (!wifly_->print(buffer))
        return -1;
    wifly_->flush();

    // clear the buffer since it still holds the HTTP request
    memset(buffer, 0x00, bufferSize);
    if (!wifly_->awaitResponse())
        return -1;

    // determine transfer mode
    bool chunked = wifly_->findUntil_P(HTTP_CHUNKED, HTTP_END_OF_HEADER);
    if (chunked) {
        // skip the rest of the header
        if (!wifly_->find_P(HTTP_END_OF_HEADER))
            return -1;
        // process successive chunks
        uint16_t index = 0;
        while (index < bufferSize - 1) {
            char parseBuffer[SSCANF_BUFFER_SIZE];
            // read the line containing the chunk size
            int nBytes = wifly_->readBytesUntil_P(HTTP_CRLF, parseBuffer,
                SSCANF_BUFFER_SIZE);
            // chunk size should be at least one digit followed by \r\n
            if (nBytes < 1 + strlen_P(HTTP_CRLF))
                return -1;
            // erase the \r\n
            memset(parseBuffer + nBytes - 2, 0x00, 2);
            // parse chunk size
            uint16_t chunkSize = 0;
            sscanf(parseBuffer, "%x", &chunkSize);
            if (chunkSize < 0 || chunkSize > bufferSize) {
                return -1;
            }
            if (chunkSize == 0)
                break;
            // download chunk
            nBytes = wifly_->readBytes(buffer + index, chunkSize);
            if (nBytes != chunkSize)
                return -1;
            index += chunkSize;
            // skip end of line
            if (!wifly_->find_P(HTTP_CRLF))
                return -1;
        }
        return index;
    }
    else {
        int nBytes = wifly_->readBytes(buffer, bufferSize);
        return nBytes;
    }
}