How to send a PUT/FORM-DATA request from SAP ABAP with cl_http_client - abap

I want to send a PUT request using cl_http_client to a Flask endpoint
CL_HTTP_CLIENT=>CREATE_BY_URL(
EXPORTING
URL = MY_URL
SSL_ID = 'ANONYM'
IMPORTING
CLIENT = AO_HTTP_CLIENT
EXCEPTIONS
ARGUMENT_NOT_FOUND = 1
PLUGIN_NOT_ACTIVE = 2
INTERNAL_ERROR = 3
).
IF SY-SUBRC IS NOT INITIAL.
"Error handling
ENDIF.
AO_HTTP_CLIENT->REQUEST->SET_METHOD( 'PUT' ).
AO_HTTP_CLIENT->REQUEST->SET_HEADER_FIELD( NAME = 'Content-Type' VALUE = 'multipart/form-data').
AO_HTTP_CLIENT->REQUEST->SET_HEADER_FIELD( NAME = 'Authorization'
VALUE = 'Basic Y292ZXN0cxxxxxxx3Zlc3Ryb19kZW1v').
AO_HTTP_CLIENT->REQUEST->SET_FORM_FIELD( NAME = 'VAR1' VALUE = '1' ).
AO_HTTP_CLIENT->REQUEST->SET_FORM_FIELD( NAME = 'VAR2' VALUE = '2' ).
AO_HTTP_CLIENT->SEND( ).
The code is 500 and the reason is BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.

Related

Want to know about authentication error /creational invalid in power BI i call rest API

