Using the Jira REST API with cURL to upload .zip file - rest

So I'm trying to upload a .zip file to Jiras restAPI but I'm getting error 415 unsupported media type.
What I've tried:
curl -D- -u $username:$password -X POST -H "X-Atlassian-Token: no-check" -H "Content-Type:application/zip" -F "file=#result.zip" $myURL/rest/api/2/issue/QTC-12/attachments
But sadly this gives 415.

This is probably due to the -H "Content-Type:application/zip" I suspect that the Jira API isn't expecting a zip as the content type.
As it is using the -F option this is probably a form which is the default content type used by Curl so have you tried removing the zip header and running the command?
Edit:
Just looked at the JIRA API https://docs.atlassian.com/software/jira/docs/api/REST/7.6.1/#api/2/issue/{issueIdOrKey}/attachments
And it is of multipart/form-data type. The example on the API shows no other content type header.

Related

Pass json structure or array data in CURL command to test my REST service

I am looking to test my REST resource on dropwizard using CURL command. I am able to upload the file and get the content and file name. But along with the file I want to pass some list of Ids as well.
How can I pass list of long ids (array of Long data type) to the REST service in the below CURL command?
Can I pass a json structure additionally in the below command if required along with my file content?
CURL command
curl -F 'file=#/cygdrive/c/TestDocument1.txt' http://localhost:8199/test-app/api/upload-documents/1004/documents
REST service to upload file
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Path("/reconciliation-details/{reconciliationDetailId}/documents")
public Response uploadDocument(#FormDataParam("file") File inventoryDocumentContent,
#FormDataParam("file") FormDataContentDisposition fileDetail,
#FormDataParam("reconciliationIds") List<Long> reconciliationIds) throws Exception {
byte[] documentContent = FileUtils.readFileToByteArray(inventoryDocumentContent);
String documentName = fileDetail.getFileName();
reconDetailsService.uploadDocument(documentName, documentContent, reconciliationIds);
return ResponseHelper.createOkResponse();
}
With multipart, each part can have it's own Content-Type header. By default if it is not specified, text/plain is used. Some clients cannot set the Content-Type for individual parts, as mentioned in this post (for which there is a solution mentioned), but cURL has this capability. You just need to append ;type=<content-type>. For example
-F "reconciliationIds=[1, 2, 3, 4];type=application/json"
Instead of the using the actual JSON array, you could also use a file containing the JSON
-F "reconciliationIds=#path-to-json;type=application/json"
Jersey will see that the Content-Type for this part is application/json and use the deserializer that it would normally use for JSON
Make sure to see the linked post above - Even though this may work, you don't want to limit your users to only using clients with this capability. The bottom of the post gives you the solution, though I have not tested it with a List<Long>. I'm not sure how that would work using the getEntityAs(Class), as you wouldn't be able to pass the generic Long type. You could always wrap it in a POJO instead of just using a list.
You need to set your content-type to application/json. But -d sends the Content-Type application/x-www-form-urlencoded, which is not accepted on Spring's side.
Looking at the curl man page, I think you can use -H:
-H "Content-Type: application/json"
Full example:
curl -H "Content-Type: application/json" -X POST -d '{"username":"xyz","password":"xyz"}' http://localhost:3000/api/login
(-H is short for --header, -d for --data.)
For Json with file
curl -i -X POST -H "Content-Type: multipart/mixed" -F "blob=#/Users/username/Documents/bio.jpg" -F "metadata={\"edipi\":123456789,\"firstName\":\"John\",\"lastName\":\"Smith\",\"email\":\"john.smith#gmail.com\"};type=application/json" http://localhost:8080/api/v1/user/

NextCloud file tagging through WebDAV script

I am using NextCloud 11 to store my personal files, and I use the simple curl script from the documentation in order to upload files to my NextCloud drive:
curl -u user:pw -T test.pdf "http://localhost/nextcloud/remote.php/dav/files/user/test/test.pdf"
Moreover, I would like to directly add some tags to the uploaded files. However, in the official documentation, they just show how files can be uploaded, deleted and moved through the WebDAV interface.
Does anybody have a hint how I could tag a file remotely?
I have posted the same question in the official NextCloud community forum, but I did not receive a response yet. In case I receive a response, I will post it here.
POST https://yournextcloud.com/index.php/api/v1/files/path/to/file
Payload is JSON:
{"tags": ["tag1", "tag2"]}
You will need to authenticate yourself using Basic Auth
Edit: The API can only be called from inside Nextcloud because the CSRF token is required.
For the record, after a bit of digging I found https://doc.owncloud.com/server/latest/developer_manual/webdav_api/tags.html which does the job for nextcloud as well. In a nutshell:
Get file id for a given file:
curl --silent -u user:password -X PROPFIND -H "Content-Type: text/xml" \
--data-binary "#file-propfind.xml" https://nextcloud/remote.php/webdav/file' | xmllint --format -
with a file-propfind.xml in your directory containing something like
<?xml version="1.0" encoding="utf-8" ?>
<a:propfind xmlns:a="DAV:" xmlns:oc="http://owncloud.org/ns">
<a:prop>
<oc:fileid/>
</a:prop>
</a:propfind>
Then get list of tags for this file using
curl --silent -u user:password -X PROPFIND -H "Content-Type: text/xml" \
--data-binary "#tags-propfind.xml" https://nextcloud/remote.php/dav/systemtags-relations/files/<FILEID>" | xmllint --format -
where FILEID is the number you got as oc:fileid in the previous response and tags-propfind.xml a file containing something like
<?xml version="1.0" encoding="utf-8" ?>
<a:propfind xmlns:a="DAV:" xmlns:oc="http://owncloud.org/ns">
<a:prop>
<oc:display-name/>
<oc:user-visible/>
<oc:user-assignable/>
<oc:id/>
</a:prop>
</a:propfind>
This is for tag reading, but the API document also explain how to add a tag in the same fashion.

