cancel
Showing results for 
Search instead for 
Did you mean: 

Zip file downloaded via application server is invalid ('data after the end of the payload data')

MikeDoyle
Active Contributor
0 Kudos
334

My brief is to create an ABAP report that downloads various table data to CSV, and then archives the CSV files to a single ZIP file.  It needs to work in the foreground (downloading the archive to the user's client) or in batch (downloading the archive to the application server). I use the standard ABAP class CL_ABAP_ZIP.

The foreground mode is working fine, using CL_GUI_FRONTEND_SERVICES=>GUI_DOWNLOAD.  When I use the 7-zip Test archive function I can see that the there are no errors and I can even parse the zip file in the downstream CAP Node.js app, using yauzl.

When I run the report in the background, and then download via CGY3, the file looks good. I can open the archive using 7-zip and I see all of the constituent CSV files.  When I test with 7-zip however I get the following error: There are some data after the end of the payload data

When I upload the file and try to parse it, I get the following error in yauzl:

Invalid comment length. Expected: 51. Found: 0. Are there extra bytes at the end of the file? Or is the end of central dir signature `PK☺☻` in the comment?

See yauzl/issues/48#issuecomment-266587526 for explanation

In background mode I am using the OPEN DATASET / TRANSFER / CLOSE DATASET commands and I expect the file output to be identical to when I run in foreground. Clearly it isn't identical.

Has anyone seen a similar issue before?  Can you see what is wrong with my code (see below)?  Is there an alternative method I can use to save to the application server?

NB the code must be highly backwards compatible as it could be run in systems that aren't on recent releases. Hence no inline data declarations or other modern constructs

 

 

METHOD save_archive.

        DATA: lv_xstring_zip TYPE xstring,
              lv_zip_size TYPE i,
              lv_datestamp(8),
              lv_default_filename TYPE string,
              lt_binary TYPE STANDARD TABLE OF raw255,
              ls_binary LIKE LINE OF lt_binary,
              lv_filename TYPE string,
              lv_path TYPE string,
              lv_fullpath TYPE string.

        lv_xstring_zip = go_zip->SAVE( ).

*       Convert the XSTRING to Binary table
        CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
          EXPORTING
            BUFFER                = lv_xstring_zip
*           APPEND_TO_TABLE       = ' '
          IMPORTING
            OUTPUT_LENGTH         = lv_zip_size
          TABLES
            BINARY_TAB            = lt_binary
                  .

        CONCATENATE ZIP_FILE_PREFIX sy-datum INTO lv_default_filename.

        IF sy-batch = 'X'.
          OPEN DATASET I_EXPORT FOR OUTPUT IN BINARY MODE.
          LOOP AT LT_BINARY INTO ls_binary.
            TRANSFER ls_binary TO I_EXPORT.
          ENDLOOP.
          CLOSE DATASET I_EXPORT.
        ELSE.
          "NB for initial directory set parameter ID GR8
          CALL METHOD CL_GUI_FRONTEND_SERVICES=>FILE_SAVE_DIALOG
             EXPORTING
               WINDOW_TITLE              = 'Choose export location'
               DEFAULT_EXTENSION         = 'zip'
               DEFAULT_FILE_NAME         = lv_default_filename
               PROMPT_ON_OVERWRITE       = 'X'
            CHANGING
              FILENAME                  = lv_filename
              PATH                      = lv_path
              FULLPATH                  = lv_fullpath
            EXCEPTIONS
              CNTL_ERROR                = 1
              ERROR_NO_GUI              = 2
              NOT_SUPPORTED_BY_GUI      = 3
              INVALID_DEFAULT_FILE_NAME = 4
              others                    = 5
                  .
          IF SY-SUBRC <> 0.
            MESSAGE e383(n1me) WITH sy-subrc.
          ENDIF.

          CALL METHOD CL_GUI_FRONTEND_SERVICES=>GUI_DOWNLOAD
            EXPORTING
               BIN_FILESIZE              = lv_zip_size
               FILENAME                  = lv_fullpath
               FILETYPE                  = 'BIN'
            CHANGING
              DATA_TAB                  = lt_binary
            EXCEPTIONS
              FILE_WRITE_ERROR          = 1
              NO_BATCH                  = 2
              GUI_REFUSE_FILETRANSFER   = 3
              INVALID_TYPE              = 4
              NO_AUTHORITY              = 5
              UNKNOWN_ERROR             = 6
              HEADER_NOT_ALLOWED        = 7
              SEPARATOR_NOT_ALLOWED     = 8
              FILESIZE_NOT_ALLOWED      = 9
              HEADER_TOO_LONG           = 10
              DP_ERROR_CREATE           = 11
              DP_ERROR_SEND             = 12
              DP_ERROR_WRITE            = 13
              UNKNOWN_DP_ERROR          = 14
              ACCESS_DENIED             = 15
              DP_OUT_OF_MEMORY          = 16
              DISK_FULL                 = 17
              DP_TIMEOUT                = 18
              FILE_NOT_FOUND            = 19
              DATAPROVIDER_EXCEPTION    = 20
              CONTROL_FLUSH_ERROR       = 21
              NOT_SUPPORTED_BY_GUI      = 22
              ERROR_NO_GUI              = 23
              others                    = 24
                  .
          IF SY-SUBRC <> 0.
            MESSAGE e828(5n) WITH sy-subrc.
          ENDIF.
        ENDIF.

    ENDMETHOD.

 

 

 

View Entire Topic
Sandra_Rossi
Active Contributor

You are writing too many bytes via TRANSFER. It will always be a multiple of 255 bytes (data element RAW255) which is greater or equal than the length of LV_XSTRING_ZIP, e.g. if LV_XSTRING_ZIP has a length of 300 bytes, it will write a file of 510 bytes, so there are 210 extraneous bytes.

Just do that:

          OPEN DATASET I_EXPORT FOR OUTPUT IN BINARY MODE.
          TRANSFER lv_xstring_zip TO I_EXPORT.
          CLOSE DATASET I_EXPORT.

NB: you forgot to handle all possible exceptions (SY-SUBRC after OPEN DATASET and TRY/CATCH of CX_SY_FILE_AUTHORITY and CX_SY_FILE_IO).

MikeDoyle
Active Contributor
0 Kudos

Thank you so much Sandra, can't believe that was all I had to do! Works perfectly