Search code examples
delphisslhttpsspeechindy10

Can't open Microsoft Speech Recognition API via Post with Delphi


I want to send a Post request to Microsoft Speech Recognition API via HTTPS using Indy's TIdHTTP in Delphi.

On Microsofts Speech Recognition API Page: Microsoft Speech Recognition API Get started with speech recognition by using the REST API

they write you should send a HTTP POST Request like this:

POST     https://speech.platform.bing.com/speech/recognition/interactive/cognitiveservices/v1?language=en-US&format=detailed HTTP/1.1
Accept: application/json;text/xml
Content-Type: audio/wav; codec=audio/pcm; samplerate=16000
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY
Host: speech.platform.bing.com
Transfer-Encoding: chunked
Expect: 100-continue

I try this with Delphi XE 10 Indy.

But I ever got Error 400 - Bad Request as Answer!

What do I false in the following code?

procedure TForm1.Button1Click(Sender: TObject);
var
  Response, csrf, url: String;
  PostStream: TIdMultipartFormDataStream;

  HTTPClient: TIdHTTP;
  SSL: TIdSSLIOHandlerSocketOpenSSL;


begin
  url := 'https://speech.platform.bing.com/speech/recognition/interactive/cognitiveservices/v1?language=en-US&format=detailed HTTP/1.1';

  HTTPClient := TIdHTTP.Create;
  try
    HTTPClient.Disconnect;
    HTTPClient.AllowCookies := True;
    SSL := TIdSSLIOHandlerSocketOpenSSL.Create(HTTPClient);
    SSL.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
    HTTPClient.IOHandler := SSL;
    HTTPClient.HandleRedirects := true;

    HTTPClient.Request.Accept := 'application/json;text/xml';
    HTTPClient.Request.Method := 'POST';
    HTTPClient.Request.ContentType := 'audio/wav; codec=audio/pcm;   samplerate=16000';

    //-----------------------------------------------------------------------


    PostStream := TIdMultiPartFormDataStream.Create;
    try
      PostStream.AddFormField('Ocp-Apim-Subscription-Key','YOUR_SUBSCRIPTION_KEY');

      PostStream.AddFile('file', 'test.wav');


      Response := HTTPClient.Post(url, PostStream);

      PostStream.Clear;


    finally
     PostStream.Free;
    end;

  finally
    HTTPClient.Free;
  end;
end;

Solution

  • Your POST request is not setup the way Microsoft's documentation says. Most importantly, you should not be using TIdMultipartFormDataStream at all, since the REST server is not expecting a request in multipart/form-data format. The body of the request is expected to be just the actual WAV file and nothing else. TIdHTTP even has an overload of Post() specifically for uploading just a file.

    Try this instead:

    procedure TForm1.Button1Click(Sender: TObject);
    var
      Response, url: String;
      HTTPClient: TIdHTTP;
      SSL: TIdSSLIOHandlerSocketOpenSSL;
    begin
      url := 'https://speech.platform.bing.com/speech/recognition/interactive/cognitiveservices/v1?language=en-US&format=detailed';
    
      HTTPClient := TIdHTTP.Create;
      try
        SSL := TIdSSLIOHandlerSocketOpenSSL.Create(HTTPClient);
        SSL.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
        HTTPClient.IOHandler := SSL;
    
        HTTPClient.AllowCookies := True;
        HTTPClient.HandleRedirects := true;
    
        HTTPClient.Request.Accept := 'application/json;text/xml';
        HTTPClient.Request.ContentType := 'audio/wav; codec=audio/pcm; samplerate=16000';
        HTTPClient.Request.CustomHeaders.Values['Ocp-Apim-Subscription-Key'] := 'YOUR_SUBSCRIPTION_KEY';
    
        Response := HTTPClient.Post(url, 'test.wav');
      finally
        HTTPClient.Free;
      end;
    end;