diff --git a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServer.java b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServer.java index 3cca83eac53..17be09ea1f3 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServer.java +++ b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServer.java @@ -585,23 +585,21 @@ public class HttpFSServer { switch (op.value()) { case APPEND: { Boolean hasData = params.get(DataParam.NAME, DataParam.class); - if (!hasData) { - URI redirectURL = createUploadRedirectionURL( - uriInfo, HttpFSFileSystem.Operation.APPEND); - Boolean noRedirect = params.get( - NoRedirectParam.NAME, NoRedirectParam.class); - if (noRedirect) { + URI redirectURL = createUploadRedirectionURL(uriInfo, + HttpFSFileSystem.Operation.APPEND); + Boolean noRedirect = + params.get(NoRedirectParam.NAME, NoRedirectParam.class); + if (noRedirect) { final String js = JsonUtil.toJsonString("Location", redirectURL); response = Response.ok(js).type(MediaType.APPLICATION_JSON).build(); - } else { - response = Response.temporaryRedirect(redirectURL).build(); - } - } else { + } else if (hasData) { FSOperations.FSAppend command = new FSOperations.FSAppend(is, path); fsExecute(user, command); AUDIT_LOG.info("[{}]", path); response = Response.ok().type(MediaType.APPLICATION_JSON).build(); + } else { + response = Response.temporaryRedirect(redirectURL).build(); } break; } @@ -662,7 +660,8 @@ public class HttpFSServer { protected URI createUploadRedirectionURL(UriInfo uriInfo, Enum uploadOperation) { UriBuilder uriBuilder = uriInfo.getRequestUriBuilder(); uriBuilder = uriBuilder.replaceQueryParam(OperationParam.NAME, uploadOperation). - queryParam(DataParam.NAME, Boolean.TRUE); + queryParam(DataParam.NAME, Boolean.TRUE) + .replaceQueryParam(NoRedirectParam.NAME, (Object[]) null); return uriBuilder.build(null); } @@ -726,18 +725,14 @@ public class HttpFSServer { switch (op.value()) { case CREATE: { Boolean hasData = params.get(DataParam.NAME, DataParam.class); - if (!hasData) { - URI redirectURL = createUploadRedirectionURL( - uriInfo, HttpFSFileSystem.Operation.CREATE); - Boolean noRedirect = params.get( - NoRedirectParam.NAME, NoRedirectParam.class); - if (noRedirect) { + URI redirectURL = createUploadRedirectionURL(uriInfo, + HttpFSFileSystem.Operation.CREATE); + Boolean noRedirect = + params.get(NoRedirectParam.NAME, NoRedirectParam.class); + if (noRedirect) { final String js = JsonUtil.toJsonString("Location", redirectURL); response = Response.ok(js).type(MediaType.APPLICATION_JSON).build(); - } else { - response = Response.temporaryRedirect(redirectURL).build(); - } - } else { + } else if (hasData) { Short permission = params.get(PermissionParam.NAME, PermissionParam.class); Short unmaskedPermission = params.get(UnmaskedPermissionParam.NAME, @@ -761,6 +756,8 @@ public class HttpFSServer { "Location", uriInfo.getAbsolutePath()); response = Response.created(uriInfo.getAbsolutePath()) .type(MediaType.APPLICATION_JSON).entity(js).build(); + } else { + response = Response.temporaryRedirect(redirectURL).build(); } break; } diff --git a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSServer.java b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSServer.java index da708059986..ae7e2c42ae4 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSServer.java +++ b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSServer.java @@ -1565,7 +1565,7 @@ public class TestHttpFSServer extends HFSTestCase { new InputStreamReader(conn.getInputStream())); String location = (String)json.get("Location"); Assert.assertTrue(location.contains(DataParam.NAME)); - Assert.assertTrue(location.contains(NoRedirectParam.NAME)); + Assert.assertFalse(location.contains(NoRedirectParam.NAME)); Assert.assertTrue(location.contains("CREATE")); Assert.assertTrue("Wrong location: " + location, location.startsWith(TestJettyHelper.getJettyURL().toString())); @@ -1834,4 +1834,50 @@ public class TestHttpFSServer extends HFSTestCase { assertTrue( xAttrs.containsKey(HdfsServerConstants.XATTR_SATISFY_STORAGE_POLICY)); } + + @Test + @TestDir + @TestJetty + @TestHdfs + public void testNoRedirectWithData() throws Exception { + createHttpFSServer(false, false); + + final String path = "/file"; + final String username = HadoopUsersConfTestHelper.getHadoopUsers()[0]; + // file creation which should not redirect + URL url = new URL(TestJettyHelper.getJettyURL(), + MessageFormat.format( + "/webhdfs/v1{0}?user.name={1}&op=CREATE&data=true&noredirect=true", + path, username)); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod(HttpMethod.PUT); + conn.setRequestProperty("Content-Type", MediaType.APPLICATION_OCTET_STREAM); + conn.setDoOutput(true); + conn.connect(); + Assert.assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); + JSONObject json = (JSONObject) new JSONParser() + .parse(new InputStreamReader(conn.getInputStream())); + + // get the location to write + String location = (String) json.get("Location"); + Assert.assertTrue(location.contains(DataParam.NAME)); + Assert.assertTrue(location.contains("CREATE")); + url = new URL(location); + conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod(HttpMethod.PUT); + conn.setRequestProperty("Content-Type", MediaType.APPLICATION_OCTET_STREAM); + conn.setDoOutput(true); + conn.connect(); + final String writeStr = "write some content"; + OutputStream os = conn.getOutputStream(); + os.write(writeStr.getBytes()); + os.close(); + // Verify that file got created + Assert.assertEquals(HttpURLConnection.HTTP_CREATED, conn.getResponseCode()); + json = (JSONObject) new JSONParser() + .parse(new InputStreamReader(conn.getInputStream())); + location = (String) json.get("Location"); + Assert.assertEquals(TestJettyHelper.getJettyURL() + "/webhdfs/v1" + path, + location); + } }