package com.limegroup.gnutella.uploader; import java.util.Collections; import junit.framework.Test; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.message.BasicHttpRequest; import org.apache.http.message.BasicHttpResponse; import org.apache.http.protocol.BasicHttpContext; import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.States; import org.limewire.gnutella.tests.LimeTestCase; import org.limewire.gnutella.tests.LimeTestUtils; import org.limewire.gnutella.tests.NetworkManagerStub; import org.limewire.io.ConnectableImpl; import com.google.inject.AbstractModule; import com.google.inject.Inject; import com.google.inject.Injector; import com.limegroup.gnutella.ConnectionManager; import com.limegroup.gnutella.NetworkManager; import com.limegroup.gnutella.URN; import com.limegroup.gnutella.http.HTTPHeaderName; import com.limegroup.gnutella.library.FileCollection; import com.limegroup.gnutella.library.FileDesc; import com.limegroup.gnutella.library.FileDescStub; import com.limegroup.gnutella.library.GnutellaFiles; import com.limegroup.gnutella.library.LibraryStubModule; import com.limegroup.gnutella.stubs.ConnectionManagerStub; import com.limegroup.gnutella.tigertree.HashTree; import com.limegroup.gnutella.tigertree.HashTreeCache; import com.limegroup.gnutella.uploader.authentication.GnutellaUploadFileViewProvider; public class FileRequestHandlerTest extends LimeTestCase { private FileDesc fd = new FileDescStub("filename"); private URN urn1; private MockHTTPUploadSessionManager sessionManager; private FileRequestHandler fileRequestHandler; @Inject private Injector injector; @Inject @GnutellaFiles private FileCollection gnutellaFileCollection; private Mockery context; private HashTreeCache hashTreeCache; private States states; public FileRequestHandlerTest(String name) { super(name); } public static Test suite() { return buildTestSuite(FileRequestHandlerTest.class); } @Override protected void setUp() throws Exception { context = new Mockery(); hashTreeCache = context.mock(HashTreeCache.class); states = context.states("").startsAs("default"); context.checking(new Expectations() {{ allowing(hashTreeCache).getHashTree(with(any(FileDesc.class))); will(returnValue(null)); when(states.is("default")); }}); sessionManager = new MockHTTPUploadSessionManager(); LimeTestUtils.createInjectorNonEagerly(new AbstractModule() { @Override protected void configure() { bind(ConnectionManager.class).to(ConnectionManagerStub.class); bind(HTTPUploadSessionManager.class).toInstance(sessionManager); bind(NetworkManager.class).to(NetworkManagerStub.class); bind(HashTreeCache.class).toInstance(hashTreeCache); } }, new LibraryStubModule(), LimeTestUtils.createModule(this)); ConnectionManagerStub connectionManager = (ConnectionManagerStub) injector .getInstance(ConnectionManager.class); connectionManager.setPushProxies(Collections.singleton(new ConnectableImpl("127.0.0.1", 9999, false))); urn1 = URN.createSHA1Urn("urn:sha1:PLSTHIPQGSSZTS5FJUPAKUZWUGYQYPFG"); FileDesc fd1 = new FileDescStub("abc1.txt", urn1, 0); gnutellaFileCollection.add(fd1); GnutellaUploadFileViewProvider uploadProvider = injector.getInstance(GnutellaUploadFileViewProvider.class); fileRequestHandler = injector.getInstance(FileRequestHandlerFactory.class).createFileRequestHandler(uploadProvider, false); } public void testHandleAccept() throws Exception { HttpRequest request = new BasicHttpRequest("GET", "filename"); HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, ""); HTTPUploader uploader = new HTTPUploader("filename", null); // setting host to a value, so we don't need to specify a session uploader.setHost("somehost"); uploader.setFileDesc(fd); NetworkManagerStub networkManager = (NetworkManagerStub) injector .getInstance(NetworkManager.class); networkManager.setCanDoFWT(true); fileRequestHandler.handleAccept(new BasicHttpContext(null), request, response, uploader, fd, null); Header header = response.getFirstHeader(HTTPHeaderName.FWTPORT.httpStringValue()); assertNotNull("expected header: " + HTTPHeaderName.FWTPORT.httpStringValue(), header); assertEquals(networkManager.getStableUDPPort() + "", header.getValue()); } public void testFeatureHeaderInterceptor() throws Exception { HTTPUploadSession session = new HTTPUploadSession(null, null, null); HTTPUploader uploader = new HTTPUploader("filename", session); // setting host to a value, so we don't need to specify a session uploader.setHost("somehost"); uploader.setFileDesc(fd); sessionManager.uploader = uploader; HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, ""); HttpRequest request = new BasicHttpRequest("GET", LimeTestUtils.getRelativeRequest(urn1)); request.addHeader("X-Features", "fwalt/0.1,browse/1.0,chat/0.1"); request.addHeader("X-Node", "127.0.0.1:1234"); request.addHeader("X-Downloaded", "123456"); request.addHeader("Range", "bytes 1-2"); request.addHeader("X-Gnutella-Content-URN", urn1.httpStringValue()); request.addHeader("X-Queue", "1.0"); fileRequestHandler.handle(request, response, new BasicHttpContext(null)); assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); assertEquals(1234, uploader.getGnutellaPort()); assertEquals("127.0.0.1", uploader.getHost()); assertTrue(uploader.isBrowseHostEnabled()); assertEquals(123456, uploader.getTotalAmountUploaded()); assertEquals(1, uploader.getUploadBegin()); assertEquals(3, uploader.getUploadEnd()); assertEquals(true, uploader.containedRangeRequest()); assertEquals(urn1, uploader.getRequestedURN()); assertTrue(uploader.supportsQueueing()); } /** * Tests if browse host is enabled on the uploader if the downloader sent * its push endpoint information along in the X-FWT-Node header. */ public void testIsFWTBrowseHostEnabled() throws Exception { HTTPUploadSession session = new HTTPUploadSession(null, null, null); HTTPUploader uploader = new HTTPUploader("filename", session); // setting host to a value, so we don't need to specify a session uploader.setHost("somehost"); uploader.setFileDesc(fd); sessionManager.uploader = uploader; HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, ""); HttpRequest request = new BasicHttpRequest("GET", LimeTestUtils.getRelativeRequest(urn1)); String pushEndpoint = "FF9EEA9E8B2E1D737828EFD1B7DAC500;129.168.0.1:5555"; request.addHeader(HTTPHeaderName.FW_NODE_INFO.create(pushEndpoint)); fileRequestHandler.handle(request, response, new BasicHttpContext(null)); assertTrue(uploader.isBrowseHostEnabled()); assertEquals(pushEndpoint, uploader.getPushEndpoint().httpStringValue()); } public void testResponseContainsThexUriHeader() throws Exception { HttpRequest request = new BasicHttpRequest("GET", "filename"); HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, ""); HTTPUploader uploader = new HTTPUploader("filename", null); // setting host to a value, so we don't need to specify a session uploader.setHost("somehost"); uploader.setFileDesc(fd); final HashTree hashTree = context.mock(HashTree.class); context.checking(new Expectations() {{ one(hashTreeCache).getHashTree(fd); will(returnValue(hashTree)); one(hashTree).httpStringValue(); will(returnValue("/uri-res/N2X?hash-tree-httpstring")); }}); // switch state to allow expectations here to kick in states.is("non-default").activate(); fileRequestHandler.handleAccept(new BasicHttpContext(null), request, response, uploader, fd, null); Header header = response.getFirstHeader("X-Thex-URI"); assertNotNull(header); assertEquals("/uri-res/N2X?hash-tree-httpstring", header.getValue()); context.assertIsSatisfied(); } public void testResponseContainsCorrectFriendThexUriHeader() throws Exception { HttpRequest request = new BasicHttpRequest("GET", "filename"); HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, ""); HTTPUploader uploader = new HTTPUploader("filename", null); // setting host to a value, so we don't need to specify a session uploader.setHost("somehost"); uploader.setFileDesc(fd); final HashTree hashTree = context.mock(HashTree.class); context.checking(new Expectations() {{ one(hashTreeCache).getHashTree(fd); will(returnValue(hashTree)); one(hashTree).httpStringValue(); will(returnValue("/uri-res/N2X?hash-tree-httpstring")); }}); // switch state to allow expectations here to kick in states.is("non-default").activate(); fileRequestHandler.handleAccept(new BasicHttpContext(null), request, response, uploader, fd, "friend@id"); Header header = response.getFirstHeader("X-Thex-URI"); assertNotNull(header); assertEquals("/friend/download/friend%40id/uri-res/N2X?hash-tree-httpstring", header.getValue()); context.assertIsSatisfied(); } }