Calling a REST API on a .NETCore server - bash

I am not a linux guru and using curl is too complicated for me. So I found httpie and try to call one of my own REST servers written in C# against .NETCore 2 and running on Docker under CentOS 7.
I have a working Powershell script on Windows and try to port this to a bash script using httpie, unfortunately with no luck.
The API generates a file on the server and returns it as octet-stream. The headers on the server are defined as follows:
Options = new Dictionary<string, string>
{
{"Content-Type", "application/octet-stream"},
{"X-Api-DocType", filetype},
{"X-Api-DocLength", responseStream.Length.ToString()}
};
My POWERSHELL script (which works fine) looks like so:
$request = #{
Namespace = "MyApplication.MessagingApi"
Version = "current"
DataDefinitionLanguage = "Csharp"
MakePartial = $false
MakeVirtual = $false
}
$docPath = "D:\Projects\AccountingApiMessageDefinitions.cs"
$Url = "http://172.16.63.241:6083/bbopman/messaging/apireferences"
$response = Invoke-WebRequest -Method Get -Uri $Url -Body $request
Set-Content -Path $docPath -Encoding Byte -Value $response.Content
I ported this to a bash script as follows:
#!/bin/bash
url="http://172.16.63.241:6083/bbopman/messaging/apireferences"
request="Namespace=='MyApplication.MessagingApi' Version=='current' DataDefinitionLanguage=='Csharp'"
http -d GET $url $request > ~/AccountingApiMessageDefinitions.cs
What I get back is BAD REQUEST but on the server the call is successfully processed. So I guess I make something wrong when reading the response, but don't know what.... Here is the output in my shell:
$ ./ExecuteRestCall.sh
HTTP/1.1 400 Bad Request
Content-Type: text/html
Date: Wed, 30 May 2018 18:45:50 GMT
Server: Kestrel
Transfer-Encoding: chunked
Vary: Accept
X-Powered-By: ServiceStack/5.02 NETStandard/.NET
Could anybody tell me how I correctly call this from a Linux shell? Many thanks.

You don't need quotes for the parameter values for httpie. Send them without quotes.
request="Namespace==MyApplication.MessagingApi Version==current DataDefinitionLanguage==Csharp"
Also, you seem to be missing the MakePartial and MakeVirtual parameters in the shell script version.
By the way: "on the server the call is successfully processed" - this cannot be true. The bad request status is returned by the server, not something that happens on the client.

Related

Ansible Tower REST API: Is there any way to get the logs/output of a job?

