Question

procedure Texport_plan.cxB_LoadClick(Sender: TObject);
var
  HTTP: TIdHTTP;
  Query: String;
  Buffer: TMemoryStream;
  loadData: Sting;
  responseData: String; 
begin 
  try
    HTTP := TIdHTTP.Create(nil);
    HTTP.Request.ContentEncoding := 'utf-8';
    HTTP.Request.ContentType := 'text/xml';
    Application.ProcessMessages;

    Query := 'http://priem.edu.ru:8000/import/ImportService.svc/import';
    loadData := '<Root></Root>'

    Buffer := TMemoryStream.Create;
    loadData.SaveToStream(Buffer);
    responseData := HTTP.Post(Query, Buffer);
  except
    on E: EIdHTTPProtocolException do
      ShowMessage(E.Message);
  end;
end;

This returns HTTP/1.1 400 Bad Request. If use get from http://priem.edu.ru:8000/import/ImportService.svc/test/import i get right xml document in response. Why could this happen? I checked all i can find in google...but nothing helps.

Im using RAD Delphi XE3

UPD: Test client works fine...C# + webclient class. May be something more exists for delphi...not only IdHTTP?

Was it helpful?

Solution

Edit

It turned out that the assignment order of the Charset and ContentType is important.

If you use a ContentType containing the xml, xml-external-parsed-entity words or ending with +xml, the Charset is forcibly set to the value 'us-ascii' and to 'ISO-8859-1' in all other cases.

The behavior is undocumented, so you're free to think it is a bug or an implementation detail.

Comments from Remy in the body of TIdEntityHeaderInfo.SetContentType (IdHTTPHeaderInfo.pas) say:

// RLebeau: per RFC 3023 Sections 3.1, 3.3, 3.6, and 8.5:
//
// Conformant with [RFC2046], if a text/xml entity is received with
// the charset parameter omitted, MIME processors and XML processors
// MUST use the default charset value of "us-ascii"[ASCII]. In cases
// where the XML MIME entity is transmitted via HTTP, the default
// charset value is still "us-ascii". (Note: There is an
// inconsistency between this specification and HTTP/1.1, which uses
// ISO-8859-1[ISO8859] as the default for a historical reason. Since
// XML is a new format, a new default should be chosen for better
// I18N. US-ASCII was chosen, since it is the intersection of UTF-8
// and ISO-8859-1 and since it is already used by MIME.)

To change the charset, you must set it after setting the ContentType value, like this:

HTTP.Request.ContentType := 'text/xml';
HTTP.Request.Charset := 'utf-8';

Original answer
(still valid)

You're indicating your content is encoded in utf-8, but Delphi strings are utf-16 encoded by default.

I have no Delphi at hand to check if the string helper have a overloaded version of the SaveToStream method which supports encodings, but I bet it have, so you can try:

loadData.SaveToStream(Buffer, TEncoding.UTF8);

before sending your data.

OTHER TIPS

I found error. If content type is */xml IdHTTP changes Charset to 'us-ansi'... To make this component works properly you need to change

HTTP.Request.Charset := 'utf-8';
HTTP.Request.ContentType := 'text/xml';

to

HTTP.Request.ContentType := 'text/xml; charset=utf-8';

So IdHTTP cant change Charset to us-ansi and you will get encoding you want.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top