process_get

in src/zgoog_cl_content_repo_gcs.clas.abap [0:0]


  METHOD process_get.

    CONSTANTS: lc_default_compid_1 TYPE c LENGTH 4 VALUE 'data',
               lc_default_compid_2 TYPE c LENGTH 5 VALUE 'data1'.

    DATA: lo_contrep       TYPE REF TO data,
          lo_docid         TYPE REF TO data,
          lo_compid        TYPE REF TO data,
          lo_gcs           TYPE REF TO zgoog_cl_storage_cont_repo_v1,
          lo_struc         TYPE REF TO cl_abap_structdescr,
          ls_component     TYPE REF TO abap_compdescr,
          lo_abap_sdk_excp TYPE REF TO /goog/cx_sdk,
          lo_entity        TYPE REF TO if_http_entity.

    DATA: lv_compid       TYPE string,
          lv_pversion     TYPE string,
          lv_fromoffset   TYPE i,
          lv_tooffset     TYPE i,
          lv_seckey       TYPE string,
          lv_smand        TYPE c LENGTH 1,
          lv_signature    TYPE c LENGTH 1,
          lv_p_bucket     TYPE string,
          lv_p_object     TYPE string,
          lv_ret_code     TYPE i,
          lv_err_text     TYPE string,
          lv_data         TYPE xstring,
          lv_msg          TYPE string,
          lv_datec        TYPE string,
          lv_timec        TYPE string,
          lv_datem        TYPE string,
          lv_timem        TYPE string,
          lv_size         TYPE i,
          lv_mimetype     TYPE string,
          lv_status       TYPE string,
          lv_length       TYPE i,
          lv_size_s       TYPE string,
          lv_length_s     TYPE string,
          lv_sdokprof     TYPE string,
          lv_contdisp     TYPE string,
          lv_contdisp1    TYPE string,
          lv_exp          TYPE tzntstmps,
          lv_time_stamp   TYPE tzntstmps,
          lv_diff         TYPE tzntstmpl,
          lv_max          TYPE string VALUE '86400',
          lv_cval         TYPE string,
          lv_comp_id      TYPE sdok_filnm,
          lv_file_name    TYPE sdok_filnm,
          lv_str2         TYPE string,
          lv_str1         TYPE string,
          lv_doc_prot     TYPE c LENGTH 10 VALUE '-',
          lv_s_doc_prot   TYPE string,
          lv_dummy        TYPE string,
          lv_tm           TYPE string,
          lv_dd           TYPE string,
          lv_time_created TYPE string,
          lv_time_updated TYPE string.

    DATA: ls_object_list   TYPE /goog/cl_storage_v1=>ty_016,
          ls_data          TYPE xstring,
          ls_err_resp      TYPE /goog/err_resp,
          ls_metadata      TYPE scms_acinf,
          ls_output_object TYPE /goog/cl_storage_v1=>ty_013,
          ls_info          TYPE scms_acinf.

    DATA: lt_txt   TYPE STANDARD TABLE OF sdokcntasc,
          lt_bin   TYPE STANDARD TABLE OF sdokcntbin,
          lt_infos TYPE STANDARD TABLE OF scms_acinf,
          lt_comps TYPE STANDARD TABLE OF string.

    FIELD-SYMBOLS: <lv_contrep>       TYPE c,
                   <lv_docid>         TYPE c,
                   <lv_compid>        TYPE c,
                   <ls_comp>          TYPE string,
                   <ls_metadata_comp> TYPE any,
                   <ls_source>        TYPE any,
                   <ls_target>        TYPE any,
                   <ls_source_val>    TYPE any.

    get_parameter_c( EXPORTING iv_name      = 'contRep '
                               iv_mandatory = 'S'
                     IMPORTING er_value     = lo_contrep ).
    get_parameter_c( EXPORTING iv_name      = 'docId'
                               iv_mandatory = 'S'
                     IMPORTING er_value     = lo_docid ).
    get_parameter_c( EXPORTING iv_name    = 'compId'
                     IMPORTING ev_value_s = lv_compid
                               er_value   = lo_compid ).

    ASSIGN lo_contrep->* TO <lv_contrep>.
    ASSIGN lo_docid->*   TO <lv_docid>.
    ASSIGN lo_compid->*  TO <lv_compid>.

    lv_pversion = get_parameter( iv_name      = 'pVersion'
                                 iv_mandatory = 'X' ).
    lv_fromoffset = get_parameter_i( iv_name    = 'fromOffset'
                                     iv_default = 0 ).
    lv_tooffset = get_parameter_i( iv_name    = 'toOffset'
                                   iv_default = -1 ).
    lv_seckey = get_parameter( iv_name = 'secKey' ).

    IF lv_seckey IS NOT INITIAL.
      lv_smand = 'S'.
      get_parameter( iv_name      = 'accessMode'
                     iv_mandatory = lv_smand ).
      get_parameter( iv_name      = 'authId'
                     iv_mandatory = lv_smand ).
      get_parameter( iv_name      = 'expiration'
                     iv_mandatory = lv_smand ).
    ENDIF.

    check_parameter_consistence( ).
    IF gs_error IS NOT INITIAL.
      RETURN.
    ENDIF.

    lv_signature = check_signature( iv_docprot = 'r' ).
    IF gs_error IS NOT INITIAL.
      RETURN.
    ENDIF.

    load_goog_repo_config( <lv_contrep> ).
    IF gs_error IS NOT INITIAL.
      RETURN.
    ENDIF.

    lv_p_bucket = gs_repo_config-bucket.

    TRY.
        CREATE OBJECT lo_gcs EXPORTING iv_key_name = gs_repo_config-keyname.

        IF lv_compid IS NOT INITIAL.
          APPEND lv_compid TO lt_comps.
        ELSE.
          APPEND lc_default_compid_1 TO lt_comps.
          APPEND lc_default_compid_2 TO lt_comps.
        ENDIF.

        LOOP AT lt_comps ASSIGNING <ls_comp>.

          lv_p_object = <lv_docid> && '/' && <lv_docid> && '-' && <ls_comp>.

          CLEAR lv_ret_code.
          CLEAR lv_err_text.
          CLEAR ls_output_object.
          lo_gcs->get_objects( EXPORTING iv_p_bucket = lv_p_bucket
                                         iv_p_object = lv_p_object
                               IMPORTING es_output   = ls_output_object
                                         ev_ret_code = lv_ret_code
                                         ev_err_text = lv_err_text ).

          IF lo_gcs->is_success( lv_ret_code ) = abap_true.
            EXIT.
          ENDIF.
        ENDLOOP.

        IF lo_gcs->is_success( lv_ret_code ) <> abap_true.
          set_error( iv_code = lv_ret_code
                     iv_text = lv_err_text ).
          RETURN.
        ENDIF.

        lo_gcs->add_common_qparam( iv_name  = 'alt'
                                   iv_value = 'media' ).

        lo_gcs->get_objects( EXPORTING iv_p_bucket = lv_p_bucket
                                       iv_p_object = lv_p_object
                             IMPORTING ev_ret_code = lv_ret_code
                                       ev_err_text = lv_err_text
                                       es_raw      = lv_data ).

        IF lo_gcs->is_success( lv_ret_code ) <> abap_true.
          set_error( iv_code = lv_ret_code
                     iv_text = lv_err_text ).
          RETURN.
        ENDIF.

      CATCH /goog/cx_sdk INTO lo_abap_sdk_excp.
        lv_msg = lo_abap_sdk_excp->get_text( ).
        set_error( iv_code = 400
                   iv_text = lv_msg ).
        RETURN.
    ENDTRY.

    ASSIGN ls_output_object-metadata->* TO <ls_metadata_comp>.

    lo_struc ?= cl_abap_structdescr=>describe_by_data( <ls_metadata_comp> ).

    LOOP AT lo_struc->components REFERENCE INTO ls_component.
      ASSIGN COMPONENT ls_component->name OF STRUCTURE <ls_metadata_comp> TO <ls_source>.
      IF sy-subrc IS NOT INITIAL.
        CONTINUE.
      ENDIF.

      ASSIGN COMPONENT ls_component->name OF STRUCTURE ls_metadata TO <ls_target>.
      IF sy-subrc IS NOT INITIAL.
        CONTINUE.
      ENDIF.

      ASSIGN <ls_source>->* TO <ls_source_val>.
      <ls_target> = <ls_source_val>.
    ENDLOOP.

    MOVE-CORRESPONDING ls_metadata TO ls_info.

    lv_time_created = ls_output_object-time_created(19).
    ls_info-crea_time  = convert_str_to_time( lv_time_created ).

    lv_time_updated = ls_output_object-updated(19).
    ls_info-chng_time  = convert_str_to_time( lv_time_updated ).

    ls_info-comp_id    = <ls_comp>.
    ls_info-binary_flg = 'X'.
    APPEND ls_info TO lt_infos.

    lo_entity = go_server->response.

    READ TABLE lt_infos INDEX 1 INTO ls_info.
    IF sy-subrc <> 0.
      gs_error-status_code = 500.
      EXIT.
    ENDIF.

    format_timestamp( EXPORTING iv_timestamp = ls_info-crea_time
                      IMPORTING ev_date      = lv_datec
                                ev_time      = lv_timec ).
    format_timestamp( EXPORTING iv_timestamp = ls_info-chng_time
                      IMPORTING ev_date      = lv_datem
                                ev_time      = lv_timem ).

    lv_size = ls_info-comp_size.
    lv_mimetype = ls_info-mimetype.
    lv_compid   = ls_info-comp_id.
    lv_status = 'online'.

    lv_size = xstrlen( lv_data ).

    IF lv_tooffset >= lv_size AND lv_fromoffset >= lv_size.
      lv_length = 0.
      CLEAR lv_data.
    ELSE.
      IF lv_tooffset < 0 OR lv_tooffset >= lv_size.
        lv_tooffset = lv_size - 1.
      ENDIF.

      IF lv_fromoffset < 0 OR lv_fromoffset >= lv_size.
        lv_fromoffset = lv_size - 1.
      ENDIF.

      IF lv_fromoffset > lv_tooffset.
        CLEAR lv_data.
        lv_length = 0.
      ELSEIF lv_fromoffset > 0 OR lv_tooffset < lv_size.
        lv_length = lv_tooffset - lv_fromoffset + 1.
        IF lv_length <= 0 OR lv_fromoffset < 0.
          lv_length = 0.
          CLEAR lv_data.
        ELSE.
          lv_data = lv_data+lv_fromoffset(lv_length).
        ENDIF.
      ELSE.
        lv_length = lv_size.
      ENDIF.
    ENDIF.

    lv_size_s = lv_size.
    lv_length_s = lv_length.
    " concatenate 'inline; filename="' lv_compid '"' into l_contdisp.
    CALL FUNCTION 'SDOK_PROFILE_READ'
      EXPORTING
        name      = 'CNTDISP'
      IMPORTING
        value     = lv_sdokprof
      EXCEPTIONS
        not_found = 1
        OTHERS    = 2.
    IF ( sy-subrc <> 0 ) OR ( lv_sdokprof IS INITIAL ).
      " Default Content-Disposition is attachment from BASIS 751 onwords.
      lv_contdisp = 'attachment' ##NO_TEXT.
    ELSE.
      lv_contdisp = lv_sdokprof.
    ENDIF.

    CONCATENATE lv_contdisp'; filename="' lv_compid '"' INTO lv_contdisp1 ##NO_TEXT.

    " Content-Disposition handling
    " the following behavior is realized:
    " auto or default: Send content-disposition only, if compId has an extension.
    " on: Force content-disposition for all compId's
    " off: Turn off content-disposition for all compId's

    IF gv_cd_mode = ' '.
      CALL FUNCTION 'SDOK_PROFILE_READ'
        EXPORTING
          name      = 'CNTDISPMOD'
