synapse httpsend through proxy server - delphi

I have a routine that currently uses
httpgettext to send two urls out to google..
The first with the maps key
and the second to get some distance calculations with is returned as a JSON object...
It all worked fine but now the client wants it to go through a proxy server.
I have tried modifying code that was on synapse knowledge base but i just get a bad response...
The code looks like this that works no proxy...
buildstring:='http://maps.google.com/maps?file=api&v2&key=ASASASASASASASAS-AAAA';
httpgettext(buildstring,myoutput);
buildstring:='http://maps.googleapis.com/maps/api/directions/json?origin='+trim(start_postcode)+'&destination='+trim(end_postcode)+'&sensor=false';
httpgettext(buildstring,myoutput);
How do I get the same response but through a proxy?
The google maps key above is fake - and will not work - you need to use your own.
When I tried modifying an example the first request came back OK the second one came back with a 400 bad request.
With thanks in advance
Phil Hutchinson

I have found the issue?
I looked at the source code demos supplied and if I create a type of httpsend and put the proxy info in and send the request, the first one works.
The second request fails - so it must be something to do with the htppsend method leaving some rubbish in the type. If I destroy it and send it again it works fine.
Not the perfect solution but it works!

Related

IE using Negotiate authorization instead of Basic

I initially asked this question, which shows that I see MVC errors of missing POST values. I was unable to reproduce - I still can't reproduce it on demand, but I did get the error myself on IE11, and I got a clue...
I have an application in IIS7.5 running with Basic authentication only. I look in Fiddler, and normally all transactions have Authorization: Basic xxxxx as expected. The body contains POST values as expected, and Content-Length is correct.
When I experienced this problem, I found that every single request (GETs and POSTs, including static content) was now showing Authorization: Negotiate xxxxx in Fiddler, with an empty body and zero Content-Length, even when I submitted a POST object via jQuery AJAX, and IE's dev tools shows the real POST body (which of course means IE is lying - not the first time). It gets a 401 response, and then a new request occurs with Basic, but also with an empty POST body, which means ASP.NET throws an error about missing parameter values.
Other web applications on the same top-level domain do use Windows authentication instead of Basic, and my suspicion is that the user goes to one of these sites, and IE becomes confused and thinks that my application should use Windows authentication as well - but I can't reproduce that every time. I have reproduced it twice, but out of a dozen or so times of doing the same thing over and over, so I'm not finding a way to make it reproduce every time.
I don't know why the POST body would get emptied, even if it does switch over and try to do WinAuth instead of basic - but that's when the problem occurs, so I'm sure it's related.
Any ideas on how to prevent IE from getting confused and using Negotiate, or at least how to detect and gracefully handle this on the server? I've only seen it in IE, but I can't be sure it's IE-only.
Here's what a normal POST looks like:
Then after the problem starts occurring, the exact same POST looks like:
EDIT
Here's an interesting edit - I just saw a new symptom. This time, all GET requests are coming in with no Authorization header at all, and the response comes back with a 401 for basic, and the GET is re-done properly with basic. But the POSTs are going through normally, with basic on the first try. I don't know what started this happening, but it's a similar symptom of the same problem.

http POST method for web server

I'm looking at HTTP POST method to create a web page.
I'm a tad unfamiliar with it, and was looking for some explanation on how this works.
I'm simply wanting to use their seemingly simplistic page for my own server needs.
My question is this, how does this curl link really work?
curl --data-binary #audio2.flac --header 'Content-type: audio/x-flac; rate=16000' 'https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&pfilter=0&maxresults=1&lang="en-US"'
So I got it to work by using curl, by sending a flac file as you can see, and it responds with
this JSon stuff
{"status":0,"id":"3b7853241a0dded048f84744cc1ab896-1","hypotheses":[{"utterance":"ice cream","confidence":0.88215643}]}
Please correct me if I'm wrong:
So I believe this is a post method as it has the ? mark with it to send the name value pair.
I have no idea how they got the link https://www.google.com/speech-api/v1/recognize
to only accept POST requests without having a script name like this at the end
https://www.google.com/speech-api/v1/recognize/scriptName.pl
How do I write something to accept a post request at that given page without a .pl or .py extension? How can I put it in a certain directory on the server.
In addition for my purposes can I also send a file back to them once I process / zip?
Any ideas on how to do that?
Thanks so much for your time and generous help!
It seems that if you use --data/--data-binary/--form that the request is POSTed.
I first totally misunderstood your question and though you wanted to know how to use the interface, but you got that working.
The serverside can be achieved by multiple means, totally depending on the infrastructure and software used.
With the Webserver apache for example, you could use Rewrite or something in a HtAccess file to obfuscate/change the requested file. So looking at the extension (or the absence of it) is not helpful.
Please also see various options mentioned here
Running PHP without extension without using mod_rewrite?
or
ForceType/htaccess file extension question - extensionless files?
to see how you could achieve the same.
Only accepting POST data is then again dependant on the programming/scripting technique you employ at your server side, PHP e.g. distinguishes between multiple superglobals like $_GET and $_POST.

415 error while trying to POST or PUT to a RESTLET service

I'm using Restlet v2.1.2 to build a Java based REST service. Everything has been working flawlessly BUT no I've run into problems while trying to PUT/POST to the service using a .Net client, which in turn uses RestSharp to talk to the service. As I mentioned various GET/PU/POST/DELETE request have all worked flawlessly but now when I try to send a "large" request I've run into problems.
I have a URI looking something like: "http://:/matches"
What I'd like to do is to provide two URI parameters {index} and {base64encoded} but as the {base64encoded} may get veeeeeery large, I unfortunately have to rely on PUT/POST in order to use the request.AddBody() method and there provide an object containing those parameters. Furthermore I set request.RequestFormat = DataFormat.Json; but when I execute the request I get either a http 405 or 415 error.
What am I doing wrong here???
I'm so sorry! I had simply overseen the fact that I had forgot to provide the "...foo(JsonRepresentation bar)" parameter declaration for the Get method!!! After adding this parameter it works like a charm:) Thanks for your reply though...:)

