TIdHTTP->Get() , Server ignores parameters - c++builder

I've got this query:
https://api-v3.mojepanstwo.pl/dane/krs_podmioty.json?conditions[krs_podmioty.nip]=7282827109
In a browser, it works OK, showing data specific for the given nip number.
But in Indy, I get a response as if the query part was omitted:
https://api-v3.mojepanstwo.pl/dane/krs_podmioty.json
I've tried this so far:
BurL = "https://api-v3.mojepanstwo.pl/dane/krs_podmioty.json?conditions[krs_podmioty.nip]=7282827109";
BurL = TIdURI::URLEncode("https://api-v3.mojepanstwo.pl/dane/krs_podmioty.json?conditions[krs_podmioty.nip]=7282827109");
End even raw urlencoded data:
BurL= "https://api-v3.mojepanstwo.pl/dane/krs_podmioty.json?conditions%5Bkrs_podmioty.nip%5D=7282827109";
Code:
try {
Resp = IdHTTPKrs->Get(BurL);
} catch (EIdHTTPProtocolException& e) {
ShowMessage(e.Message);
}
What's wrong, and how can I fix this? Or, maybe I am too tired already and am missing something obvious?
I suspect there is something with the [] part of the query, but I am just guessing here. Similar queries without the [] work OK.
I am using C++Builder XE6 pro, with Indy 10.6.0.512

Your Indy version is out of date. The latest version, at the time of this writing, is 10.6.2.5448. Using the latest version, I can't reproduce your issue. Both URL encodings return the same data for me. As they should be, since a web server is required to decode urlencoded characters when processing the requested URL. conditions%5Bkrs_podmioty.nip%5D=7282827109 and conditions[krs_podmioty.nip]=7282827109 should be getting processed the exact same way by the server, as they are sematically identical data.

Related

DocuSign Connect update XML desserialization error

I have been using DocuSign SOAP and REST based API calls to create envelope and am also using their Connect feature to update the recipient and envelope statuses for my clients.
I am getting a strange error parsing DocuSign Connect update for one client.
The error says "There is an error in XML document (1, 16174)".
Here is my code...
Dim sr As New StreamReader(Request.InputStream)
Dim reader As XmlReader = New XmlTextReader(New StringReader(xml))
Dim serializer As New XmlSerializer(GetType(DocuSignEnvelopeInformation), "http://www.docusign.net/API/3.0")
If Not serializer Is Nothing Then
envelopeInfo = TryCast(serializer.Deserialize(reader), DocuSignEnvelopeInformation)
Dim envid As String = envelopeInfo.EnvelopeStatus.EnvelopeID.ToString
I have tried bunch of things such as removing the XML definition from the XML document but did not work. The strange thing is that the same code works for all of my other clients. This is the only client that is having issues. They have added closed 65 tags in the document to be signed but I don't think that the tags are causing issues on their end since I also tried removing them.
Please advise.
Minal
I have run into this issue before when there are unsupported characters in the tab values or in the PDF byte stream itself when it is decoded. I suspect that copying and pasting values into tabs from external programs like Word introduce some invisible weird characters like 
 - carriage returns and the like. You should validate your XML in its entirety.

Grails (iOS specific): Returning video (mp4) file gives Broken Pipe exception (getOutputStream() has already been called for this response)

I'm trying to return an mp4 file from my Grails controller so that it can be played in the browser. The following is the simplest version of what I have:
def file = new File(<path to mp4 file>)
response.outputStream << file.newInputStream()
The strange thing is that this works when hitting it from a desktop (Chrome on my MacBook), works on an Android phone, but does not work on an iPad Air.
The one header that's different in the iOS request is for "range" of "0-1", but it looks like that might not be causing a problem (tested by adding that request on my laptop).
The exception says:
ERROR errors.GrailsExceptionResolver - SocketException occurred when processing request: [GET]
and further down it says
getOutputStream() has already been called for this response.
I've found many others with similar errors, but they talk about webRequest.setRenderView(false), flushing and closing the outputstream, and many other options. I've tried all of those, but nothing seems to work.
The part that really gets me is that it works on everything except iOS.
Any thoughts would be greatly appreciated. Thanks in advance!
UPDATE 1
Per Graeme's answer below, the accept header from Chrome is:
accept -> text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
And iOS produces multiple requests, which have the following accept headers:
accept -> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept -> */*
The second accept header, */* is the what occurs during the exception.
I have also created a JIRA issue for Grails:
http://jira.grails.org/browse/GRAILS-11325
Might be related to the Accept header that gets sent, as Grails has some parsing depending on the Accept header. If you could post an example in a JIRA with steps to reproduce that would help.
http://jira.grails.org/browse/GRAILS
This turned out to be an iOS specific issue. The range header is required to be implemented, and if you try to return the entire file content for the response of a range request, iOS will not make additional requests.
The following is the code I used:
try {
def rangeValue = request.getHeader("range")
log.debug("rangeValue: ${rangeValue}")
if (rangeValue != null) {
// Get start and end string, substring(6) removes "bytes="
def (start, end) = rangeValue.substring(6).split("-")
def startInt = start.toLong()
def endInt = end.toLong()
def fileSize = file.length()
response.reset()
response.setStatus(206)
response.setHeader("Accept-Ranges", "bytes")
// WARNING: Do not sent Content-length, as it appears to prevent videos from working in iOS
response.setHeader("Content-range", "bytes ${start}-${end}/"+Long.toString(fileSize))
response.setContentType("video/quicktime")
def bytes = new byte[endInt-startInt+1]
def inputStream = file.newInputStream()
// Skip to the point in the inputStream that the range is requesting
inputStream.skip(startInt)
// Read a chunk of the input stream into the bytes array
inputStream.read(bytes, 0, bytes.length)
response.outputStream << bytes
}
else {
response.outputStream << file.newInputStream()
}
} catch (ClientAbortException e) {
log.error("User aborted download")
}
There are a few important notes:
If the Content-length header is returned in the response, iOS will not play the video. Seems like this could be related to content being gzipped - https://stackoverflow.com/a/2359184/2601060
When using the inputStream.read() function, it will always start reading at the beginning of the stream, so make sure to skip() to the proper position in the file (the startInt)
A response can be reset() to make sure that anything that has already been written is not included (this may not be required, but prevents automatic grails actions from providing default behavior)

