简体   繁体   中英

Flutter HTTP request send using xml body

I'm trying to process a HTTP request in Flutter/Dart (in this case using the SEARCH method to filter some files on a WebDAV server (Nextcloud)) need to send XML data in the body of the request.

[x] Can execute the comand using cURL on terminal with the --data parameter:

curl -u user:pass -X SEARCH 'https://host123.com.br/remote.php/dav' -H "content-Type: text/xml" --data '<?xml version="1.0" encoding="UTF-8"?><d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:basicsearch><d:select><d:prop><d:displayname/></d:prop></d:select><d:from><d:scope><d:href>/files/wprech</d:href><d:depth>infinity</d:depth></d:scope></d:from><d:where><d:and><d:or><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>image/png</d:literal></d:eq><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>image/jpg</d:literal></d:eq><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>video/mp4</d:literal></d:eq></d:or></d:and></d:where><d:orderby/></d:basicsearch></d:searchrequest>'

[x] Also works via Postman app:

[ ] Can't do this request with xml body using Flutter/Dart. All other HTTP requests of this project we used the DIO pkg, and it works fine, but the problem is. to send the xml body with it. The closest code is bellow:

void _list() async {
final prefs = await SharedPreferences.getInstance();

var us = prefs.getString('id') ?? '';
var sn = prefs.getString('password') ?? '';

String basicAuth = 'Basic ' + base64Encode(utf8.encode('$us:$sn'));

try {
  Dio dio = new Dio();
  dio.options.method = 'SEARCH';
  dio.options.responseType = ResponseType.plain;
  dio.options.headers = {
    HttpHeaders.authorizationHeader: basicAuth,
    'content-Type': 'text/xml'
  };
  String data =
      '<?xml version="1.0" encoding="UTF-8"?><d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:basicsearch><d:select><d:prop><d:displayname/></d:prop></d:select><d:from><d:scope><d:href>/files/wprech</d:href><d:depth>infinity</d:depth></d:scope></d:from><d:where><d:and><d:or><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>image/png</d:literal></d:eq><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>image/jpg</d:literal></d:eq><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>video/mp4</d:literal></d:eq></d:or></d:and></d:where><d:orderby/></d:basicsearch></d:searchrequest>';

  Response response = await dio.request(
      "https://host123.com.br/remote.php/dav",
      data: data);

  print(response);
} catch (e) {
  print(e);
}}

Server responses vary between 400, 404, 500 e 501, depending how it's sent:

I/flutter ( 6767): DioError [DioErrorType.RESPONSE]: Http status error [400]

Any help? :)

Experiment with a simpler package:http version.

import 'dart:convert';
import 'dart:io';

import 'package:http/http.dart' as http;

main() async {
  var username = 'foo';
  var password = 'B@r!';
  var credential = base64.encode(utf8.encode('$username:$password'));
  var client = http.IOClient();

  var request = http.Request(
    'SEARCH',
    Uri.parse('https://host123.com.br/remote.php/dav'),
  );
  request.headers.addAll({
    HttpHeaders.authorizationHeader: 'Basic $credential',
    'content-type': 'text/xml' // or text/xml;charset=utf-8
  });

  var xml = '<?xml version="1.0" encoding="UTF-8"?>...';
  // either
  request.body = xml;
  // which will encode the string to bytes, and modify the content-type header, adding the encoding
  // or
  // request.bodyBytes = utf8.encode(xml);
  // which gives you complete control over the character encoding

  var streamedResponse = await client.send(request);
  print(streamedResponse.statusCode);

  var responseBody =
      await streamedResponse.stream.transform(utf8.decoder).join();
  print(responseBody);
  client.close();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM