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' ).