s-w-i-t rollback
@@ -596,7 +596,32 @@ public class NugetArtifactController extends BaseArtifactController
OutputStream packagePartOutputStream)
throws IOException
{
- MultipartStream multipartStream = new MultipartStream(is, boundaryString.getBytes(), 4096, null);
+ // According to the specification, the final Boundary of MultipartStream should be prefixed with
+ // `0x0D0x0A0x2D0x2D` characters, but seems that Nuget command line tool has broken Multipart Boundary format.
+ // We need to fix missing starting byte of ending Mulipart boundary (0x0D), which is incorrectly generated by
+ // NuGet `push` implementation.
+ byte[] boundary = boundaryString.getBytes();
+ byte[] boundaryPrefixToFix = {0x00, 0x0A, 0x2D, 0x2D};
+ byte[] boundaryPrefixTarget = {0x00, 0x0D, 0x0A, 0x2D, 0x2D};
+
+ byte[] replacementPattern = new byte[boundary.length + 4];
+ byte[] replacementTarget = new byte[boundary.length + 5];
+
+ System.arraycopy(boundaryPrefixToFix, 0, replacementPattern, 0, 4);
+ System.arraycopy(boundaryPrefixTarget, 0, replacementTarget, 0, 5);
+
+ System.arraycopy(boundary, 0, replacementPattern, 4, boundary.length);
+ System.arraycopy(boundary, 0, replacementTarget, 4, boundary.length);
+
+ Path streamContentPath = Files.createTempFile("boundaryString", "nupkg");
+ ReplacingInputStream replacingIs = new ReplacingInputStream(is, boundaryPrefixToFix, boundaryPrefixTarget);
+ long len = Files.copy(replacingIs, streamContentPath,
+ StandardCopyOption.REPLACE_EXISTING);
+ System.out.println(len);
+
+ try (InputStream streamContentIs = new BufferedInputStream(Files.newInputStream(streamContentPath)))
+ {
+ MultipartStream multipartStream = new MultipartStream(streamContentIs, boundary, 4096, null);
multipartStream.skipPreamble();
String header = multipartStream.readHeaders();
@@ -613,6 +638,7 @@ public class NugetArtifactController extends BaseArtifactController
int contentLength = multipartStream.readBodyData(packagePartOutputStream);
logger.info(String.format("NuGet package content length [%s]", contentLength));
}
+ }
private URI storePackage(String storageId,
String repositoryId,
