SoapUI 5.7.0 mockRequest.requestContent is empty for POST request - rest

I am using SOAP UI 5.7.0 to mock a REST service and it is working fine. Only, when I want to access the body of a POST request with mockRequest.requestContent, the correct content is returned only in the first call, but from then on, it always returns the empty string.
I tried the call in OnRequestScript and in the POST requests own Dispatch script but the behavior is the same in both cases. I have the suspicion, that the Stream of the request is already read somewhere else and so does not return any more content. But I don't know what to do about it.
I wonder what is the correct way to read the content of a POST request.
Thank you

Appears to be a known issue, see posts in the community forum here and here.
this seems to be an old bug of PUT operation in REST mocks.
Unfortunately, this is a bug. There is an internal defect of SOAP-2344 for this issue. This applies for the PUT and DELETE methods for a REST mock service.
I have the same issue with a PATCH request.

Use the following trick to get the body of the PUT and DELETE requests:
mockRequest.with {
if (method.toString() == 'PUT' || method.toString() == 'DELETE') {
InputStreamReader isr = new InputStreamReader(request.getInputStream(), "UTF-8")
BufferedReader br = new BufferedReader(isr)
StringBuilder sb = new StringBuilder()
while ((s=br.readLine())!=null) {
sb.append(s)
}
def requestBody = new groovy.json.JsonSlurper().parseText(sb.toString())
log.info "requestBody: " + requestBody
}
}
I use it on the project but I don't really remember how where I got the snippet from. I had to change some parts to make it work as far as I remember. Give it a try.

Related

How to handle a basic form submission with http4s?