I have a Ansible job started by another Process. Now I need to check the status of the current running job in Ansible Tower.
I am able to track the status whether it is running/success/failed/canceled with /jobs/{id} using REST API.
But I would also need the information of the console logs/ouputs of the task for processing as well. Is there any direct API call for the same?
You can access the job log via a link similar to:
https://tower.yourcompany.com/api/v1/jobs/12345/stdout?format=txt_download
Your curl command would be similar to:
curl -O -k -J -L -u ${username):${password} https://tower.company.com/api/v1/jobs/${jobnumber}/stdout?format=txt_download
obviously replacing ${username}, ${password}, and ${jobnumber} with your own values
The curl flags used:
-O : output the filename that is actually downloaded
-k : insecure SSL (don't require trusted CAs)
-J : content header for file download https://curl.haxx.se/docs/manpage.html#-J
-L : follow redirects
-u : username and password
You can do this via their restful call.
To get the job number use a GET against https://yourtowerinstance/api/v2/job_templates/
this will return your templates, and their IDs
To get the output in real time I use this powershell code
$stdouturl = "https://yourtowerinstance/api/v2/jobs/$($templateResult.id)/stdout/?format=txt"
$resultstd = Invoke-Restmethod -uri $stdouturl -Method 'Get' -Headers $authHeader
while ($resultstd -notmatch 'PLAY RECAP') {
$resultstd = Invoke-Restmethod -uri $stdouturl -Method 'Get' -Headers $authHeader
start-sleep -s 5
}
$resultstd
Once you launch a template you get the job-id in response but I don't think there is a API to get the output of the job. However from the dashboard under jobs section you can download the individual job output.

How can I output the full web-page specific content with Powershell wget?

When I issue the command powershell.exe wget http://IP_ADDR:8080/config/version/ I get the response:
StatusCode : 200
StatusDescription : OK
Content : {"Content of the web page does not fully show through this output… How can I use wget to just show the full content of the webpage without cutting it out?
RawContent : HTTP/1.1 200 OK
Content-Length: 307
Content-Type: application/json
Date: Wed, 26 Apr 2017 04:20:04 GMT
Server: CherryPy/3.2.2
{"Content of the web page does not fully show...
Forms : {}
Headers : {[Content-Length, 307], [Content-Type, application/json], [Date, Wed, 26 Apr 2017 04:20:04 GMT],
[Server, CherryPy/3.2.2]}
Images : {}
InputFields : {}
Links : {}
ParsedHtml : mshtml.HTMLDocumentClass
RawContentLength : 307
As above, the command shows only part of the content, and not the full output of what is returned when I go to the address normally.
My other alternative is to just use curL, but I would like a native resolution to the above other than a third-party tool.
My question is, how can I use the wget command to only show the output of the content, and the full output of it?
Per the comments, you need to access either the .Content or .RawContent property (RawContent contains the HTTP header fields where as Content does not. Note that the Headers are also available in the .Headers property):
powershell.exe (wget http://IP_ADDR:8080/config/version/).Content
or
powershell.exe (wget http://IP_ADDR:8080/config/version/).RawContent
To explain what is occurring, PowerShell returns Objects rather than plain text which to put simply means they are like mini databases with properties that can be returned/filtered etc. What you see when you make your call is the default view of a subset of properties of the object, which is not all of the properties available.
To learn more about wget look up Invoke-WebRequest which is the full cmdlet name (wget is an alias of it).
As a further aside, if your web call is returning JSON or XML you might want to consider using Invoke-RestMethod instead as that will take the JSON or XML and convert it automatically a PowerShell object (which you could then further manipulate within PowerShell).

How to get custom header in bash

I'm adding a custom header in Asp.Net app:
context.Response.Headers.Add("X-Date", DateTime.Now.ToString());
context.Response.Redirect(redirectUrl, false);
When I'm using Fiddler I can see the "X-Date" header in the response.
I need to receive it by using bash.
I tried curl -i https://my.site.com and also wget -O - -o /dev/null --save-headers https://my.site.com with no success.
In both cases I see just the regular headers like: Content-Type, Server, Date, etc...
How I can receive the "X-Date" header?
Thanks,
Lev
protocol headers are different than file-headers (like http-header and tcp-header are different). When you create a protocol header you wiil need a server to resolve it and use the associated enviroment variables. Example ...
#!/bin/bash
# Apache - CGI
echo "text/plain"
echo ""
echo "$CONTENT_TYPE"
echo "$HTTP_ACCEPT"
echo "$SERVER_PROTOCOL"
When calling this script via web, The response ony my browser was...
text/html
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP/1.1
What you looking for are enviorment variables called $HTTP_ACCEPT, $CONTENT_TYPE and maybe $SERVER_PROTOCOL too.

Invoke-RestMethod : Content-Length or Chunked Encoding cannot be set for an operation that does not write data

I am looking for cURL equivalent command in powershell and then found the below mentioned URL :
https://superuser.com/questions/344927/powershell-equivalent-of-curl
Based on the above URL I tried the below mentioned powershell script in a system which has Powershell version 4.0
Invoke-RestMethod -Uri www.discoposse.com/index.php/feed -Method Get -OutFile C:\Temp\DiscoPosseFeed.xml
Once I run the above command I see a xml file in the specified location but if now I specify the encoding as mentioned below:
Invoke-RestMethod -Uri www.discoposse.com/index.php/feed -TransferEncoding compress -Method Get -OutFile C:\Temp\DiscoPosseFeed.xml
I am getting an error :
Can anyone help me to know is there anything I am missing here?
The explanation is tha your command line does not write anything on the line. TransferEncoding specifies a value for the transfer-encoding HTTP response header. Valid values are Chunked, Compress, Deflate, GZip and Identity.

Cannot accept post in Sinatra using Curl

Just been tinkering with Sinatra and trying to get a bit of a restful web service going.
The error I'm getting at the moment is very specific though.
Take this example post method
post '/postMan/:someParam' do
#Edited here. This code can be anything. 411 is still the response
puts params[:someParam]
end
Seems simple enough. Take a param, make an object out of it, then go store it in whatever way the objects save method defines.
Heres what I use to post the data using Curl
$curl -I -X POST http://127.0.0.1/postman/123456
The only problem is, I'm getting 411 back and have no idea why.
To the best of my knowledge, 411 is length required. Here is the trace
HTTP/1.1 411 Length Required
Content-Type: text/html; charset=ISO-8859-1
Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
Date: Fri, 02 Mar 2012 22:27:09 GMT
Content-Length: 303
Connection: close
I 'Cannot' change the curl message in any way. So might anyone have a way to set the content length to be ignored in sinatra? Or some fix which doesn't involve changing the curl request?
For the record, it doesn't matter whether I use the parameters in the Post method or not. I could have some crazy code inside it, it will still throw the same error
As others said above, WEBrick wrongly requires POST requests to have a Content-Length header. I just pass an empty body, because it's less typing than passing in the header:
curl -X POST -d '' http://webrickwhyyounotakeemptyposts.com/
Are you sure you're on port 80 for your app?
When I run:
ruby -r sinatra -e "post('/postMan/:someParam'){puts params[:someParam]}"
and curl it:
curl -I -X POST http://127.0.0.1:4567/postMan/123456
HTTP/1.1 200 OK
X-Frame-Options: sameorigin
X-XSS-Protection: 1; mode=block
Content-Type: text/html;charset=utf-8
Content-Length: 0
Connection: keep-alive
Server: thin 1.3.1 codename Triple Espresso
it's ok. Had to change the URL to postManthough, your example threw a 404because you had postman.
The output was also as expected:
== Sinatra/1.3.2 has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.3.1 codename Triple Espresso)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:4567, CTRL+C to stop
123456
Ah. Try it without -I. It's probably sending a HEAD request and as such, not sending what you expect. Use -v if you want to show the headers.
curl -v -X POST http://127.0.0.1/postman/123456
curl -v -X POST -d "key=val" http://127.0.0.1/postman/123456
WEBrick erroneously requires POST requests to include the Content-Length header.
curl -H 'Content-Length: 0' -X POST http://example.com
Standardly, however, POST requests don't require a body and therefore don't require the Content-Length header.

Resources