When i call rest API by using following line of code that time, I'm pass my Power BI desktop username and pass but its showing error
() =>
let body = [username = "Username", password = "----"],
Data = Json.Document(Web.Contents("URL", [Headers = [# "Content-Type" = "application/json"], Content = Json.FromValue(body)])),
result = Record.Field(Data[result] {
0
}, "token")
in
result
refer this code I'm trying but I found error

Issue with Multiline parameters passed in Gupshup's Whatsapp Template message api

I am using Gupshup's Template message Api to send messages from a Whatsapp Business account:
def send_template_msg(phone,template_id,params):
url = "http://api.gupshup.io/sm/api/v1/template/msg"
headers = CaseInsensitiveDict()
headers["apikey"] = "xxxxxxxxxxxxxxx"
headers["Content-Type"] = "application/x-www-form-urlencoded"
source_phone ="91xxxxxxxxxx"
dest_phone = "91"+phone
data = 'source='+source_phone+'&destination='+dest_phone+'&template={"id": "'+template_id+'","params": '+str(params)+'}'
print(data)
response = requests.post(url, headers=headers, data=data)
print(response.text,response.status_code)
return response
It is working fine for single line parameters, but for multiple line parameters, it gives the 202 response with message id but we do not receive any message on whatsapp.
How do I send multiline parameters via Gupshup API?

Karate framework variable usage

I have this steps:
...
Then status 200
And match response.requests[0].request.url == "/endpoint"
And json body = response.requests[0].request.body
And match body == { "something": "something"}
To simplify, I tried to put response.requests[0].request in a variable called request:
...
Then status 200
And def request = response.requests[0].request
And match request.url == "/endpoint"
And json body = request.body
And match body == { "something": "something"}
I'm having the following error:
'request' is not a variable, use the form '* request <expression>' instead
I read the documentation and the use of request seems to be fine:
Given def color = 'red '
And def num = 5
Then assert color + num == 'red 5'
What am I doing wrong?
Thanks in advance.
Just make this change:
* def req = response.requests[0].request
# other steps
* request req
We simply disallow def request (using request as a variable name) because a lot of newbie users get confused. The error message has worked 99.9% of the time for users to understand what the problem is, but I guess you fall in the 0.1% :)

Send multiple files in HTTP response

I have created an ICF handler class which sends files to the sender. The thing is, it works fine with single file where i am reading the data in binary format and attaching the same in body part using set_data.
But when I try to add more than 1 file, I am unable to add 2 files separately. i am using IF_HTTP_EXTENSION and do not have NTW GATEWAY component yet.
I am also using MULTIPART feature, but dont konw exactly on how to add 2 files separately. Can you please help me ?
//file1
server->response->set_header_field( name = 'Content-Type' value = 'multipart/mixed').
CONCATENATE 'form-data;name="file"; filename="' filename+5(9) '"' INTO lv_header_value.
server->response->set_header_field( name = 'content-disposition' value = lv_header_value ).
server->response->set_data( data = attach_xstring ).
//file2
server->response->add_multipart( ).
CONCATENATE 'form-data;name="file"; filename="' filename+5(9) '"' INTO lv_header_value.
server->response->set_header_field( name = 'content-disposition' value = lv_header_value ).
server->response->set_data( data = attach_xstring ).
You need to use add_multipart() method. Try like this:
cl_http_client=>create( EXPORTING host = host service = port scheme = scheme
IMPORTING client = lo_http_client ).
lo_http_client->request->set_header_field( name = 'Content-Type' value = 'multipart/form-data' ). "#EC NOTEXT
lo_request_part = lo_http_client->request->add_multipart( ).
lo_request_part->set_content_type( 'application/xml' ).
lv_content_disposition = |form-data; name="item"; filename="item_data.xml" |.
lo_request_part->set_header_field( name = `Content-Disposition` value = lv_content_disposition ).
lo_request_part->set_data( data = lv_create_item_xml ).
LOOP AT mt_files ASSIGNING <attachment>.
lo_request_part = lo_http_client->request->add_multipart( ).
lo_request_part->set_content_type( <attachment>-content_type ). "#EC NOTEXT
lv_content_disposition = |form-data; name="{ <attachment>-part_name }"; filename="{ <attachment>-filename }" |.
lo_request_part->set_header_field( name = `Content-Disposition` value = lv_content_disposition ).
lo_request_part->set_data( <attachment>-file ).
ENDLOOP.
It is sample for request, but for response the scheme should be the same. Here initially xml-file added to request and them multiple attachments are processed in loop.

WCF Client access with Message Contracts

I have a web service , i add some extra class which have message contract and after that it changed the way we access some of the methods( and i have not added message contract to these classes these are data contracts ), earlier i.e before we could create one object for request and response (like see the Before part) we are creating a single object for OrderStatusResponse Class. But if you see now the After(we have to create separate objects for request and response).
is this a side effect of enabling "Always generate message contract?"
Before
SmartConnect.Service1Client Client =
new SmartConnectClient.SmartConnect.Service1Client();
SmartConnect.OrderStatusResponse Status =
new SmartConnectClient.SmartConnect.OrderStatusResponse();
Status.UserID = "1234";
Status.Password = "abcd";
Status.SoftwareKey = "abc";
Status.OrderNumber = "1234";
Status = Client.GetOrderStatus(Status);
lbl_OS.Text = Status.Status.ToString();
lbl_RM.Text = Status.ReturnMessage.ToString();
After
SmartConnectRepublic.SmartConnectClient SmartClient =
new WCF_Client.SmartConnectRepublic.SmartConnectClient();
//SmartConnectRepublic.OrderStatusResponse Status =
new WCF_Client.SmartConnectRepublic.OrderStatusResponse();
WCF_Client.SmartConnectRepublic.GetOrderStatusRequest request =
new WCF_Client.SmartConnectRepublic.GetOrderStatusRequest();
request.status = new WCF_Client.SmartConnectRepublic.OrderStatusResponse();
request.status.OrderNumber = "1055055";
request.status.UserID = "1234";
request.status.Password = "dfsdfsd";
request.status.SoftwareKey = "sdfsdfsdfs";
WCF_Client.SmartConnectRepublic.GetOrderStatusResponse response =
new WCF_Client.SmartConnectRepublic.GetOrderStatusResponse();
response = SmartClient.GetOrderStatus(request);
lbl_Status.Text = response.GetOrderStatusResult.Status;
lbl_RC.Text = response.GetOrderStatusResult.ReturnCode.ToString();
lbl_RM.Text = response.GetOrderStatusResult.ReturnCode.ToString();
Yes, I suspect it is a difference with using message contracts. You seem to have figured it out, though.