I can't believe this isn't in the http4s documentation, and the example code I was able to dig up online (after poking around long enough to discover the UrlForm class) is not working for me.
The relevant bit of code looks like this:
case req # POST -> Root / "compose" =>
req.decode[UrlForm] { ps =>
println("ps.values: " + ps.values)
val content = ps.getFirstOrElse("content",
throw new IllegalStateException("No content given!"))
// Do something with `content`...
}
When submitting the associated form, the IllegalStateException is thrown. ps.values is an empty map (Map()).
I can see (using println) that the Content-Type is application/x-www-form-urlencoded, as expected, and I can see from my browser's Network tab that request "paramaters" (the encoded form values) are being sent properly.
The problem is that I had a filter (javax.servlet.Filter) in place that was calling getParameterMap on the HttpServletRequest. This was draining the InputStream for the request, and it was happening before the request got passed off to the servlet (BlockingHttp4sServlet) instance.
It seems to me the BlockingHttp4sServlet should raise an IllegalStateException (or something more descriptive) when it receives an InputStream with isFinished returning true. (I've filed an issue with the http4s project on Github.)

PATCH / Post with curl in Classic ASP

I was thrown into a pretty old project, which is made in classic ASP. For our needs, I need to make a simple curl-request, to update some data.
I'm pretty new to ASP, so I looked for similar problems. I stumbled upon this
question here:
How can I post data using cURL in asp classic?
I tried to adapt as much as possible, but it seems like I'm missing an important thing and here I need your help:
functions.asp
public function makeCurlRequest(strMethod)
Dim http: Set http = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
Dim privateKey
privateKey = "abc def"
Dim url: url = "https://sandbox.uberall.com/api/locations/322427?private_key=" & privateKey
Dim data: data = "{""location"":{""openingHours"":[{""dayOfWeek"":1,""from1"":""07:01"",""to1"":""07:02""}]}}"
'method needs to be PATCH
With http
Call .Open(strMethod, url, False)
Call .SetRequestHeader("Content-Type", "application/json")
Call .Send(data)
End With
If Left(http.Status, 1) = 2 Then
response.write("updated")
response.end()
Else
'Output error
Call Response.Write("Server returned: " & http.Status & " " & http.StatusText)
End If
end function
In my file, I simply call makeCurlRequest("PATCH").
Now it does indeed print "updated", so I guess I'm retrieving a 200, but the fields aren't updated.
Regarding to the uberall API, they require a location-object, which should be this, what is currently in my data-variable. (Checked it via a JSON-validator).
For a better readability, I'll provide the indented code as well, maybe here is an error:
{
"location":{
"openingHours":[
{
"dayOfWeek":1,
"from1":"07:01",
"to1":"07:02"
}
]
}
}
The ID's are correct, I double-checked that already. Maybe the payload is wrong? What might be the problem? Maybe data needs to be provided otherwise instead of this approach?
Looking at the examples on Uberall Tutorials Page
It looks as though the encapsulation of the location object is not necessary, instead structure the body like
{
"openingHours":[
{
"dayOfWeek":1,
"from1":"07:01",
"to1":"07:02"
}
]
}
In the code, change the data variable to be;
Dim data: data = "{""openingHours"":[{""dayOfWeek"":1,""from1"":""07:01"",""to1"":""07:02""}]}"
Must admit I had to dig around in the documentation to find an example that showed how they expected the body of the request to be structured, which isn't great for an API. Also if the payload was wrong you should be getting back an error so you know there was a problem with the payload, something along the lines of HTTP 400 Bad Request would make sense.
It's also possibly that the API uses HTTP 200 OK for everything, in which case any errors might get missed, so while testing you could just do something like this;
Dim http: Set http = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
Dim privateKey
privateKey = "abc def"
Dim url: url = "https://sandbox.uberall.com/api/locations/322427?private_key=" & privateKey
'Purposefully passing the wrong structure to see what is returned.
Dim data: data = "{""location"":{""openingHours"":[{""dayOfWeek"":1,""from1"":""07:01"",""to1"":""07:02""}]}}"
'method needs to be PATCH
With http
Call .Open(strMethod, url, False)
Call .SetRequestHeader("Content-Type", "application/json")
Call .Send(data)
End With
'Not bothered about the status for now, just give me the response.
Call Response.Write("Server returned: " & http.Status & " " & http.StatusText)
Call Response.Write("Body: " & http.ResponseText)

Restangular - how to cancel/implement my own request

I found a few examples of using fullRequestInterceptor and httpConfig.timeout to allow canceling requests in restangular.
example 1 | example 2
this is how I'm adding the interceptor:
app.run(function (Restangular, $q) {
Restangular.addFullRequestInterceptor(function (element, operation, what, url, headers, params, httpConfig) {
I managed to abort the request by putting a resolved promise in timeout (results in an error being logged and the request goes out but is canceled), which is not what I want.
What I'm trying to do - I want to make the AJAX request myself with my own requests and pass the result back to whatever component that used Restangular. Is this possible?
I've been looking a restangular way to solve it, but I should have been looking for an angular way :)
Overriding dependency at runtime in AngularJS
Looks like you can extend $http before it ever gets to Restangular. I haven't tried it yet, but it looks like it would fit my needs 100%.
I'm using requestInterceptor a lot, but only to change parameters and headers of my request.
Basically addFullRequestInterceptor is helping you making change on your request before sending it. So why not changing the url you want to call ?
There is the httpConfig object that you can modify and return, and if it's close to the config of $http (and I bet it is) you can change the url and even method, and so change the original request to another one, entirely knew.
After that you don't need timeout only returning an httpConfig customise to your need.
RestangularConfigurer.addFullRequestInterceptor(function (element, operation, route, url, headers, params, httpConfig) {
httpConfig.url = "http://google.com";
httpConfig.method = "GET";
httpConfig.params = "";
return {
httpConfig: httpConfig
};
});
It will be pass on and your service or controller won't know that something change, that's the principle of interceptor, it allow you to change stuff and returning to be use by the next process a bit like a middleware. And so it will be transparent to the one making the call but the call will be made to what you want.

Can I retrieve a file from server with GET in rest

Can I return a file with my get request? I want to return a word document to calling angularJS service through REST GET method. Not sure if it is even possible.
You're a bit light on detail, so I'm gonna be a bit light on answer.
A REST request is just... a request. The REST side of things is more the way URLs are defined that what actually happens in the request process itself, which is all still vanilla HTTP.
So, same as with any GET request, if you want to return binary data, set the headers appropriately (<cfheader>), then return the file (<cfcontent>).
So this is how I did it, luckily I got this:
http://smithcustomdev.com/2010/10/20/download-file-to-browser-using-cfscript/
All I have to do was make the method remote and listen to REST service
<cfscript>
private void function serveFile(string filePath){
var fileContent = fileRead(expandPath(filePath));
var context = getPageContext();
context.setFlushOutput(false);
var response = context.getResponse().getResponse();
response.reset();
response.setContentType("text/csv");
response.setContentLength(len(fileContent));
response.setHeader("Content-Disposition","attachment; filename=#listLast(filePath,'\')#");
var out = response.getOutputStream();
out.write(ToBinary(ToBase64(fileContent)));
out.flush();
out.close();
}
</cfscript>

The definitive guide to posting a Facebook Feed item using pure C#

Does anyone have a definitive way to post to a user's wall, using nothing but the .NET Framework, or Silverlight?
Problems deriving from people's attempts have been asked here on SO, but I cannot find a full, clear explanation of the Graph API spec and a simple example using WebClient or some similar class from System.Net.
Do I have to send all feed item properties as parameters in the query string? Can I construct a JSON object to represent the feed item and send that (with the access token as the only parameter)?
I expect its no more than a 5 line code snippet, else, point me at the spec in the FB docs.
Thanks for your help,
Luke
This is taken from how we post to a user's wall. We place the data for the post in the request body (I think we found this to be more reliable than including all the parameters in the query part of the request), it has the same format as a URL encoded query string.
I agree that the documentation is rather poor at explaining how to interact with a lot of resources. Typically I look at the documentation for information on fields and connections, then work with the Graph API Explorer to understand how the request needs to be constructed. Once I've got that down it's pretty easy to implement in C# or whatever. The only SDK I use is Facebook's Javascript SDK. I've found the others (especially 3rd party) are more complicated, buggy, or broken than rolling my own.
private void PostStatus (string accessToken, string userId)
{
UriBuilder address = new UriBuilder ();
address.Scheme = "https";
address.Host = "graph.facebook.com";
address.Path = userId + "/feed";
address.Query = "access_token=" + accessToken;
StringBuilder data = new StringBuilder ();
data.Append ("caption=" + HttpUtility.UrlEncodeUnicode ("Set by app to describe the app."));
data.Append ("&link=" + HttpUtility.UrlEncodeUnicode ("http://example.com/some_resource_to_go_to_when_clicked"));
data.Append ("&description=" + HttpUtility.UrlEncodeUnicode ("Message set by user."));
data.Append ("&name=" + HttpUtility.UrlEncodeUnicode ("App. name"));
data.Append ("&picture=" + HttpUtility.UrlEncodeUnicode ("http://example.com/image.jpg"));
WebClient client = new WebClient ();
string response = client.UploadString (address.ToString (), data.ToString ());
}
I don't know much about .net or silverlight, but the facebook api works with simple http requests.
All the different sdks (with the exception of the javascript one) are mainly just wrappers for the http requests with the "feature" of adding the access token to all requests.
Not in all requests the parameters are sent as querystring, in some POST requests you need to send them in the request body (application/x-www-form-urlencoded), and you can not send the data as json.
If the C# sdk is not to your liking, you can simply create one for your exact needs.
As I wrote, you just need to wrap the requests, and you can of course have a method that will get a json as parameter and will break it to the different parameters to be sent along with the request.
I would point you to the facebook documentation but you haven't asked anything specific so there's nothing to point you to except for the landing page.