Ejemplo n.º 1
0
/**
 * function for download resource 
 * form url to path location
 * @param url
 * @param path
 */
void CoverDownloader::saveImage(std::string url, std::string path) {
    std::string host = HttpClientSocket::getHostFromUrl(url);
    std::string serverPath = HttpClientSocket::getServerPathFromUrl(url);      

    HttpClientSocket httpSocket(host, 80);
    httpSocket.connectSocket();

    std::string req = "GET ";
    req += serverPath;
    req += " HTTP/1.1\r\nHost: ";
    req += host;
    req += "\r\n\r\n";

    std::cout << req << std::endl;

    if (!httpSocket.sendRequest(req)) {
        Logger::getInstance()->log(httpSocket.getSocketId(), "REQUEST FOR IMAGE WAS NOT SEND CORRECTLY", LOG_LEVEL_ERROR);
    }

    if (!httpSocket.saveResponseContent(path)) {
        Logger::getInstance()->log(httpSocket.getSocketId(), "COULD NOT SAVE IMAGE", LOG_LEVEL_ERROR);
    }
}
Ejemplo n.º 2
0
void HttpSocket<isServer>::onData(uS::Socket s, char *data, int length) {
    HttpSocket httpSocket(s);
    HttpSocket::Data *httpData = httpSocket.getData();

    httpSocket.cork(true);

    if (httpData->contentLength) {
        httpData->missedDeadline = false;
        if (httpData->contentLength >= length) {
            getGroup<isServer>(s)->httpDataHandler(httpData->outstandingResponsesTail, data, length, httpData->contentLength -= length);
            return;
        } else {
            getGroup<isServer>(s)->httpDataHandler(httpData->outstandingResponsesTail, data, httpData->contentLength, 0);
            data += httpData->contentLength;
            length -= httpData->contentLength;
            httpData->contentLength = 0;
        }
    }

    if (FORCE_SLOW_PATH || httpData->httpBuffer.length()) {
        if (httpData->httpBuffer.length() + length > MAX_HEADER_BUFFER_SIZE) {
            httpSocket.onEnd(s);
            return;
        }

        httpData->httpBuffer.reserve(httpData->httpBuffer.length() + length + WebSocketProtocol<uWS::CLIENT>::CONSUME_POST_PADDING);
        httpData->httpBuffer.append(data, length);
        data = (char *) httpData->httpBuffer.data();
        length = httpData->httpBuffer.length();
    }

    char *end = data + length;
    char *cursor = data;
    *end = '\r';
    Header headers[MAX_HEADERS];
    do {
        char *lastCursor = cursor;
        if ((cursor = getHeaders(cursor, end, headers, MAX_HEADERS))) {
            HttpRequest req(headers);

            if (isServer) {
                headers->valueLength = std::max<int>(0, headers->valueLength - 9);
                httpData->missedDeadline = false;
                if (req.getHeader("upgrade", 7)) {
                    if (getGroup<SERVER>(s)->httpUpgradeHandler) {
                        getGroup<SERVER>(s)->httpUpgradeHandler(HttpSocket<isServer>(s), req);
                    } else {
                        Header secKey = req.getHeader("sec-websocket-key", 17);
                        Header extensions = req.getHeader("sec-websocket-extensions", 24);
                        Header subprotocol = req.getHeader("sec-websocket-protocol", 22);
                        if (secKey.valueLength == 24) {
                            bool perMessageDeflate;
                            httpSocket.upgrade(secKey.value, extensions.value, extensions.valueLength,
                                               subprotocol.value, subprotocol.valueLength, &perMessageDeflate);
                            getGroup<SERVER>(s)->removeHttpSocket(s);
                            s.enterState<WebSocket<SERVER>>(new WebSocket<SERVER>::Data(perMessageDeflate, httpData));
                            getGroup<SERVER>(s)->addWebSocket(s);
                            s.cork(true);
                            getGroup<SERVER>(s)->connectionHandler(WebSocket<SERVER>(s), req);
                            s.cork(false);
                            delete httpData;
                        } else {
                            httpSocket.onEnd(s);
                        }
                    }
                    return;
                } else {
                    if (getGroup<SERVER>(s)->httpRequestHandler) {

                        HttpResponse *res = HttpResponse::allocateResponse(httpSocket, httpData);
                        if (httpData->outstandingResponsesTail) {
                            httpData->outstandingResponsesTail->next = res;
                        } else {
                            httpData->outstandingResponsesHead = res;
                        }
                        httpData->outstandingResponsesTail = res;

                        Header contentLength;
                        if (req.getMethod() != HttpMethod::METHOD_GET && (contentLength = req.getHeader("content-length", 14))) {
                            httpData->contentLength = atoi(contentLength.value);
                            size_t bytesToRead = std::min<int>(httpData->contentLength, end - cursor);
                            getGroup<SERVER>(s)->httpRequestHandler(res, req, cursor, bytesToRead, httpData->contentLength -= bytesToRead);
                            cursor += bytesToRead;
                        } else {
                            getGroup<SERVER>(s)->httpRequestHandler(res, req, nullptr, 0, 0);
                        }

                        if (s.isClosed() || s.isShuttingDown()) {
                            return;
                        }
                    } else {
                        httpSocket.onEnd(s);
                        return;
                    }
                }
            } else {
                if (req.getHeader("upgrade", 7)) {
                    s.enterState<WebSocket<CLIENT>>(new WebSocket<CLIENT>::Data(false, httpData));

                    httpSocket.cancelTimeout();
                    httpSocket.setUserData(httpData->httpUser);
                    getGroup<CLIENT>(s)->addWebSocket(s);
                    s.cork(true);
                    getGroup<CLIENT>(s)->connectionHandler(WebSocket<CLIENT>(s), req);
                    s.cork(false);

                    if (!(s.isClosed() || s.isShuttingDown())) {
                        WebSocketProtocol<CLIENT> *kws = (WebSocketProtocol<CLIENT> *) ((WebSocket<CLIENT>::Data *) s.getSocketData());
                        kws->consume(cursor, end - cursor, s);
                    }

                    delete httpData;
                } else {
                    httpSocket.onEnd(s);
                }
                return;
            }
        } else {
            if (!httpData->httpBuffer.length()) {
                if (length > MAX_HEADER_BUFFER_SIZE) {
                    httpSocket.onEnd(s);
                } else {
                    httpData->httpBuffer.append(lastCursor, end - lastCursor);
                }
            }
            return;
        }
    } while(cursor != end);

    httpSocket.cork(false);
    httpData->httpBuffer.clear();
}
Ejemplo n.º 3
0
/**
 * function to download image form last.fm/api
 * sends one request to obtain album info from
 * witch parses link to image to download.
 * Then updates Qpixmap member in AlbumWidget instance.s
 */
