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; } } }
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; } } }
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); } }