Exemple #1
0
void Loader::Host::servePendingRequests(RequestQueue& requestsPending)
{
    while (m_requestsLoading.size() < m_maxRequestsInFlight && !requestsPending.isEmpty()) {        
        Request* request = requestsPending.first();
        requestsPending.removeFirst();

        DocLoader* docLoader = request->docLoader();
        
        ResourceRequest resourceRequest(request->cachedResource()->url());
        
        if (!request->cachedResource()->accept().isEmpty())
            resourceRequest.setHTTPAccept(request->cachedResource()->accept());
        
        KURL referrer = docLoader->doc()->url();
        if ((referrer.protocolIs("http") || referrer.protocolIs("https")) && referrer.path().isEmpty())
            referrer.setPath("/");
        resourceRequest.setHTTPReferrer(referrer.string());

        RefPtr<SubresourceLoader> loader = SubresourceLoader::create(docLoader->doc()->frame(),
                                                                     this, resourceRequest, request->shouldSkipCanLoadCheck(), request->sendResourceLoadCallbacks());
        if (loader) {
            m_requestsLoading.add(loader.release(), request);
            request->cachedResource()->setRequestedFromNetworkingLayer();
#if REQUEST_DEBUG
            printf("HOST %s COUNT %d LOADING %s\n", resourceRequest.url().host().latin1().data(), m_requestsLoading.size(), request->cachedResource()->url().latin1().data());
#endif
        } else {            
            docLoader->decrementRequestCount();
            docLoader->setLoadInProgress(true);
            request->cachedResource()->error();
            docLoader->setLoadInProgress(false);
            delete request;
        }
    }
}
void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& serveLowerPriority)
{
    while (!requestsPending.isEmpty()) {        
        Request* request = requestsPending.first();
        DocLoader* docLoader = request->docLoader();
        bool resourceIsCacheValidator = request->cachedResource()->isCacheValidator();

        // For named hosts - which are only http(s) hosts - we should always enforce the connection limit.
        // For non-named hosts - everything but http(s) - we should only enforce the limit if the document isn't done parsing 
        // and we don't know all stylesheets yet.
        bool shouldLimitRequests = !m_name.isNull() || docLoader->doc()->parsing() || !docLoader->doc()->haveStylesheetsLoaded();
        if (shouldLimitRequests && m_requestsLoading.size() + m_nonCachedRequestsInFlight >= m_maxRequestsInFlight) {
            serveLowerPriority = false;
            cache()->loader()->scheduleServePendingRequests();
            return;
        }
        requestsPending.removeFirst();
        
        ResourceRequest resourceRequest(request->cachedResource()->url());
        resourceRequest.setTargetType(cachedResourceTypeToTargetType(request->cachedResource()->type()));
        
        if (!request->cachedResource()->accept().isEmpty())
            resourceRequest.setHTTPAccept(request->cachedResource()->accept());
        
         // Do not set the referrer or HTTP origin here. That's handled by SubresourceLoader::create.
        
        if (resourceIsCacheValidator) {
            CachedResource* resourceToRevalidate = request->cachedResource()->resourceToRevalidate();
            ASSERT(resourceToRevalidate->canUseCacheValidator());
            ASSERT(resourceToRevalidate->isLoaded());
            const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified");
            const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag");
            if (!lastModified.isEmpty() || !eTag.isEmpty()) {
                ASSERT(docLoader->cachePolicy() != CachePolicyReload);
                if (docLoader->cachePolicy() == CachePolicyRevalidate)
                    resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0");
                if (!lastModified.isEmpty())
                    resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified);
                if (!eTag.isEmpty())
                    resourceRequest.setHTTPHeaderField("If-None-Match", eTag);
            }
        }

        RefPtr<SubresourceLoader> loader = SubresourceLoader::create(docLoader->doc()->frame(),
            this, resourceRequest, request->shouldDoSecurityCheck(), request->sendResourceLoadCallbacks());
        if (loader) {
            m_requestsLoading.add(loader.release(), request);
            request->cachedResource()->setRequestedFromNetworkingLayer();
#if REQUEST_DEBUG
            printf("HOST %s COUNT %d LOADING %s\n", resourceRequest.url().host().latin1().data(), m_requestsLoading.size(), request->cachedResource()->url().latin1().data());
#endif
        } else {            
            docLoader->decrementRequestCount();
            docLoader->setLoadInProgress(true);
            request->cachedResource()->error();
            docLoader->setLoadInProgress(false);
            delete request;
        }
    }
}
Exemple #3
0
void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& serveLowerPriority)
{
    while (!requestsPending.isEmpty()) {        
        Request* request = requestsPending.first();
        DocLoader* docLoader = request->docLoader();
        bool resourceIsCacheValidator = request->cachedResource()->isCacheValidator();
        // If the document is fully parsed and there are no pending stylesheets there won't be any more 
        // resources that we would want to push to the front of the queue. Just hand off the remaining resources
        // to the networking layer.
        bool parsedAndStylesheetsKnown = !docLoader->doc()->parsing() && docLoader->doc()->haveStylesheetsLoaded();
        if (!parsedAndStylesheetsKnown && !resourceIsCacheValidator && m_requestsLoading.size() >= m_maxRequestsInFlight) {
            serveLowerPriority = false;
            return;
        }
        requestsPending.removeFirst();
        
        ResourceRequest resourceRequest(request->cachedResource()->url());
        
        if (!request->cachedResource()->accept().isEmpty())
            resourceRequest.setHTTPAccept(request->cachedResource()->accept());
        
        KURL referrer = docLoader->doc()->url();
        if ((referrer.protocolIs("http") || referrer.protocolIs("https")) && referrer.path().isEmpty())
            referrer.setPath("/");
        resourceRequest.setHTTPReferrer(referrer.string());
        FrameLoader::addHTTPOriginIfNeeded(resourceRequest, docLoader->doc()->securityOrigin()->toString());
        
        if (resourceIsCacheValidator) {
            CachedResource* resourceToRevalidate = request->cachedResource()->resourceToRevalidate();
            ASSERT(resourceToRevalidate->canUseCacheValidator());
            ASSERT(resourceToRevalidate->isLoaded());
            const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified");
            const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag");
            if (!lastModified.isEmpty() || !eTag.isEmpty()) {
                ASSERT(docLoader->cachePolicy() != CachePolicyReload);
                if (docLoader->cachePolicy() == CachePolicyRevalidate)
                    resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0");
                if (!lastModified.isEmpty())
                    resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified);
                if (!eTag.isEmpty())
                    resourceRequest.setHTTPHeaderField("If-None-Match", eTag);
            }
        }

        RefPtr<SubresourceLoader> loader = SubresourceLoader::create(docLoader->doc()->frame(),
                                                                     this, resourceRequest, request->shouldSkipCanLoadCheck(), request->sendResourceLoadCallbacks());
        if (loader) {
            m_requestsLoading.add(loader.release(), request);
            request->cachedResource()->setRequestedFromNetworkingLayer();
#if REQUEST_DEBUG
            printf("HOST %s COUNT %d LOADING %s\n", resourceRequest.url().host().latin1().data(), m_requestsLoading.size(), request->cachedResource()->url().latin1().data());
#endif
        } else {            
            docLoader->decrementRequestCount();
            docLoader->setLoadInProgress(true);
            request->cachedResource()->error();
            docLoader->setLoadInProgress(false);
            delete request;
        }
    }
}
Exemple #4
0
    void mainloop(){
    
    rio_t rp_client, rp_server;
    int  hostport;
    char hostname[MAXLINE], pathname[MAXLINE];
    char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE];
    while (1) {
        char buffer[MAX_UINT];
        while (queue->isEmpty()) {
            sleep(1);
            continue;
        }
        clientsock = queue->Pop();
        if(clientsock == -1){
            //printf("Fake Client sockID:%d \n", clientsock);
            continue;
        }
        //printf("Get Client sockID:%d \n", clientsock);
        // Init read structure for client-proxy connection
        Rio_readinitb(&rp_client, clientsock);
        
        // Parse the HTTP request
        read_requesthdrs(&rp_client, method, uri, version);
        
        // Parse the URI of the request
        parse_uri(uri, hostname, pathname, &hostport);
        //printf("%s %s %d\n", hostname, pathname, hostport);
        /*****  If method is GET *****/
        if (strcmp(method, "GET")!=0) {
            char buf2[] = "500 'Internal Error' \r\n";
            Rio_writenb_w(clientsock, buf2, strlen(buf2));
            //printf("It is not GET method:%s socket:%d \n", method, clientsock);
            Rio_close(clientsock);
            continue;
        }
        
#ifdef WITH_CACHE
        //find url in cache and return [FIXME]
        if(pmap->find(uri)!=pmap->end()){ //not found the topic
            
            proxy_cache *pcache = (*pmap)[uri];
            
            for (int i =0; i<pcache->size; i++) {
                Rio_writen_w(clientsock, pcache->buf[i], strlen(pcache->buf[i]));
            }
            Rio_close(clientsock);
            continue;
        }
        // Make cache entry [FIXME]
        proxy_cache *pcache = new proxy_cache();
        std::string urlstr = *new std::string(uri);
        std::pair<std::string, proxy_cache *> newpair(urlstr,pcache);
        pmap->insert(newpair);
#endif
        // Open connection to requested web server
        char strport[10]={0};
        sprintf(strport, "%d",hostport);
        proxysock = open_targetfd(hostname, strport);
        
        if (proxysock < 0) {
            char buf2[] = "500 'Internal Error' \r\n";
            Rio_writenb_w(clientsock, buf2, strlen(buf2));
            Rio_close(clientsock);
            continue;
        }
        
        // Init read struct for proxy-webserver connection
        Rio_readinitb(&rp_server, proxysock);
        
        sprintf(buf, "%s %s %s\r\n", method, pathname, "HTTP/1.0");
        Rio_writenb_w(proxysock, buf, strlen(buf));
        //printf("%s", buf);
        sprintf(buf, "Host: %s\r\n", hostname);
        Rio_writenb_w(proxysock, buf, strlen(buf));
        //printf("%s", buf);

        // Read from client request
        // and write to web server
        while(strcmp(buf, "\r\n")) {
            Rio_readlineb_w(&rp_client, buf, MAXLINE);
            
            if (!strcmp(buf, "\r\n")) {
                char buf2[] = "Connection: close\r\n";
                Rio_writenb_w(proxysock, buf2, strlen(buf2));
                //printf("%s", buf2);
            }
            if (!strncmp(buf, "Connection: keep-alive", 22) ||
                !strncmp(buf, "Host:", 5)) {
                //printf("%s", buf);
                continue;
            }
            
            Rio_writenb_w(proxysock, buf, strlen(buf));
            //printf("%s", buf);
            
        }
        
        // Read the respons from webserver and
        // forward it to the requesting client
        ssize_t n = 0;
        while ((n = Rio_readnb_w(proxysock, buffer, MAX_UINT)) > 0) {
#ifdef WITH_CACHE
            char *cache = (char*)malloc(sizeof(char)*(n+1));
            if(cache == NULL){
                perror("Alloc memory failed, cache emited");
            }
            memset(cache, 0, n+1);
            strncpy(cache,buffer,n);
#endif
            Rio_writenb_w(clientsock, buffer, n);
            
        }
        
        Rio_close(clientsock);
        Rio_close(proxysock);
    }
}