void CoverDownloader::download() {
    HttpClientSocket httpSocket("ws.audioscrobbler.com", 80);

    if (m_artist.empty() || m_albumName.empty()) {
        Logger::getInstance()->log(httpSocket.getSocketId(), "BOTH ARTIST AND ALBUM MUST BE SET", LOG_LEVEL_ERROR);
        return;
    }

    std::string albumTitle = CoverDownloader::escapeStrings(m_albumName);
    std::string artistName = CoverDownloader::escapeStrings(m_artist);

    std::string req = "GET /2.0/?method=album.getinfo&api_key=";
    req += API_KEY;
    req += "&artist=";
    req += artistName;
    req += "&album=";
    req += albumTitle;
    req += " HTTP/1.1\r\nHost: ws.audioscrobbler.com\r\n\r\n";

    std::cout << "REQUEST: " << req << std::endl;

    if (!httpSocket.sendRequest(req)) {
        Logger::getInstance()->log(httpSocket.getSocketId(), "REQUEST WAS NOT SUCCESSFULLY SENT.", LOG_LEVEL_ERROR);
        return;
    }

    std::string response = httpSocket.getResponse();

    if (response.size() < 10) {
        Logger::getInstance()->log(httpSocket.getSocketId(), "RESPONSE HAS INVALID SIZE", LOG_LEVEL_ERROR);
        return;
    }

    std::cout << "RESPONSE: " << response << std::endl;

    size_t pos1 = response.find("<image size=\"extralarge\">");
    size_t pos2 = response.find("</image>", pos1);

    if (pos1 == response.npos || pos2 <= pos1)
        return;

    std::string url = response.substr(pos1 + 25, pos2 - pos1 - 25);
    std::cout << "URL: " << url << std::endl;

    if (url.length() < 5) {
        Logger::getInstance()->log(httpSocket.getSocketId(), "PARSED URL IS INVALID", LOG_LEVEL_ERROR);
        return;
    }

    std::string filename = m_artist + "_" + m_albumName;
    std::string path = "cache/" + filename + url.substr(url.length() - 4);

    saveImage(url, path);
    
    QImage* image = getImage(QString::fromStdString(filename));
    if (image != NULL) {
        Q_EMIT renderedImage(*image);
    } else {
        Logger::getInstance()->log(httpSocket.getSocketId(), "COULD NOT LOAD IMAGE", LOG_LEVEL_ERROR);
    }        
}
Ejemplo n.º 4
0
void HTTPSocket<isServer>::onData(uS::Socket s, char *data, int length) {
    HTTPSocket httpSocket(s);
    HTTPSocket::Data *httpData = httpSocket.getData();

    // 5k = force close!
    if (httpData->httpBuffer.length() + length > 1024 * 5) {
        httpSocket.onEnd(s);
        return;
    }

    httpData->httpBuffer.append(data, length);

    size_t endOfHTTPBuffer = httpData->httpBuffer.find("\r\n\r\n");
    if (endOfHTTPBuffer != std::string::npos) {
        if (isServer) {

            HTTPParser httpParser = (char *) httpData->httpBuffer.data();
            std::pair<char *, size_t> secKey = {}, extensions = {}, subprotocol = {}, path = httpParser.value;
            for (httpParser++; httpParser.key.second; httpParser++) {
                if (httpParser.key.second == 17 || httpParser.key.second == 24 || httpParser.key.second == 22) {
                    // lowercase the key
                    for (size_t i = 0; i < httpParser.key.second; i++) {
                        httpParser.key.first[i] = tolower(httpParser.key.first[i]);
                    }
                    if (!strncmp(httpParser.key.first, "sec-websocket-key", httpParser.key.second)) {
                        secKey = httpParser.value;
                    } else if (!strncmp(httpParser.key.first, "sec-websocket-extensions", httpParser.key.second)) {
                        extensions = httpParser.value;
                    } else if (!strncmp(httpParser.key.first, "sec-websocket-protocol", httpParser.key.second)) {
                        subprotocol = httpParser.value;
                    }
                }
            }

            if (secKey.first && secKey.second == 24) {

                // this needs to be part of upgrade itself, and shared with Hub::upgrade!
                bool perMessageDeflate = false;
                std::string extensionsResponse;
                if (extensions.first) {
                    Group<isServer> *group = (Group<isServer> *) s.getNodeData(s.getSocketData());
                    ExtensionsNegotiator<uWS::SERVER> extensionsNegotiator(group->extensionOptions);
                    extensionsNegotiator.readOffer(std::string(extensions.first, extensions.second));
                    extensionsResponse = extensionsNegotiator.generateOffer();
                    if (extensionsNegotiator.getNegotiatedOptions() & PERMESSAGE_DEFLATE) {
                        perMessageDeflate = true;
                    }
                }

                if (httpSocket.upgrade(secKey.first, extensionsResponse.data(), extensionsResponse.length(), subprotocol.first, subprotocol.second)) {
                    s.cancelTimeout();
                    s.enterState<WebSocket<SERVER>>(new WebSocket<SERVER>::Data(perMessageDeflate, httpData));

                    ((Group<SERVER> *) s.getSocketData()->nodeData)->addWebSocket(s);
                    //s.cork(true);
                    ((Group<SERVER> *) s.getSocketData()->nodeData)->connectionHandler(WebSocket<SERVER>(s), {path.first, subprotocol.first,
                                                                                                              path.second, subprotocol.second});
                    //s.cork(false);
                    delete httpData;
                }
            } else {
                httpSocket.onEnd(s);
            }
        } else {
            httpData->httpBuffer.resize(httpData->httpBuffer.length() + WebSocketProtocol<uWS::CLIENT>::CONSUME_POST_PADDING);

            bool isUpgrade = false;
            HTTPParser httpParser = (char *) httpData->httpBuffer.data();
            //std::pair<char *, size_t> secKey = {}, extensions = {};
            for (httpParser++; httpParser.key.second; httpParser++) {
                if (httpParser.key.second == 7) {
                    // lowercase the key
                    for (size_t i = 0; i < httpParser.key.second; i++) {
                        httpParser.key.first[i] = tolower(httpParser.key.first[i]);
                    }
                    // lowercase the value
                    for (size_t i = 0; i < httpParser.value.second; i++) {
                        httpParser.value.first[i] = tolower(httpParser.value.first[i]);
                    }
                    if (!strncmp(httpParser.key.first, "upgrade", httpParser.key.second)) {
                        if (!strncmp(httpParser.value.first, "websocket", 9)) {
                            isUpgrade = true;
                        }
                        break;
                    }
                }
            }

            if (isUpgrade) {
                s.enterState<WebSocket<CLIENT>>(new WebSocket<CLIENT>::Data(false, httpData));

                //s.cork(true);
                httpSocket.cancelTimeout();
                httpSocket.setUserData(httpData->httpUser);
                ((Group<CLIENT> *) s.getSocketData()->nodeData)->addWebSocket(s);
                ((Group<CLIENT> *) s.getSocketData()->nodeData)->connectionHandler(WebSocket<CLIENT>(s), {nullptr, nullptr, 0, 0});
                //s.cork(false);

                if (!(s.isClosed() || s.isShuttingDown())) {
                    WebSocketProtocol<CLIENT> *kws = (WebSocketProtocol<CLIENT> *) ((WebSocket<CLIENT>::Data *) s.getSocketData());
                    kws->consume((char *) httpData->httpBuffer.data() + endOfHTTPBuffer + 4, httpData->httpBuffer.length() - endOfHTTPBuffer - 4 - WebSocketProtocol<uWS::CLIENT>::CONSUME_POST_PADDING, s);
                }

                delete httpData;
            } else {
                httpSocket.onEnd(s);
            }
        }
    }
}