Results 1 to 10 of 10

Thread: HTTPRIO - verschil in Content-type ??

  1. #1

    HTTPRIO - verschil in Content-type ??

    Ik zit met een vervelend probleem met HTTPRIO.
    Een van de SOAP koppelingen die ik maak struikelt op een ESOAPHTTPException:
    Cannot process the message because the content type 'text/xml, charset='urf-8' was not the expected type 'application/soap-xml, charset=utf-8' (415)
    gevolgd door de URL van de service.

    Een andere koppeling (uiteraard andere service maar dezelfde informatie-leverancier) geen problemen geeft.

    Basis voor beide koppelingen is dezelfde code:

    Code:
    procedure PrepareSoap(var myRIO: THTTPRIO, var URL: String, defauilt_URL: string) ;
          myRIO := THTTPRIO.Create(nil);
          myRIO.HTTPWebNode.OnBeforePost := x509Rio.BeforePost;
          myRIO.OnAfterExecute := x509Rio.onAfterExecute;
          myRIO.HTTPWebNode.Proxy := x509Proxy;
          if ansileftstr(defaultURL,8) <> 'https://'  then
            URL := 'https://' + defaultURL
          else
            URL := defaultURL;
    
    
    function Get_data(Vraagdata: RequestData; default_url: string): ResponseType;
    
    var
      MyLink : (interface uit WSDL)
      MyRio: THTTPRIO;
      Hetantwoord : Response-class;
      DeVraag : Request-type;
    
    begin
       vul DeVraag in met gegevens uit Vraagdata;
       if not PrepareSoap(myRIO, URL, vaste_URL) then
          exit;
       hetAntwoord := nil;
       myLink := Service-Infnterface-functie (False, URL, myRIO);
       retryCount := 0;
       repeat
          isTimeout := false;
          try
          begin
             hetAntwoord := myLink.SOAP-functie(deVraag);
          end;
          except
             on ex: Exception do
             begin
                uVerbindingsfout('Limnknaam', ex);
             end;
          end;
       until not (isTimeout) or (retryCount >= 2);
       Result := HetAntwoord;
    end;
    In de wsdl- en daarvan afgeleide .pas bestanden zie ik ook geen indicatie van de oorzaak.van dat verschil. Content-Type zal ergens omnder de motorkap ingevuld worden - in de code doe ik het in elk geval niet.


    Waar komt dta vandaan en hoe los ik het op?

  2. #2
    charset='urf-8' ???

    Wat is urf-8 ?

  3. #3
    UTF-8. Maar dat snap je wel

  4. #4
    Dat begrijp ik wel.
    Maar je foutmelding heeft het over urf-8.
    Cannot process the message because the content type 'text/xml, charset='urf-8' was not the expected type
    Is dat een "tikfout" van jou of verstuur je ook echt urf-8 naar de server?
    Want dat kan de foutmelding dus wel verklaren.

  5. #5
    Toch maar eens de code doorgestapt - het zit binnen de Indy code. In SOAPHTTPTrans staat het volgende codeblok (vanaf regel 658):
    Code:
        if FBindingType = btMIME then
        begin
          ContentHeader := Format(ContentHeaderMIME, [FMimeBoundary]);
          ContentHeader := Format(ContentTypeTemplate, [ContentHeader]);
          HttpAddRequestHeaders(Request, PChar(MIMEVersion), Length(MIMEVersion), HTTP_ADDREQ_FLAG_ADD);
    
          { SOAPAction header }
          { NOTE: It's not really clear whether this should be sent in the case
                  of MIME Binding. Investigate interoperability ?? }
          if not (soNoSOAPActionHeader in FInvokeOptions) then
          begin
            ActionHeader:= GetSOAPActionHeader;
            HttpAddRequestHeaders(Request, PChar(ActionHeader), Length(ActionHeader), HTTP_ADDREQ_FLAG_ADD);
          end;
    
        end else { Assume btSOAP }
        begin
          { SOAPAction header }
          if not (soNoSOAPActionHeader in FInvokeOptions) then
          begin
            ActionHeader:= GetSOAPActionHeader;
            HttpAddRequestHeaders(Request, PChar(ActionHeader), Length(ActionHeader), HTTP_ADDREQ_FLAG_ADD);
          end;
    
          if UseUTF8InHeader then
            ContentHeader := Format(ContentTypeTemplate, [ContentTypeUTF8])
          else
            ContentHeader := Format(ContentTypeTemplate, [ContentTypeNoUTF8]);
        end;
    FBindingType <> MIME, en UseUTF8InHeader = true, dus:

    Code:
           ContentHeader := Format(ContentTypeTemplate, [ContentTypeUTF8])
    Dat is in SOAPConst.pas gedefinieerd als:

    Code:
      ContentTypeUTF8 = 'text/xml; charset="utf-8"';           { Do not localize }
    Let wel - dit is Indy10 onder Delphi2007....

    In de laatste Delphi-versie 10.2 (Tokyo) is dat in elk geval verbeterd:

    Code:
    function THTTPReqResp.GetSOAPActionHeader: string;
    begin
      if (SoapAction = '') then
        Result := SHTTPSoapAction + ':'
      else if (SoapAction = '""') then
        Result := SHTTPSoapAction + ': ""'
      else
        Result := SHTTPSoapAction + ': ' + '"' + SoapAction + '"';
    end;
    
    function THTTPReqResp.GetContentType: string;
    begin
      Result := '';
      if not (wnoSOAP12 in GetWebNodeOptions) then
      begin
        if UseUTF8InHeader then
          Result := ContentTypeUTF8
        else
          Result := ContentTypeNoUTF8;
      end
      else
      begin
        if UseUTF8InHeader then
          Result := Format(ContentTypeWithActionNoLabelFmt, [ContentType12UTF8, GetSOAPAction])
        else
          Result := Format(ContentTypeWithActionNoLabelFmt, [ContentType12NoUTF8, GetSOAPAction]);
      end;
    end;
    en

    Code:
      ContentType12UTF8 = 'application/soap+xml; charset=utf-8';   { Do not localize }
      ContentType12NoUTF8 = 'application/soap+xml';                { Do not localize }
    het ziet er dus naar uit dat de ene remote applicatie wel met text/xml overweg kan (SOAP 1.0, SOAP 1.1) maar de ander niet (SOAP 1.2)….

    De beste oplossing is uiteraard over te gaan naar de nieuwe Delphi versie - dat wordt al aan gewerkt maar dat is een op zichzelf staand project, gezien de impact die dat op de code heeft....In de tussentijd moet dit binnen de Indy code worden opgelost....

    (Ander issue: de remote applicatie verwacht "soap-xml" - maar Indy geeft "soap+xml". Wat is correct?)

  6. #6
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,292
    Quote Originally Posted by WillemGrooters View Post
    (Ander issue: de remote applicatie verwacht "soap-xml" - maar Indy geeft "soap+xml". Wat is correct?)
    Voor zover ik weet is de geldige content-type "application/soap+xml" en dus niet "soap-xml".
    Er staat me ook iets van bij dat deze melding voor verwarring kan zorgen en dat de oorzaak heel ergens anders ligt dan de content-type.
    TMemoryLeak.Create(Nil);

  7. #7
    Voorlopig maar een standalone programma in Delphi 2018 De baisis code komt uit Codegear 2007 C++ code, ik heb nu voor alles een oplossing, het pronleem is echter dat de server authenticatie op basis van een certioficaat en wachtwoord verwacht (dat zal wel onder de motorkop gebeuren). dde code in de C+ code is:

    in stdsoap2,h (uit gsoap toolset)

    Code:
    struct SOAP_STD_API soap
    …
      unsigned short ssl_flags;
      const char *keyfile;
      const char *password;
    …
    en in de code van het project:

    Code:
      struct soap soap;
      memset(&soap, 0, sizeof(soap));
    ..
      soap.keyfile = Parms->pCERTIFICAAT;  // is .pem bestand, inclusief pad
      soap.password = "(Certww)";               // hardcoded in deze code....
    Ik heb al gezocht naar informatie, vind wel een antwoord op username en password, (zitten in THTTPRIO.HTTPWebNode) maar niets op "keyfile". Gezien de locatie in de C_header-file heft het met ssl (dus versleuteling) te maken, mogelijk ook met versleuteing van het bercht zelf (en authenticatie? Helaas is dat "gewoon" ongedocumenteerd).

    Hoe doe je zoets in Delphi?
    Last edited by WillemGrooters; 29-Jun-18 at 15:48.

  8. #8
    Voorlopig maar een standalone programma in Delphi 2018 De baisis code komt uit Codegear 2007 C++ code, ik heb nu voor alles een oplossing, het pronleem is echter dat de server authenticatie op basis van een certioficaat en wachtwoord verwacht (dat zal wel onder de motorkop gebeuren). dde code in de C+ code is:

    in stdsoap2,h:
    Code:
    struct SOAP_STD_API soap
    …
      unsigned short ssl_flags;
      const char *keyfile;
      const char *password;
    …
    en in de code:

    Code:
      struct soap soap;
      memset(&soap, 0, sizeof(soap));
    ..
      soap.keyfile = Parms->pCERTIFICAAT;  // is .pem bestand, inclusief pad
      soap.password = "(Certww)";               // hardcoded in deze code....
    Ik heb al gezocht naar informatie, vind wel een antwoord op username en password, (zitten in THTTPRIO.HTTPWebNode) maar niets op "keyfile". Gezien de locatie in de C_header-file heft het met ssl (dus versleuteling) te maken, mogelijk ook met versleuteing van het bercht zelf (en authenticatie? Helaas is dat "gewoon" ongedocumenteerd).

    Hoe doe je zoets in Delphi?

  9. #9
    Ik heb het zelf niet gebruikt op deze manier, maar je zou eens kunnen zoeken op X509 certificaat.

    Certificaat moet jij uiteraard wel hebben gekregen van de andere partij, inclusief password.

  10. #10
    Het blijkt een stuk simpeler dan eerst gedacht. In een andere functie wordt een andere service aangestuurd (ook SOAP) met een certificaat - en die doet het. Het was genoeg om die code aan te sturen en de WSDL opnieuw te importeren; dat was voldoende om de zaak aan de praat te krijgen.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •