HTTP Request PUT file (image) to Swift RESTful API (Grails) - swift

// authenticate
def authSite = new HTTPBuilder( 'https://*********.objectstore.eu/' )
authSite.auth.basic '******', '******'
def filestore = new File("C:/*****")
filestore.createNewFile()
FileUtils.writeStringToFile(filestore, "datawhathwat")
//save object
authSite.request(PUT) { req ->
uri.path = '/images/********.txt'
headers.'Content-Type' = 'image/jpg'
body: "filestore"
}
authSite.shutdown()
When using this code, the headers come through, a file is created, but the file is empty.
Here is a link to the API documentation: http://developer.openstack.org/api-ref-objectstorage-v1.html#createOrReplaceObject

In the request body you are passing a string, rather than the contents of the file you are trying to upload. Get the contents of the file into the body this way:
authSite.request(PUT) { req ->
...
body: filestore.bytes
}

Related

How to specify file name for a download done via POST in akka http

The user sends a post request, than based on that post body I create an Excel file (.xlsx) and want to send that file back, without storage of that file itself.
def writeAsync(out: OutputStream): Unit = {
Future {
val wb = new XSSFWorkbook
val sheet1: Sheet = wb.createSheet("sheet1");
val os = new ByteArrayOutputStream()
wb.write(os)
os.writeTo(out)
out.close()
wb.close()
}
}
...
pathPrefix("createAndDownloadExcel") {
post {
...
val generatedFileName = "customGeneratedFileName.xlsx" // <-- this name should the file name be like
val (out, source) = StreamConverters.asOutputStream().preMaterialize()
writeAsync(out)
complete(HttpEntity(ContentTypes.`application/octet-stream`, source))
}
}
The response has the excel content with the file name: "createAndDownloadExcel", but I would like it to have the file name based on the individual generated file name.
The name will be later manually generated based on the POST body, whereby a simple change in pathPrefix("fixedName.xlsx") does not work for my needs.
How can I solve this, being able to give a dynamic file name for that returned OutputStream?
"org.apache.poi" % "poi-ooxml" % "5.2.0"
Try adding response header Content-Disposition.
The first parameter in the HTTP context is either inline (default value, indicating it can be displayed inside the Web page, or as the Web page) or attachment (indicating it should be downloaded; most browsers presenting a 'Save as' dialog, prefilled with the value of the filename parameters if present).
import akka.http.scaladsl.model.headers.ContentDispositionTypes.attachment
import akka.http.scaladsl.model.headers.`Content-Disposition`
....
respondWithHeader(`Content-Disposition`(attachment, Map("filename" -> "customGeneratedFileName.xlsx"))) {
complete(HttpEntity(ContentTypes.`application/octet-stream`, source))
}

How to send a POST request with Content-Type "application/x-www-form-urlencoded"

I am trying to send a POST request from my TornadoFX application to my nodejs server.
That's how i send my request to the server:
val api: Rest by inject()
api.baseURI = "http://localhost:5000/"
api.post("api/register", userModel) {
it.addHeader("Content-Type", "application/x-www-form-urlencoded")
}
My UserModel looks like this:
class UserModel : JsonModel {
val nameProperty = SimpleStringProperty("")
var name by nameProperty
val emailProperty = SimpleStringProperty("")
var email by emailProperty
override fun toJSON(json: JsonBuilder) {
with(json) {
add("name", name)
add("email", email)
}
}
}
Printing the request body on my node server i get following:
[Object: null prototype] {
'{"name":"Test","email":"test#test.org"}': ''
}
When i send a request via Postman i get the following body:
[Object: null prototype] {
name: 'Test',
email: 'test#test.org'
}
And that's what i'm trying to produce with TornadoFX without success.
I am grateful for any help!
You are correctly setting the Content-Type header, but you're pushing a JsonModel as your data, and consequently the framework will convert it to a JSON structure by calling toJSON() on it. The application/x-www-form-urlencoded content type expects an URL encoded piece of data, so you need to convert your data into an url encoded string. I suggest adding a function to your domain model like this:
fun toURLEncoded() =
"name=${name.urlEncoded}&email=${email.urlEncoded}".byteInputStream(StandardCharsets.UTF_8)
This example uses an extension function called urlEncoded to avoid clutter. You can define that extension function like this for example:
fun Any.urlEncoded(): String = URLEncoder.encode(toString(), "UTF-8")
Now you just have to call api.post("api/register", userModel.toURLEncoded()) and you should be good to go.

Soap UI Test step result in the name of file where request and response is saved

I have a Soap Project, where I want to save Request and response in txt format locally with the Test Step Result in the Name
def project = context.testCase.testSuite.project
project.testSuiteList.each { suite ->
suite.testCaseList.each { kase ->
kase.testStepList.each { step ->
if (step instanceof WsdlTestRequestStep) {
def reqFilePath = new File("${directoryToSave}/${suite.name}_${kase.name}_${step.name}_request${dt}.txt")
def resFilePath = new File("${directoryToSave}/${suite.name}_${kase.name}_${step.name}_response${dt}.txt")
saveToFile(reqFilePath, step.testRequest.requestContent)
saveToFile(resFilePath, step.testRequest.responseContent)
} else {
log.info "Ignoring as the step type is not Soap request"
}
Currently, I am using these line to save request and response .
Current
File Name - SuiteName.TestCase.TestStep_response.txt
Expected
File Name -SuiteName.TestCase.TestStep_response_TESTSTEPRESULT(PASS/FAIL)_Response.txt

How to PUT XmlSlurper back to REST with HttpBuilder

I'm trying to make GET and then PUT call on XML REST web service.
I do it this way:
#Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.7')
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
import groovy.xml.XmlUtil
def url = "http://localhost:81"
def pathPrefix = "/api/v1"
def http = new HTTPBuilder(url)
def profile = http.request(GET, XML) { req ->
uri.path = "$pathPrefix/profiles/55"
response.success = {resp, xml ->
xml
}
}
println XmlUtil.serialize(profile) // this is fine!
Now i'm going to change and save
profile.name = "New Name"
// this is not fine (i have 400 Bad Request)
// because it sends body not in XML
def savedProfile = http.request(PUT, XML) { req ->
uri.path = "$pathPrefix/profiles/55"
body = profile
response.success = {resp, xml ->
xml
}
}
println XmlUtil.serialize(savedProfile)
When i make PUT request HTTPBuilder do not send XML. It sends string, made of profile.toString().
It it not what i'm expecting.
How to send XmlSlurper object (that i obtained earlier) in PUT request?
Thank you.
I think i found the solution.
When i define body configuration value, i have to write
body = {
mkp.yield profile
}

Can't send InputStream object using grails rest-client-builder

I've been using rest-client-builder plugin (http://grails.org/plugin/rest-client-builder) and faced with problem to send a file as inputStream object.
From plugin documentation:
Multipart requests are possible by setting properties of the request body to File, URL, byte[] or InputStream instances:
def resp = rest.post(url) {
contentType "multipart/form-data"
zip = new File(pluginPackage)
pom = new File(pomFile)
xml = new File(pluginXmlFile)
}
My code:
def post(String url, InputStream photo, String contentType, Cookie[] cookies = null) {
def rest = new RestBuilder()
def cookiesHeaderString = ""
if (cookies) {
cookiesHeaderString = WebUtils.buildCookiesHeader(cookies)
}
def resp = rest.post(url) {
header "Cookie", cookiesHeaderString
file = photo
contentType "multipart/form-data"
}
return resp?.responseEntity?.body
}
Could somebody suggest how can I send an InputStream object or what I'm doing wrong?
For File type we need to set "file" property on the RequestCustomizer. The below code worked for me.
File myFile = new File("myFile.txt")
def restResponse = rest.post(url) {
header headerName, headerValue
contentType "multipart/form-data"
setProperty "file", myFile
}
I know I am quite late for this answer but I was searching for the answer and nothing seemed to work. So, by trial and error I finally have found my answer working, so would like to post it here.
RestTemplate restTemplate=new RestTemplate()
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
def restBuilder=new RestBuilder(restTemplate)
File f = new File("C:/Users/USER/Documents/hello.txt")
MultiValueMap<String, File> form = new LinkedMultiValueMap<String, File>()
form.add("fileUpload", f)
return client.post(path) {
auth('ngtest1', 'ngtest1')
header :['contentType':"multipart/form-data"]
setProperty "fileUpload", f
body (form)
}
This worked for me. I have given the name as 'fileUpload' in my application. Hope this helps.