@@ -1950,6 +1950,132 @@ public void testCreationWithUploadChecksumMismatch() throws Exception {
19501950 assertResponseStatus (460 ); // Checksum mismatch
19511951 }
19521952
1953+ @ Test
1954+ public void testUploadWithAbsoluteUploadUri () throws Exception {
1955+ String absoluteBaseUri = "https://uploads.example.com" ;
1956+ TusFileUploadService service = createTusFileUploadService (absoluteBaseUri );
1957+
1958+ String uploadContent = "Absolute URL upload content" ;
1959+
1960+ // Step 1: POST to create upload on root endpoint "/"
1961+ servletRequest .setMethod ("POST" );
1962+ servletRequest .setRequestURI ("/" );
1963+ servletRequest .addHeader (HttpHeader .CONTENT_LENGTH , 0 );
1964+ servletRequest .addHeader (HttpHeader .UPLOAD_LENGTH , uploadContent .getBytes ().length );
1965+ servletRequest .addHeader (HttpHeader .TUS_RESUMABLE , "1.0.0" );
1966+
1967+ service .process (servletRequest , servletResponse , OWNER_KEY );
1968+ assertResponseStatus (HttpServletResponse .SC_CREATED );
1969+ assertResponseHeader (HttpHeader .TUS_RESUMABLE , "1.0.0" );
1970+ String locationHeader = servletResponse .getHeader (HttpHeader .LOCATION );
1971+ assertResponseHeaderNotBlank (HttpHeader .LOCATION );
1972+
1973+ // Retrieve upload info using the full Location header to verify ID lookup works with absolute
1974+ // URLs
1975+ UploadInfo infoByLocation = service .getUploadInfo (locationHeader , OWNER_KEY );
1976+ assertTrue (infoByLocation != null && infoByLocation .getId () != null );
1977+ assertThat (locationHeader , is ("https://uploads.example.com/" + infoByLocation .getId ()));
1978+
1979+ String uploadPath = "/" + infoByLocation .getId ();
1980+
1981+ // Step 2: PATCH bytes to the upload resource
1982+ reset ();
1983+ servletRequest .setMethod ("PATCH" );
1984+ servletRequest .setRequestURI (uploadPath );
1985+ servletRequest .addHeader (HttpHeader .CONTENT_TYPE , "application/offset+octet-stream" );
1986+ servletRequest .addHeader (HttpHeader .CONTENT_LENGTH , uploadContent .getBytes ().length );
1987+ servletRequest .addHeader (HttpHeader .UPLOAD_OFFSET , 0 );
1988+ servletRequest .addHeader (HttpHeader .TUS_RESUMABLE , "1.0.0" );
1989+ servletRequest .setContent (uploadContent .getBytes ());
1990+
1991+ service .process (servletRequest , servletResponse , OWNER_KEY );
1992+ assertResponseStatus (HttpServletResponse .SC_NO_CONTENT );
1993+ assertResponseHeader (HttpHeader .UPLOAD_OFFSET , "" + uploadContent .getBytes ().length );
1994+
1995+ // Step 3: HEAD request to verify completion
1996+ reset ();
1997+ servletRequest .setMethod ("HEAD" );
1998+ servletRequest .setRequestURI (uploadPath );
1999+ servletRequest .addHeader (HttpHeader .TUS_RESUMABLE , "1.0.0" );
2000+
2001+ service .process (servletRequest , servletResponse , OWNER_KEY );
2002+ assertResponseStatus (HttpServletResponse .SC_NO_CONTENT );
2003+ assertResponseHeader (HttpHeader .UPLOAD_OFFSET , "" + uploadContent .getBytes ().length );
2004+ assertResponseHeader (HttpHeader .UPLOAD_LENGTH , "" + uploadContent .getBytes ().length );
2005+
2006+ // Verify upload info is also retrievable via relative path
2007+ UploadInfo infoByPath = service .getUploadInfo (uploadPath , OWNER_KEY );
2008+ assertTrue (infoByPath != null && infoByLocation .getId ().equals (infoByPath .getId ()));
2009+
2010+ // Step 4: Verify uploaded bytes
2011+ try (InputStream stream = service .getUploadedBytes (uploadPath , OWNER_KEY )) {
2012+ assertThat (IOUtils .toString (stream , StandardCharsets .UTF_8 ), is (uploadContent ));
2013+ }
2014+ }
2015+
2016+ @ Test
2017+ public void testUploadWithAbsoluteUploadUriWithPath () throws Exception {
2018+ String absoluteBaseUri = "https://uploads.example.com/api" ;
2019+ TusFileUploadService service = createTusFileUploadService (absoluteBaseUri );
2020+
2021+ String uploadContent = "Absolute URL with path upload content" ;
2022+
2023+ // Step 1: POST to create upload on endpoint "/api"
2024+ servletRequest .setMethod ("POST" );
2025+ servletRequest .setRequestURI ("/api" );
2026+ servletRequest .addHeader (HttpHeader .CONTENT_LENGTH , 0 );
2027+ servletRequest .addHeader (HttpHeader .UPLOAD_LENGTH , uploadContent .getBytes ().length );
2028+ servletRequest .addHeader (HttpHeader .TUS_RESUMABLE , "1.0.0" );
2029+
2030+ service .process (servletRequest , servletResponse , OWNER_KEY );
2031+ assertResponseStatus (HttpServletResponse .SC_CREATED );
2032+ assertResponseHeader (HttpHeader .TUS_RESUMABLE , "1.0.0" );
2033+ String locationHeader = servletResponse .getHeader (HttpHeader .LOCATION );
2034+ assertResponseHeaderNotBlank (HttpHeader .LOCATION );
2035+
2036+ // Retrieve upload info using the full Location header to verify ID lookup works with absolute
2037+ // URLs
2038+ UploadInfo infoByLocation = service .getUploadInfo (locationHeader , OWNER_KEY );
2039+ assertTrue (infoByLocation != null && infoByLocation .getId () != null );
2040+ assertThat (locationHeader , is ("https://uploads.example.com/api/" + infoByLocation .getId ()));
2041+
2042+ String uploadPath = "/api/" + infoByLocation .getId ();
2043+
2044+ // Step 2: PATCH bytes to the upload resource
2045+ reset ();
2046+ servletRequest .setMethod ("PATCH" );
2047+ servletRequest .setRequestURI (uploadPath );
2048+ servletRequest .addHeader (HttpHeader .CONTENT_TYPE , "application/offset+octet-stream" );
2049+ servletRequest .addHeader (HttpHeader .CONTENT_LENGTH , uploadContent .getBytes ().length );
2050+ servletRequest .addHeader (HttpHeader .UPLOAD_OFFSET , 0 );
2051+ servletRequest .addHeader (HttpHeader .TUS_RESUMABLE , "1.0.0" );
2052+ servletRequest .setContent (uploadContent .getBytes ());
2053+
2054+ service .process (servletRequest , servletResponse , OWNER_KEY );
2055+ assertResponseStatus (HttpServletResponse .SC_NO_CONTENT );
2056+ assertResponseHeader (HttpHeader .UPLOAD_OFFSET , "" + uploadContent .getBytes ().length );
2057+
2058+ // Step 3: HEAD request to verify completion
2059+ reset ();
2060+ servletRequest .setMethod ("HEAD" );
2061+ servletRequest .setRequestURI (uploadPath );
2062+ servletRequest .addHeader (HttpHeader .TUS_RESUMABLE , "1.0.0" );
2063+
2064+ service .process (servletRequest , servletResponse , OWNER_KEY );
2065+ assertResponseStatus (HttpServletResponse .SC_NO_CONTENT );
2066+ assertResponseHeader (HttpHeader .UPLOAD_OFFSET , "" + uploadContent .getBytes ().length );
2067+ assertResponseHeader (HttpHeader .UPLOAD_LENGTH , "" + uploadContent .getBytes ().length );
2068+
2069+ // Verify upload info is also retrievable via relative path
2070+ UploadInfo infoByPath = service .getUploadInfo (uploadPath , OWNER_KEY );
2071+ assertTrue (infoByPath != null && infoByLocation .getId ().equals (infoByPath .getId ()));
2072+
2073+ // Step 4: Verify uploaded bytes
2074+ try (InputStream stream = service .getUploadedBytes (uploadPath , OWNER_KEY )) {
2075+ assertThat (IOUtils .toString (stream , StandardCharsets .UTF_8 ), is (uploadContent ));
2076+ }
2077+ }
2078+
19532079 protected void assertResponseHeader (final String header , final String value ) {
19542080 assertThat (servletResponse .getHeader (header ), is (value ));
19552081 }
0 commit comments