Mashape multipart-form POST request

I have a POST method in my API which uses multipart encoded form data. I have set up the correct header and data settings so that the mashape web interface generated the following curl:
curl -X POST --include 'https://sslavov-text-analytics-v1.p.mashape.com/news' \
-H 'Authorization: Basic ***********' \
-H 'X-Mashape-Key: ************' \
-H 'Content-Type: multipart/form-data' \
-F 'file=#sample.docx' \
-F 'meta={"documentType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"};type=application/json'
Basically i'm trying to upload a file with a simple paragraph of text for processing. The curious part is that when I run this exact curl in a bash script, everything works smoothly, but when I try to run it through mashape, it says either 400 Bad Request or 500 Internal Server Error
In my particular case, these errors are generated when I don't pass correct form or headers. So my question is: Is there an error in the curl syntax or should I keep looking for the error on server side?
EDIT: I figured out what the problem was. -F 'file=#sample.docx' was passed before -F 'meta....' and that was causing the 500 Internal Server Error So now the question is: Is there any way to specifically arrange the order of the form fields (because mashape rearranges them aplhabetically)?

POST request with Powershell 2.0 using cURL

Scenario
Among other things, Powershell 2.0 doesn't have the useful cmdlet Invoke-RestMethod.
I can't upgrade to version 3 and most examples I've found use version 3.
I have found this article, which seems, however, too complicated for my simple scenario.
I need to write a Powershell script that POSTs data in Json format, e.g.
{"Id":5,"Email":"test#com","DataFields":null,"Status":0}
What I've tried
I am able to GET data. This is one of the scripts I have tried.
curl -v --user username:password https://api.dotmailer.com/v2/account-info
But, when I try to POST, I can't figure out where to put the body of the message in the script. This is what I've got so far:
curl -v -X POST -H "Accept: application/json" -H "Content-Type: application/json" -u username:password -d '{"Id":5,"Email":"test#com","OptInType":0,"EmailType":0, "DataFields":null,"Status":0}' https://api.dotmailer.com/v2/contacts
which returns the following error:
{"message":"Could not parse the body of the request based on the content type \"application/json\" ERROR_BODY_DOES_NOT_MATCH_CONTENT_TYPE"}*
Question
Can anyone advise on how to POST Json data from Powershell using cURL?
Any pointers to why I get the error I mentioned in the Waht I've tried section would be much appreciated.
Thanks.
Note that the question is about the curl.exe external program, not about PowerShell's Invoke-WebRequest cmdlet (which, unfortunately, is aliased to curl in later PowerShell versions, preempting calls to the external program unless the .exe extension is explicitly specified (curl.exe ...).
Unfortunately and unexpectedly, you have to \-escape embedded " instances in a string you pass as an argument to an external program.
Therefore, even though:
'{"Id":5,"Email":"test#com","DataFields":null,"Status":0}'
should work, it doesn't, due to a long-standing bug; instead, you must use:
'{\"Id\":5,\"Email\":\"test#com\",\"DataFields\":null,\"Status\":0}'
See this answer for more information.
From curl's man page it appears you need to use -d switch:
curl -v --user username:password -H "Content-Type: application/json" -d '{"Id":5,"Email":"test#com","DataFields":null,"Status":0}' https://api.dotmailer.com/v2/contacts

File upload with post parameter in curl

How to make a request for uploading a file to facebook using graph api in curl
I am making this request but getting Error:
curl https://graph.facebook.com/<id>/photos -F "source=#me.jpg" -d "message=Me" -v
ERR:
Only One Http Request can be Selected
You cannot mix -F and -d options in the same command line. If you want a multipart formpost (which I believe you do) then you need to add all parts with -F, including the "message=Me" part.