XE5 RestClient Library issues

I have created a FMX Windows app that connects to a web server to obtain REST data. I have been using the REST Client, Response, Request and ResponseDataAdapter and have connected that to a Client Data Set. I have then connected the Datasets to a string grid through live bindings. I have done this for 2 different string grids with no problems at all, And then I come to the very last request I want to make and I am getting some very strange behaviour. I set everything up in a data module and did an execute of the RestRequest in the IDE and got the content I expected in the RESTResponse. I then activated the RESTResponseAdapter and ClientDataset. The clientdata set was populated and I was able to add the fielddefs through the ide by just going to add fields.
I have a timer setup on the app to update the string grids etc,,, Works fine for two string grids. However on the last one all I ever get on the StringGrid is the data that I originally fetched while in the IDE. I assumed this could be due to some caching on the clientdataset so I put a memo on the form and after each request execute I posted the response content to the memo.... The bizarre thing is that I occasionally get the response the server is currently sending back (Verified by going to the webserver through Chrome) but sometimes the Response Content is the data that I originally requested when I set it up in the IDE. So I went back to the IDE and cleared the response data from the Rest Response. Tried again and get the same... I get the expected result sometimes and other times I get the response that I originally got in the IDE yesterday. So then I thought perhaps the webserver was sending it back. So have run the same REST request through the webserver and never get back the data that the restresponse is showing...
The code below fires on my timer. The top two sets of code are working fine the last one is the buggy one.
restDataModule.adapterOperators.ClearDataSet;
restDataModule.cdsOperators.Close;
restDataModule.responseOperators.Content.Empty;
restDataModule.reqOnlineOperators.ClearBody;
restDataModule.reqOnlineOperators.Execute;
restDataModule.cdsOperators.Open;
restDataModule.adapterStats.ClearDataSet;
restDataModule.cdsStats.Close;
restDataModule.responseOperatorStats.Content.Empty;
restDataModule.reqOperatorStats.ClearBody;
restDataModule.reqOperatorStats.Execute;
restDataModule.cdsStats.Open;
try
restDataModule.adapterChats.ClearDataSet;
restDataModule.cdsChats.Close;
restDataModule.responseChats.Content.Empty;
restDataModule.reqChats.ClearBody;
restDataModule.reqChats.Execute;
restDataModule.cdsChats.Open;
except on E: Exception do
// ignore
memo1.Lines.Add('Failed!')
end;
memo1.Lines.Add(restDataModule.responseChats.Content);
Any suggestions welcome.
Ok the solution was to add a Parameter to the RestClient with the following settings:-
Kind = pkHTTPHEADER
Name = Cache-Control
Value = no-cache
Simple but elusive

notify() is not working in IE8

I am working on a web app based on Sproutcore 1.9.1. To retrieve data from server it
makes a SC.Request.getUrl() request, which works fine in all the browsers except IE8.
For IE8 when the request is like this:
SC.Request.getUrl("'http://example.com/some/path')
.set('isJSON', YES)
.async(false) // made async false to work in IE
.notify(this, 'someMethodDidComplete', { query: query, store: store})
.send();
works fine. But when the request is :
SC.Request.getUrl("'http://example.com/some/path')
.set('isJSON', YES)
.notify(this, 'someMethodDidComplete', { query: query, store: store})
.send();
it works fine for other browsers but for IE8, it is not working. After spending some
time with the issue i found out that the finishrequest() is not invoking. For doing so
what I did is made 'asynchronous false' and then it works. Now I don't know what to do.
Please suggest me something on this and why normal request is not working.
thanks in advance.
This problem is known (https://github.com/sproutcore/sproutcore/issues/866) and seems to be fixed, at least on SC master.
As a side note, you include the query and store in an object as parameter to .notify(). You don't need to do this, you can simply include them as extra parameters and your notify function will be called with those extra parameters:
.notify(this,this.notifier,query,store)
and somewhere else in the file:
notifier: function(result,query,store){ }

Encoding a JMS TextMessage

I'm receiving messages from a JMS MQ queue which are supposedly utf-8 encoded. However on reading the out using msgText = ((TextMessage)msg).getText();
I get question marks where non standard characters were present. It seems possible to specify the encoding when using a bytemessage, but I cant find a way to specify encoding while reading out the TextMessage. Is there a way to solve this, or should I press for bytemessages?
We tried adding Dfile.encoding="UTF-8" to Websphere's jvm and we added
source = new StreamSource(new ByteArrayInputStream(
((TextMessage) msg).getText().getBytes("UTF-8")));
In our MessageListener. This worked for us, so then we took out the Dfile.encoding bit away and it still works for us.
Due to preferred minimum configuration for Websphere we decided to leave it this way, also taking into account that we may easier switch the UTF-8 string by a setting from file or database.
If the text is not decoded correctly, then probably the client is not sending the message with the utf-8 codec; this should work:
byte[] by = ((TextMessage) msg).getText().getBytes("ISO-8859-1");
String text = new String(by,"UTF-8");

Resources