*         NAME2     =
*         UNAME     = SY-UNAME
*         MANDT     = SY-MANDT
        IMPORTING
          value     = lv_sdokprof
*         VALUE_TAB =
        EXCEPTIONS
          not_found = 1
          OTHERS    = 2.
      IF ( sy-subrc <> 0 ) OR ( lv_sdokprof IS INITIAL ).
        gv_cd_mode = 'A' ##NO_TEXT.
      ELSE.
        lv_sdokprof = to_upper( lv_sdokprof ).
        CASE lv_sdokprof.
          WHEN 'OFF'.
            gv_cd_mode = 'N' ##NO_TEXT.
          WHEN 'ON'.
            gv_cd_mode = 'Y' ##NO_TEXT.
          WHEN OTHERS.
            gv_cd_mode = 'A' ##NO_TEXT.
        ENDCASE.
      ENDIF.
    ENDIF.

    lo_entity->set_header_field( name  = 'Content-Type'
                                 value = lv_mimetype ) ##NO_TEXT.

    " To enable Cache-Control for /sap/bc/contentserver handler
    FIND REGEX `image/*` IN lv_mimetype.
    IF sy-subrc = 0.
      lv_exp = get_parameter( iv_name = 'expiration' ).
      IF lv_exp IS NOT INITIAL.
        TRY.
            GET TIME STAMP FIELD lv_time_stamp.
            lv_diff = cl_abap_tstmp=>subtract( tstmp1 = lv_exp
                                               tstmp2 = lv_time_stamp ).
          CATCH cx_parameter_invalid_range.
          CATCH cx_parameter_invalid_type.
        ENDTRY.
        IF lv_diff > 0 AND lv_diff < 86400.
          lv_max = ceil( lv_diff ).
        ENDIF.
      ENDIF.

      CONCATENATE 'private, max-age=' lv_max INTO lv_cval ##NO_TEXT.

      lo_entity->set_header_field( name  = 'Cache-Control'
                                   value = lv_cval ) ##NO_TEXT.

    ENDIF.

    " Add new header field to disable auto sniffing by IE
    lo_entity->set_header_field( name  = 'X-Content-Type-Options'
                                 value = 'nosniff' ) ##NO_TEXT.

    CASE gv_cd_mode.
      WHEN 'Y'.

        lv_comp_id = lv_compid.
        PERFORM get_subs_comp_names IN PROGRAM saplscms_api USING    lv_comp_id
                                                            CHANGING    lv_file_name.

        CONCATENATE lv_contdisp'; filename="' lv_compid '"' INTO lv_contdisp1 ##NO_TEXT.

        lo_entity->set_header_field( name  = 'Content-Disposition'
                                     value = lv_contdisp1 ) ##NO_TEXT.

      WHEN 'A' OR ' '.
        IF lv_compid CA '.'.
          lv_str2 = lv_compid.
          WHILE lv_str2 CA '.'.
            SPLIT lv_str2 AT '.' INTO lv_str1 lv_str2.
          ENDWHILE.
          IF NOT lv_str2 CA '/\'.
            lo_entity->set_header_field( name  = 'Content-Disposition'
                                         value = lv_contdisp1 ) ##NO_TEXT.
          ENDIF.
        ENDIF.
    ENDCASE.

    lo_entity->set_header_field( name  = 'X-compId'
                                 value = lv_compid ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-Content-Length'
                                 value = lv_size_s ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-compDateC'
                                 value = lv_datec ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-compTimeC'
                                 value = lv_timec ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-compDateM'
                                 value = lv_datem ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-compTimeM'
                                 value = lv_timem ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-compStatus'
                                 value = lv_status ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-pVersion'
                                 value = lv_pversion ) ##NO_TEXT.

    " Add new header field to disable auto sniffing by IE
    lo_entity->set_header_field( name  = 'X-Content-Type-Options'
                                 value = 'nosniff' ) ##NO_TEXT.

    IF lv_doc_prot <> '-'.
      lv_s_doc_prot = lv_doc_prot.
      lo_entity->set_header_field( name  = 'X-docProt'
                                   value = lv_s_doc_prot ) ##NO_TEXT.
    ENDIF.

    TRY.
        lo_entity->set_data( data = lv_data ).
      CATCH cx_vsi.
        MESSAGE e025(cms) WITH 'Virus scan detected '
                               'an infected file '
                               'while trying to access the file.'
                               'Operation aborted'
                               INTO lv_dummy ##NO_TEXT.
        sys_error_set( ).
        gs_error-status_code = 500.
        RETURN.
    ENDTRY.

    go_server->response->set_status( code   = 200
                                     reason = 'OK' ).