How to I access a SoundCloud public stream?

How do I play a track from a SoundCloud URL, which, for example, I got from the xml response from a query
<stream-url>https://api.soundcloud.com/tracks/31164607/stream</stream-url>
I should have thought that it would have been as easy as:
https://api.soundcloud.com/tracks/31164607/stream&client_id=my_client_id
yet I get
<error>401 - Unauthorized</error>
All I want to do is consume it in a Silverlight MediaElement, so all I need is set some url to the MediaElement's Source property.
I've checked an application that I wrote about 2 years ago, and THEN, accessing the stream url was as easy as this for a public track:
http://api.soundcloud.com/tracks/18163056/stream&consumer_key=MY_CONSUMER_KEY
however this no longer seems to work.
For example, all I had to do then in C# was:
MediaElement me = new MediaElement();
me.Source= new Url("http://api.soundcloud.com/tracks/18163056/stream&consumer_key=MY_CONSUMER_KEY");
me.Play();
Any hints would be appreciated.
I had a reply on a Microsoft forum that seems to imply that SoundCloud might not be possible to stream to Windows 8 Metro devices without consuming the whole stream before playback starts - which is quite worrying and would seem to imply that to make authentication possible, it would have to be done entirely in the url querystring insterad of using the header:
(The following reply is the answer to the following question: 'I am able to access an audio stream by http using the MediaElement, however I need to access it via https in which I need to add the oAuth info to the header of the initial request.
How is this done when using a MediaElement, and if it cannot be done, what is the workaround for consuming an audio feed in Metro 8 that requires header authentication to stream?')
"Direct access to the underlying network stream is not currently permitted by the MediaElement. Because of this there is currently no way to modify the header of the HTTP request to include any additional authentication information. That said, you do have control over the URL. You could theoretically setup an HTTP proxy service that translated the HTTP GET request parameters into the necessary oAuth credentials. Keep in mind that this is just a theoretical workaround. You may find different behavior in practice. Another theoretical workaround would be to handle the oAuth yourself via a raw stream socket and pass the retuned media data to the MediaElement via "Set Source" and a "Random Access Stream". Please keep in mind that this method has major limitations. in order to use a "Random Access Stream" with the ME you need to make sure all of the data is available before passing it to the ME."
The proxy service is not scalable for an application that is merely distributed for free as every stream would need to come via the proxy. And the raw stream socket, although getting around this, would mean that playback could not start until the whole file had downloaded - and this goes against all current UX (User Experience) guidelines.
So once again, if anyone has any tips, or info about how the whole authentication thing can be achieved in a querystring instead of using headers, I'd appreciate it!
I'm a little confused about whether you're referring to a public or a private track? If it's a public track, then you shouldn't need to send any authentication information, just your client id.
When I request https://api.soundcloud.com/tracks/31164607/stream?client_id=YOUR_CLIENT_ID then I get a 302 redirect to the proper mp3 stream.
Remember, adding parameters to a URL must start with a ? not &. This could (more than likely) be the reason why you are getting a 401 (SC is not picking up the client_id).
After authentication the link like this
http://api.soundcloud.com/tracks/103229681/stream?consumer_key=d61f17a08f86bfb1dea28539908bc9bf
is working fine. I am using Action Script.
I'm following up on Tom's reply because he calls attention to url character specificity. My HTTP requests randomly started failing today, and I was prefacing my client_Id with a ?. As soon as I changed that single ? to &, it started working. So in my case, SC wasn't picking up my client_Id because I used the wrong character. I think depending on where in the request we're talking about specifically, it's worth noting that differences between ? and & do make a difference.

Delphi - Connecting and logging in to a webpage

EDIT
There has been quite a development. The current problem is this:
I compared requests sent from a browser and sent from my app. There have been some differences and I managed to correct most of them. Some are still unfixed, since I haven't figured it out how yet. I am using INDY.
How can i send (or add) cookies into the request?
I tried this:IdHTTP.CookieManager.AddCookie('bakatheme=BrectanTheme',IdHTTP1.URL) but it doesn't work. Also, in INDY help they say that it is supposed to be AddCookie(String, String), but my Delphi only accept (String, TIdURI) - I am not sure if it is the right URI I am calling.
In the Headers I have this code: AcceptEncoding:='gzip,deflate,sdch'; yet when I parse the outgoing request, it states this: AcceptEncoding:gzip,deflate,sdch,identitybut I am certain I don't have "identity" anywhere in the code.
Those are the two things in which my request differs from the browser's. Now, I am getting a 500 Internal Server Error at return, can it be caused by the lack of cookies or the second thing?
Thank you very much.
Haven't exactly tried it myself but here's an example I found about website login using indy
http://www.ciuly.com/delphi/indy/persistent-login-example-for-geocacheing-no-ssl/
Ok. Lets comment:
How can i send (or add) cookies into the request?
You should not do that. Indy handles this for you (but if really want to, there is a TidCookieManager). But it seems to me that you dont know how cookies work. Its not a thing you can add to a request. It cames from the server and it identifies you.
In the Headers I have this code: AcceptEncoding:='gzip,deflate,sdch';
AcceptEnconding tells to the server that it can compact the response using those algorithms. Indy supports gzip,deflate,sdch,identity and indy is updating que header request to add the one you forgot to put.
You should take a look at those links to learn how http works:
W3
Wikipedia

Resources