From 471042d50491c524d6714569033fa04a67fe36eb Mon Sep 17 00:00:00 2001 From: Julian Tillmann Date: Mon, 21 Nov 2022 17:36:26 +0100 Subject: [PATCH 1/4] Readme --- Modules/System/WebDAV/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 Modules/System/WebDAV/README.md diff --git a/Modules/System/WebDAV/README.md b/Modules/System/WebDAV/README.md new file mode 100644 index 0000000000..588465009d --- /dev/null +++ b/Modules/System/WebDAV/README.md @@ -0,0 +1 @@ +This module provides functions to interact with WebDAV API From 0b6f586ec44ca5433d515168f3f4bb311d93cc4f Mon Sep 17 00:00:00 2001 From: Julian Tillmann Date: Mon, 16 Jan 2023 17:21:40 +0100 Subject: [PATCH 2/4] Prototype --- Modules/System/WebDAV/README.md | 2 + Modules/System/WebDAV/app.json | 27 +++ .../WebDAVAuthorization.Interface.al | 4 + .../WebDAVBasicAuthImpl.Codeunit.al | 30 +++ .../WebDAVBasicAuthorization.Codeunit.al | 13 ++ .../src/Helper/WebDAVDiagnostics.Codeunit.al | 77 +++++++ .../src/Helper/WebDAVHttpContent.Codeunit.al | 76 +++++++ .../WebDAVOperationResponse.Codeunit.al | 99 +++++++++ .../Helper/WebDAVRequestHelper.Codeunit.al | 180 ++++++++++++++++ .../WebDAV/src/Model/WebDAVContent.Table.al | 66 ++++++ .../src/Model/WebDAVContentParser.Codeunit.al | 103 ++++++++++ .../WebDAV/src/WebDAVClient.Codeunit.al | 84 ++++++++ .../WebDAV/src/WebDAVClientImpl.Codeunit.al | 192 ++++++++++++++++++ 13 files changed, 953 insertions(+) create mode 100644 Modules/System/WebDAV/app.json create mode 100644 Modules/System/WebDAV/src/Authorization/WebDAVAuthorization.Interface.al create mode 100644 Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthImpl.Codeunit.al create mode 100644 Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthorization.Codeunit.al create mode 100644 Modules/System/WebDAV/src/Helper/WebDAVDiagnostics.Codeunit.al create mode 100644 Modules/System/WebDAV/src/Helper/WebDAVHttpContent.Codeunit.al create mode 100644 Modules/System/WebDAV/src/Helper/WebDAVOperationResponse.Codeunit.al create mode 100644 Modules/System/WebDAV/src/Helper/WebDAVRequestHelper.Codeunit.al create mode 100644 Modules/System/WebDAV/src/Model/WebDAVContent.Table.al create mode 100644 Modules/System/WebDAV/src/Model/WebDAVContentParser.Codeunit.al create mode 100644 Modules/System/WebDAV/src/WebDAVClient.Codeunit.al create mode 100644 Modules/System/WebDAV/src/WebDAVClientImpl.Codeunit.al diff --git a/Modules/System/WebDAV/README.md b/Modules/System/WebDAV/README.md index 588465009d..848d5fd0a5 100644 --- a/Modules/System/WebDAV/README.md +++ b/Modules/System/WebDAV/README.md @@ -1 +1,3 @@ +# WebDAV + This module provides functions to interact with WebDAV API diff --git a/Modules/System/WebDAV/app.json b/Modules/System/WebDAV/app.json new file mode 100644 index 0000000000..d361c00f3f --- /dev/null +++ b/Modules/System/WebDAV/app.json @@ -0,0 +1,27 @@ +{ + "id": "199527d2-53dd-48e1-8732-8850d4f9e45b", + "name": "WebDAV", + "publisher": "Microsoft", + "brief": "Connect to WebDAV.", + "description": "Provides a set of AL functionality and Helper libraries to make use of WebDAV API", + "version": "21.0.0.0", + "privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009", + "EULA": "https://go.microsoft.com/fwlink/?linkid=2009120", + "help": "https://go.microsoft.com/fwlink/?linkid=2103698", + "url": "https://go.microsoft.com/fwlink/?linkid=724011", + "logo": "", + "dependencies": [ + + ], + "screenshots": [], + "platform": "21.0.0.0", + "application": "21.0.0.0", + "idRanges": [ + { + "from": 5678, + "to": 5699 + } + ], + "target": "OnPrem", + "contextSensitiveHelpUrl": "/dynamics365/business-central/" +} \ No newline at end of file diff --git a/Modules/System/WebDAV/src/Authorization/WebDAVAuthorization.Interface.al b/Modules/System/WebDAV/src/Authorization/WebDAVAuthorization.Interface.al new file mode 100644 index 0000000000..932863f4e6 --- /dev/null +++ b/Modules/System/WebDAV/src/Authorization/WebDAVAuthorization.Interface.al @@ -0,0 +1,4 @@ +interface "WebDAV Authorization" +{ + procedure Authorize(var HttpRequestMessage: HttpRequestMessage); +} \ No newline at end of file diff --git a/Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthImpl.Codeunit.al b/Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthImpl.Codeunit.al new file mode 100644 index 0000000000..d1e600c22e --- /dev/null +++ b/Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthImpl.Codeunit.al @@ -0,0 +1,30 @@ +codeunit 5681 "WebDAV Basic Auth. Impl." implements "WebDAV Authorization" +{ + Access = Internal; + + var + [NonDebuggable] + AuthorizationString: Text; + + [NonDebuggable] + procedure Authorize(var HttpRequestMessage: HttpRequestMessage); + var + Headers: HttpHeaders; + begin + HttpRequestMessage.GetHeaders(Headers); + Headers.Remove('Authorization'); + Headers.Add('Authorization', AuthorizationString); + + Headers.Remove('Translate'); + Headers.Add('Translate', 'F'); + end; + + + [NonDebuggable] + procedure SetUserNameAndPassword(Username: Text; Password: Text) + var + Base64Convert: Codeunit "Base64 Convert"; + begin + AuthorizationString := 'Basic ' + Base64Convert.ToBase64(Username + ':' + Password); + end; +} \ No newline at end of file diff --git a/Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthorization.Codeunit.al b/Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthorization.Codeunit.al new file mode 100644 index 0000000000..00be621438 --- /dev/null +++ b/Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthorization.Codeunit.al @@ -0,0 +1,13 @@ +codeunit 5680 "WebDAV Basic Authorization" +{ + Access = Public; + + procedure GetWebDAVBasicAuth(Username: Text; Password: Text): Interface "WebDAV Authorization" + var + WebDAVBasicAuthImpl: Codeunit "WebDAV Basic Auth. Impl."; + begin + WebDAVBasicAuthImpl.SetUserNameAndPassword(Username, Password); + Exit(WebDAVBasicAuthImpl); + end; + +} \ No newline at end of file diff --git a/Modules/System/WebDAV/src/Helper/WebDAVDiagnostics.Codeunit.al b/Modules/System/WebDAV/src/Helper/WebDAVDiagnostics.Codeunit.al new file mode 100644 index 0000000000..929a7fe1b1 --- /dev/null +++ b/Modules/System/WebDAV/src/Helper/WebDAVDiagnostics.Codeunit.al @@ -0,0 +1,77 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +/// +/// Stores detailed information about failed api call +/// +codeunit 5685 "WebDAV Diagnostics" implements "HTTP Diagnostics" +{ + Access = Internal; + + var + ErrorMessage, ResponseReasonPhrase : Text; + HttpStatusCode, RetryAfter : Integer; + SuccessStatusCode: Boolean; + + /// + /// Gets reponse details. + /// + /// HttpResponseMessage.IsSuccessStatusCode + [NonDebuggable] + procedure IsSuccessStatusCode(): Boolean + begin + exit(SuccessStatusCode); + end; + + /// + /// Gets response details. + /// + /// HttpResponseMessage.StatusCode + [NonDebuggable] + procedure GetHttpStatusCode(): Integer + begin + exit(HttpStatusCode); + end; + + /// + /// Gets response details. + /// + /// Retry-after header value + [NonDebuggable] + procedure GetHttpRetryAfter(): Integer + begin + exit(RetryAfter); + end; + + /// + /// Gets reponse details + /// + /// Error message + [NonDebuggable] + procedure GetErrorMessage(): Text + begin + exit(ErrorMessage); + end; + + /// + /// Gets response details. + /// + /// HttpResponseMessage.ResponseReasonPhrase + [NonDebuggable] + procedure GetResponseReasonPhrase(): Text + begin + exit(ResponseReasonPhrase); + end; + + [NonDebuggable] + internal procedure SetParameters(NewIsSuccesss: Boolean; NewHttpStatusCode: Integer; NewResponseReasonPhrase: Text; NewRetryAfter: Integer; NewErrorMessage: Text) + begin + SuccessStatusCode := NewIsSuccesss; + HttpStatusCode := NewHttpStatusCode; + ResponseReasonPhrase := NewResponseReasonPhrase; + RetryAfter := NewRetryAfter; + ErrorMessage := NewErrorMessage; + end; +} \ No newline at end of file diff --git a/Modules/System/WebDAV/src/Helper/WebDAVHttpContent.Codeunit.al b/Modules/System/WebDAV/src/Helper/WebDAVHttpContent.Codeunit.al new file mode 100644 index 0000000000..604eb1c937 --- /dev/null +++ b/Modules/System/WebDAV/src/Helper/WebDAVHttpContent.Codeunit.al @@ -0,0 +1,76 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +codeunit 5686 "WebDAV Http Content" +{ + Access = Internal; + + var + HttpContent: HttpContent; + ContentLength: Integer; + ContentType: Text; + RequestDigest: Text; + + procedure FromFileInStream(var ContentInStream: Instream) + begin + HttpContent.WriteFrom(ContentInStream); + ContentLength := GetContentLength(ContentInStream); + end; + + procedure FromText(Content: Text) + var + InStream: InStream; + begin + HttpContent.WriteFrom(Content); + HttpContent.ReadAs(InStream); + ContentLength := GetContentLength(InStream); + end; + + procedure FromXML(XMLDoc: XmlDocument) + var + RequestText: Text; + begin + XMLDoc.WriteTo(RequestText); + HttpContent.WriteFrom(RequestText); + ContentLength := StrLen(RequestText); + end; + + procedure GetContent(): HttpContent + begin + exit(HttpContent); + end; + + procedure GetContentLength(): Integer + begin + exit(ContentLength); + end; + + procedure GetContentType(): Text + begin + exit(ContentType); + end; + + // TODO DIGEST?? + procedure SetRequestDigest(RequestDigestValue: Text) + begin + RequestDigest := RequestDigestValue; + end; + + procedure GetRequestDigest(): Text; + begin + exit(RequestDigest); + end; + + local procedure GetContentLength(var SourceInStream: InStream) Length: Integer + var + MemoryStream: DotNet MemoryStream; + begin + MemoryStream := MemoryStream.MemoryStream(); + CopyStream(MemoryStream, SourceInStream); + Length := MemoryStream.Length; + Clear(SourceInStream); + end; + +} \ No newline at end of file diff --git a/Modules/System/WebDAV/src/Helper/WebDAVOperationResponse.Codeunit.al b/Modules/System/WebDAV/src/Helper/WebDAVOperationResponse.Codeunit.al new file mode 100644 index 0000000000..3af2bb38a4 --- /dev/null +++ b/Modules/System/WebDAV/src/Helper/WebDAVOperationResponse.Codeunit.al @@ -0,0 +1,99 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +codeunit 5684 "WebDAV Operation Response" +{ + Access = Internal; + + [NonDebuggable] + [TryFunction] + internal procedure GetResultAsText(var Result: Text); + var + ResultInStream: InStream; + begin + TempBlobContent.CreateInStream(ResultInStream); + ResultInStream.Read(Result); + end; + + [NonDebuggable] + [TryFunction] + internal procedure GetResultAsStream(var ResultInStream: InStream) + begin + TempBlobContent.CreateInStream(ResultInStream); + end; + + [NonDebuggable] + internal procedure SetHttpResponse(HttpResponseMessage: HttpResponseMessage) + var + ContentOutStream: OutStream; + ContentInStream: InStream; + begin + + TempBlobContent.CreateOutStream(ContentOutStream); + HttpResponseMessage.Content().ReadAs(ContentInStream); + CopyStream(ContentOutStream, ContentInStream); + HttpHeaders := HttpResponseMessage.Headers(); + + WebDAVDiagnostics.SetParameters(HttpResponseMessage.IsSuccessStatusCode, HttpResponseMessage.HttpStatusCode, HttpResponseMessage.ReasonPhrase, GetRetryAfterHeaderValue(), GetErrorDescription()); + end; + + [NonDebuggable] + internal procedure SetHttpResponse(ResponseContent: Text; ResponseHttpHeaders: HttpHeaders; ResponseHttpStatusCode: Integer; ResponseIsSuccessStatusCode: Boolean; ResponseReasonPhrase: Text) + var + ContentOutStream: OutStream; + begin + TempBlobContent.CreateOutStream(ContentOutStream); + ContentOutStream.WriteText(ResponseContent); + HttpHeaders := ResponseHttpHeaders; + WebDAVDiagnostics.SetParameters(ResponseIsSuccessStatusCode, ResponseHttpStatusCode, ResponseReasonPhrase, GetRetryAfterHeaderValue(), GetErrorDescription()); + end; + + [NonDebuggable] + internal procedure GetHeaderValueFromResponseHeaders(HeaderName: Text): Text + var + Values: array[100] of Text; + begin + if not HttpHeaders.GetValues(HeaderName, Values) then + exit(''); + exit(Values[1]); + end; + + [NonDebuggable] + internal procedure GetRetryAfterHeaderValue() RetryAfter: Integer; + var + HeaderValue: Text; + begin + HeaderValue := GetHeaderValueFromResponseHeaders('Retry-After'); + if HeaderValue = '' then + exit(0); + if not Evaluate(RetryAfter, HeaderValue) then + exit(0); + end; + + [NonDebuggable] + local procedure GetErrorDescription(): Text + var + Result: Text; + JObject: JsonObject; + JToken: JsonToken; + begin + GetResultAsText(Result); + if Result <> '' then + if JObject.ReadFrom(Result) then + if JObject.Get('error_description', JToken) then + exit(JToken.AsValue().AsText()); + end; + + [NonDebuggable] + internal procedure GetDiagnostics(): Interface "HTTP Diagnostics" + begin + exit(WebDAVDiagnostics); + end; + + var + TempBlobContent: Codeunit "Temp Blob"; + WebDAVDiagnostics: Codeunit "WebDAV Diagnostics"; + HttpHeaders: HttpHeaders; +} diff --git a/Modules/System/WebDAV/src/Helper/WebDAVRequestHelper.Codeunit.al b/Modules/System/WebDAV/src/Helper/WebDAVRequestHelper.Codeunit.al new file mode 100644 index 0000000000..747c2a5853 --- /dev/null +++ b/Modules/System/WebDAV/src/Helper/WebDAVRequestHelper.Codeunit.al @@ -0,0 +1,180 @@ +codeunit 5683 "WebDAV Request Helper" +{ + Access = Internal; + + var + Authorization: Interface "WebDAV Authorization"; + OperationNotSuccessfulErr: Label 'An error has occurred'; + + + procedure SetAuthorization(InitAuthorization: Interface "WebDAV Authorization") + begin + Authorization := InitAuthorization; + end; + + + [NonDebuggable] + procedure MkCol(Uri: Text) WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; + begin + WebDAVOperationResponse := SendRequest(PrepareRequestMsg('MKCOL', Uri)) + end; + + [NonDebuggable] + procedure Put(Uri: Text; HttpContent: HttpContent) WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; + var + RequestMessage: HttpRequestMessage; + begin + RequestMessage := PrepareRequestMsg(Enum::"Http Request Type"::PUT, Uri); + RequestMessage.Content := HttpContent; + WebDAVOperationResponse := SendRequest(RequestMessage); + end; + + [NonDebuggable] + procedure Get(Uri: Text) WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; + begin + WebDAVOperationResponse := SendRequest(PrepareRequestMsg(Enum::"Http Request Type"::GET, Uri)) + end; + + [NonDebuggable] + procedure Delete(Uri: Text) WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; + begin + WebDAVOperationResponse := SendRequest(PrepareRequestMsg(Enum::"Http Request Type"::DELETE, Uri)) + end; + + [NonDebuggable] + procedure Move(Uri: Text; DestinationUri: Text) WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; + var + RequestMessage: HttpRequestMessage; + Headers: HttpHeaders; + begin + RequestMessage := PrepareRequestMsg('MOVE', Uri); + RequestMessage.GetHeaders(Headers); + + Headers.Add('Destination', DestinationUri); + WebDAVOperationResponse := SendRequest(RequestMessage); + end; + + [NonDebuggable] + procedure Copy(Uri: Text; DestinationUri: Text) WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; + var + RequestMessage: HttpRequestMessage; + Headers: HttpHeaders; + begin + RequestMessage := PrepareRequestMsg('COPY', Uri); + RequestMessage.GetHeaders(Headers); + + Headers.Add('Destination', DestinationUri); + WebDAVOperationResponse := SendRequest(RequestMessage); + end; + + [NonDebuggable] + procedure Propfind(Uri: Text; Recursive: Boolean) WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; + var + WebDAVHttpContent: Codeunit "WebDAV Http Content"; + RequestMessage: HttpRequestMessage; + Headers: HttpHeaders; + begin + WebDAVHttpContent.FromXML(PreparePropfindRequest()); + RequestMessage := PrepareRequestMsg('PROPFIND', Uri, WebDAVHttpContent); + RequestMessage.GetHeaders(Headers); + + // Recursive + if Headers.Contains('Dephth') then + Headers.Remove('Depth'); + if Recursive then + Headers.Add('Depth', 'infinity') + else + Headers.Add('Depth', '1'); + + WebDAVOperationResponse := SendRequest(RequestMessage); + end; + + local procedure PrepareRequestMsg(HttpRequestType: Enum "Http Request Type"; Uri: Text): HttpRequestMessage + begin + Exit(PrepareRequestMsg(Format(HttpRequestType), Uri)); + end; + + local procedure PrepareRequestMsg(HttpRequestType: Text; Uri: Text) RequestMessage: HttpRequestMessage + begin + RequestMessage.Method(HttpRequestType); + RequestMessage.SetRequestUri(Uri); + end; + + local procedure PrepareRequestMsg(HttpRequestType: Enum "Http Request Type"; Uri: Text; WebDAVHttpContent: Codeunit "WebDAV Http Content") RequestMessage: HttpRequestMessage + begin + Exit(PrepareRequestMsg(Format(HttpRequestType), Uri, WebDAVHttpContent)); + end; + + local procedure PrepareRequestMsg(HttpRequestType: Text; Uri: Text; var WebDAVHttpContent: Codeunit "WebDAV Http Content") RequestMessage: HttpRequestMessage + var + Headers: HttpHeaders; + HttpContent: HttpContent; + begin + RequestMessage.Method(HttpRequestType); + RequestMessage.SetRequestUri(Uri); + + RequestMessage.GetHeaders(Headers); + if WebDAVHttpContent.GetContentLength() > 0 then begin + + HttpContent := WebDAVHttpContent.GetContent(); + HttpContent.GetHeaders(Headers); + + if Headers.Contains('Content-Type') then + Headers.Remove('Content-Type'); + + if WebDAVHttpContent.GetContentType() <> '' then + Headers.Add('Content-Type', WebDAVHttpContent.GetContentType()); + + RequestMessage.Content(HttpContent); + end; + end; + + local procedure SendRequest(HttpRequestMessage: HttpRequestMessage) OperationResponse: Codeunit "WebDAV Operation Response" + var + HttpResponseMessage: HttpResponseMessage; + HttpClient: HttpClient; + IsHandled: Boolean; + begin + OnBeforeSendRequest(HttpRequestMessage, OperationResponse, IsHandled, HttpRequestMessage.Method()); + + if not IsHandled then begin + Authorization.Authorize(HttpRequestMessage); + if not HttpClient.Send(HttpRequestMessage, HttpResponseMessage) then + Error(OperationNotSuccessfulErr); + + OperationResponse.SetHttpResponse(HttpResponseMessage); + + end; + end; + + local procedure PreparePropfindRequest() XMLDoc: XmlDocument + var + Propfind: XmlElement; + Prop: XmlElement; + NameSpaceManager: XmlNamespaceManager; + begin + XMlDoc := XmlDocument.Create(); + XmlDoc.SetDeclaration(XmlDeclaration.Create('1.0', 'utf-8', 'yes')); + + Propfind := XmlElement.Create('propfind', 'DAV:'); + Propfind.Add(XmlAttribute.CreateNamespaceDeclaration('d', 'DAV:')); + + Prop := XmlElement.Create('prop', 'DAV:'); + Prop.Add(XmlElement.Create('displayname', 'DAV:')); + Prop.Add(XmlElement.Create('resourcetype', 'DAV:')); + Prop.Add(XmlElement.Create('getcontenttype', 'DAV:')); + Prop.Add(XmlElement.Create('getcontentlength', 'DAV:')); + Prop.Add(XmlElement.Create('creationdate', 'DAV:')); + Prop.Add(XmlElement.Create('getlastmodified', 'DAV:')); + + + Propfind.Add(Prop); + XMlDoc.Add(Propfind); + end; + + [InternalEvent(false, true)] + local procedure OnBeforeSendRequest(HttpRequestMessage: HttpRequestMessage; var WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; var IsHandled: Boolean; Method: Text) + begin + end; + +} \ No newline at end of file diff --git a/Modules/System/WebDAV/src/Model/WebDAVContent.Table.al b/Modules/System/WebDAV/src/Model/WebDAVContent.Table.al new file mode 100644 index 0000000000..9c9f099b66 --- /dev/null +++ b/Modules/System/WebDAV/src/Model/WebDAVContent.Table.al @@ -0,0 +1,66 @@ +table 5678 "WebDAV Content" +{ + Access = Public; + DataClassification = SystemMetadata; // Data classification is SystemMetadata as the table is temporary + Caption = 'WebDAV Folder'; + TableType = Temporary; + Extensible = false; + + fields + { + field(1; "Entry No."; Integer) + { + Caption = 'Entry No.'; + AutoIncrement = true; + } + field(10; Name; Text[250]) + { + Caption = 'Title'; + } + field(11; "Full Url"; Text[2048]) + { + Caption = 'Full Url'; + } + field(12; "Relative Url"; Text[2048]) + { + Caption = 'Relative Url'; + } + field(13; Level; Integer) + { + Caption = 'Level'; + } + field(20; "Is Collection"; Boolean) + { + Caption = 'Is Collection'; + } + field(22; "Content Type"; Text[2048]) + { + Caption = 'Content Type'; + } + field(23; "Content Length"; Integer) + { + Caption = 'Content Length'; + } + field(30; "Creation Date"; DateTime) + { + Caption = 'Creation Date'; + } + + field(31; "Last Modified Date"; DateTime) + { + Caption = 'Last Modified Date'; + } + } + + + + + + keys + { + key(PK; "Entry No.") + { + Clustered = true; + } + } +} \ No newline at end of file diff --git a/Modules/System/WebDAV/src/Model/WebDAVContentParser.Codeunit.al b/Modules/System/WebDAV/src/Model/WebDAVContentParser.Codeunit.al new file mode 100644 index 0000000000..c976226080 --- /dev/null +++ b/Modules/System/WebDAV/src/Model/WebDAVContentParser.Codeunit.al @@ -0,0 +1,103 @@ + +codeunit 5682 "WebDAV Content Parser" +{ + + Access = Internal; + + [NonDebuggable] + procedure Initialize(InitBaseUrl: Text; InitOnlyFiles: Boolean; InitOnlyCollections: Boolean) + begin + BaseUrl := InitBaseUrl; + OnlyFiles := InitOnlyFiles; + OnlyCollections := InitOnlyCollections; + end; + + [NonDebuggable] + procedure Parse(Payload: Text; var WebDAVContent: Record "WebDAV Content") + var + XmlDoc: XmlDocument; + ChildNodes: XmlNodeList; + ResponseNode: XmlNode; + begin + XmlNamespaceManager.AddNamespace('dav', 'DAV:'); + + XmlDocument.ReadFrom(Payload, XmlDoc); + XmlDoc.SelectNodes('//dav:response', XmlNamespaceManager, ChildNodes); + foreach ResponseNode in ChildNodes do + ParseSingle(ResponseNode, WebDAVContent); + end; + + [NonDebuggable] + procedure ParseSingle(XmlNode: XmlNode; var WebDAVContent: Record "WebDAV Content") + begin + WebDAVContent."Is Collection" := HasNode(XmlNode, 'dav:propstat/dav:prop/dav:resourcetype/dav:collection'); + + if OnlyCollections then + if not WebDAVContent."Is Collection" then + exit; + if OnlyFiles then + if WebDAVContent."Is Collection" then + exit; + + WebDAVContent."Full Url" := GetValueAsText(XmlNode, 'dav:href'); + WebDAVContent."Relative Url" := GetRelativeUrl(WebDAVContent."Full Url"); + WebDAVContent.Level := GetLevelFromPath(WebDAVContent."Relative Url"); + + WebDAVContent."Name" := GetValueAsText(XmlNode, 'dav:propstat/dav:prop/dav:displayname'); + WebDAVContent."Content Type" := GetValueAsText(XmlNode, 'dav:propstat/dav:prop/dav:getcontenttype'); + if Evaluate(WebDAVContent."Content Length", GetValueAsText(XmlNode, 'dav:propstat/dav:prop/dav:getcontentlength')) then; + + if Evaluate(WebDAVContent."Creation Date", GetValueAsText(XmlNode, 'dav:propstat/dav:prop/dav:creationdate')) then; + if Evaluate(WebDAVContent."Last Modified Date", GetValueAsText(XmlNode, 'dav:propstat/dav:prop/dav:getlastmodified')) then; + + WebDAVContent."Entry No." := GetNextEntryNo(); + WebDAVContent.Insert(); + end; + + [NonDebuggable] + procedure GetValueAsText(XmlNode: XmlNode; PropertyName: Text): Text + var + ChildNode: XmlNode; + XmlElement: XmlElement; + begin + if XmlNode.SelectSingleNode(PropertyName, XmlNamespaceManager, ChildNode) then begin + XmlElement := ChildNode.AsXmlElement(); + Exit(XmlElement.InnerText()); + end; + end; + + [NonDebuggable] + procedure HasNode(XmlNode: XmlNode; PropertyName: Text): Boolean + var + ChildNode: XmlNode; + XmlElement: XmlElement; + begin + Exit(XmlNode.SelectSingleNode(PropertyName, XmlNamespaceManager, ChildNode)); + end; + + local procedure GetNextEntryNo(): Integer; + begin + NextEntryNo += 1; + Exit(NextEntryNo); + end; + + local procedure GetLevelFromPath(Path: Text): Integer + begin + Exit(Path.Split('/').Count); + end; + + local procedure GetRelativeUrl(FullUrl: Text) RelativeUrl: Text + begin + if FullUrl.StartsWith(BaseUrl) then + RelativeUrl := FullUrl.Replace(BaseUrl, ''); + RelativeUrl := RelativeUrl.TrimStart('/'); + end; + + var + [NonDebuggable] + XmlNameSpaceManager: XmlNamespaceManager; + BaseUrl: Text; + NextEntryNo: Integer; + OnlyFiles: Boolean; + OnlyCollections: Boolean; +} \ No newline at end of file diff --git a/Modules/System/WebDAV/src/WebDAVClient.Codeunit.al b/Modules/System/WebDAV/src/WebDAVClient.Codeunit.al new file mode 100644 index 0000000000..1d224b71b9 --- /dev/null +++ b/Modules/System/WebDAV/src/WebDAVClient.Codeunit.al @@ -0,0 +1,84 @@ +codeunit 5678 "WebDAV Client" +{ + Access = Public; + + var + WebDAVClientImpl: Codeunit "WebDAV Client Impl."; + + procedure Initialize(BaseUrl: Text; WebDAVAuthorization: Interface "WebDAV Authorization") + begin + WebDAVClientImpl.Initialize(BaseUrl, WebDAVAuthorization); + end; + + // [NonDebuggable] + procedure MakeCollection(): Boolean + begin + Exit(WebDAVClientImpl.MakeCollection()); + end; + + // [NonDebuggable] + procedure Delete(): Boolean + begin + Exit(WebDAVClientImpl.Delete()); + end; + + // [NonDebuggable] + procedure Move(Destination: Text): Boolean + begin + Exit(WebDAVClientImpl.Move(Destination)); + end; + + // [NonDebuggable] + procedure Copy(Destination: Text): Boolean + begin + Exit(WebDAVClientImpl.Copy(Destination)); + end; + + // [NonDebuggable] + procedure Put(Content: Text): Boolean + begin + Exit(WebDAVClientImpl.Put(Content)); + end; + + // [NonDebuggable] + procedure Put(Content: InStream): Boolean + begin + Exit(WebDAVClientImpl.Put(Content)); + end; + + // [NonDebuggable] + procedure Put(Content: HttpContent): Boolean + begin + Exit(WebDAVClientImpl.Put(Content)); + end; + + // [NonDebuggable] + procedure GetContent(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean + begin + Exit(WebDAVClientImpl.GetContent(WebDAVContent, Recursive)); + end; + + // [NonDebuggable] + procedure GetCollections(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean + begin + Exit(WebDAVClientImpl.GetCollections(WebDAVContent, Recursive)); + end; + + // [NonDebuggable] + procedure GetFiles(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean + begin + Exit(WebDAVClientImpl.GetFiles(WebDAVContent, Recursive)); + end; + + [NonDebuggable] + procedure GetFileContent(var ResponseInStream: InStream): Boolean + begin + Exit(WebDAVClientImpl.GetFileContent(ResponseInStream)); + end; + + [NonDebuggable] + procedure GetFileContentAsText(var ResponseText: Text): Boolean + begin + Exit(WebDAVClientImpl.GetFileContentAsText(ResponseText)); + end; +} \ No newline at end of file diff --git a/Modules/System/WebDAV/src/WebDAVClientImpl.Codeunit.al b/Modules/System/WebDAV/src/WebDAVClientImpl.Codeunit.al new file mode 100644 index 0000000000..291a6d5639 --- /dev/null +++ b/Modules/System/WebDAV/src/WebDAVClientImpl.Codeunit.al @@ -0,0 +1,192 @@ +codeunit 5679 "WebDAV Client Impl." +{ + Access = Internal; + + var + + [NonDebuggable] + WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; + [NonDebuggable] + Authorization: Interface "WebDAV Authorization"; + [NonDebuggable] + Uri: Text; + + [NonDebuggable] + procedure Initialize(InitUri: Text; InitAuthorization: Interface "WebDAV Authorization") + begin + Uri := InitUri; + Authorization := InitAuthorization; + end; + + [NonDebuggable] + procedure MakeCollection(): Boolean + var + WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; + begin + WebDAVRequestHelper.SetAuthorization(Authorization); + WebDAVOperationResponse := WebDAVRequestHelper.MkCol(Uri); + + if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then + Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); + + Exit(true); + end; + + [NonDebuggable] + procedure Delete(): Boolean + var + WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; + begin + WebDAVRequestHelper.SetAuthorization(Authorization); + WebDAVOperationResponse := WebDAVRequestHelper.Delete(Uri); + + if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then + Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); + + Exit(true); + end; + + + [NonDebuggable] + procedure Put(Content: InStream): Boolean + var + HttpContent: HttpContent; + begin + HttpContent.WriteFrom(Content); + Exit(Put(HttpContent)); + end; + + [NonDebuggable] + procedure Put(Content: Text): Boolean + var + HttpContent: HttpContent; + begin + HttpContent.WriteFrom(Content); + Exit(Put(HttpContent)); + end; + + [NonDebuggable] + procedure Put(Content: HttpContent): Boolean + var + WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; + begin + WebDAVRequestHelper.SetAuthorization(Authorization); + WebDAVOperationResponse := WebDAVRequestHelper.Put(Uri, Content); + + if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then + Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); + + Exit(true); + end; + + [NonDebuggable] + procedure Move(Destination: Text): Boolean + var + WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; + begin + WebDAVRequestHelper.SetAuthorization(Authorization); + WebDAVOperationResponse := WebDAVRequestHelper.Move(Uri, Destination); + + if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then + Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); + + Exit(true); + end; + + + [NonDebuggable] + procedure Copy(Destination: Text): Boolean + var + WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; + begin + WebDAVRequestHelper.SetAuthorization(Authorization); + WebDAVOperationResponse := WebDAVRequestHelper.Copy(Uri, Destination); + + if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then + Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); + + Exit(true); + end; + + + [NonDebuggable] + procedure GetContent(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean + var + WebDAVContentParser: Codeunit "WebDAV Content Parser"; + ResponseContent: Text; + begin + ResponseContent := GetPropfindResponse(Recursive); + + WebDAVContentParser.Initialize(Uri, false, false); + WebDAVContentParser.Parse(ResponseContent, WebDAVContent); + + Exit(true); + end; + + [NonDebuggable] + procedure GetCollections(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean + var + WebDAVContentParser: Codeunit "WebDAV Content Parser"; + ResponseContent: Text; + begin + ResponseContent := GetPropfindResponse(Recursive); + + WebDAVContentParser.Initialize(Uri, false, true); + WebDAVContentParser.Parse(ResponseContent, WebDAVContent); + Exit(true); + end; + + [NonDebuggable] + procedure GetFiles(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean + var + WebDAVContentParser: Codeunit "WebDAV Content Parser"; + ResponseContent: Text; + begin + ResponseContent := GetPropfindResponse(Recursive); + + WebDAVContentParser.Initialize(Uri, true, false); + WebDAVContentParser.Parse(ResponseContent, WebDAVContent); + + Exit(true); + end; + + local procedure GetPropfindResponse(Recursive: Boolean) ResponseContent: Text; + var + WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; + begin + WebDAVRequestHelper.SetAuthorization(Authorization); + WebDAVOperationResponse := WebDAVRequestHelper.Propfind(Uri, Recursive); + + if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then + Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); + + WebDAVOperationResponse.GetResultAsText(ResponseContent); + end; + + [NonDebuggable] + procedure GetFileContent(var ResponseInStream: InStream): Boolean + var + WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; + begin + WebDAVRequestHelper.SetAuthorization(Authorization); + WebDAVOperationResponse := WebDAVRequestHelper.Get(Uri); + + if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then + Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); + + WebDAVOperationResponse.GetResultAsStream(ResponseInStream); + + Exit(true); + end; + + [NonDebuggable] + procedure GetFileContentAsText(var ResponseText: Text): Boolean + var + ResponseInStream: InStream; + begin + GetFileContent(ResponseInStream); + ResponseInStream.Read(ResponseText); + Exit(true); + end; + +} \ No newline at end of file From 270947a0d66faa046a1abdb30bec61ed17e57dce Mon Sep 17 00:00:00 2001 From: Julian Tillmann Date: Mon, 13 Feb 2023 11:03:44 +0100 Subject: [PATCH 3/4] Test Automation + Bugfixes --- Modules/System Test Libraries/WebDAV/app.json | 40 +++ .../src/WebDAVDummyAuthorization.Codeunit.al | 12 + .../WebDAV/src/WebDAVTestLibrary.Codeunit.al | 204 ++++++++++++ Modules/System Tests/WebDAV/app.json | 46 +++ .../WebDAV/src/WebDAVClientTest.Codeunit.al | 309 ++++++++++++++++++ .../WebDAVOperationResponse.Codeunit.al | 20 +- .../Helper/WebDAVRequestHelper.Codeunit.al | 22 +- .../WebDAV/src/Model/WebDAVContent.Table.al | 2 +- .../src/Model/WebDAVContentParser.Codeunit.al | 15 +- .../WebDAV/src/WebDAVClient.Codeunit.al | 34 +- .../WebDAV/src/WebDAVClientImpl.Codeunit.al | 46 ++- 11 files changed, 704 insertions(+), 46 deletions(-) create mode 100644 Modules/System Test Libraries/WebDAV/app.json create mode 100644 Modules/System Test Libraries/WebDAV/src/WebDAVDummyAuthorization.Codeunit.al create mode 100644 Modules/System Test Libraries/WebDAV/src/WebDAVTestLibrary.Codeunit.al create mode 100644 Modules/System Tests/WebDAV/app.json create mode 100644 Modules/System Tests/WebDAV/src/WebDAVClientTest.Codeunit.al diff --git a/Modules/System Test Libraries/WebDAV/app.json b/Modules/System Test Libraries/WebDAV/app.json new file mode 100644 index 0000000000..f51a38b360 --- /dev/null +++ b/Modules/System Test Libraries/WebDAV/app.json @@ -0,0 +1,40 @@ +{ + "id": "ff0caa38-65a2-49c5-a7e2-6a0475cfc60e", + "name": "SharePoint Test Library", + "publisher": "Microsoft", + "version": "21.4.0.0", + "brief": "Test libraries for the SharePoint module", + "description": "Provides a set of AL functionality and Helper libraries to make use of SharePoint REST API", + "privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009", + "EULA": "https://go.microsoft.com/fwlink/?linkid=2009120", + "help": "https://go.microsoft.com/fwlink/?linkid=2103698", + "url": "https://go.microsoft.com/fwlink/?linkid=724011", + "logo": "", + "dependencies": [ + { + "id": "199527d2-53dd-48e1-8732-8850d4f9e45b", + "name": "WebDAV", + "publisher": "Microsoft", + "version": "21.4.0.0" + } + ], + "screenshots": [ + + ], + "features": [ + + ], + "platform": "21.0.0.0", + "idRanges": [ + { + "from": 135678, + "to": 135689 + } + ], + "contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?linkid=2206603", + "resourceExposurePolicy": { + "allowDebugging": true, + "allowDownloadingSource": true, + "includeSourceInSymbolFile": true + } +} \ No newline at end of file diff --git a/Modules/System Test Libraries/WebDAV/src/WebDAVDummyAuthorization.Codeunit.al b/Modules/System Test Libraries/WebDAV/src/WebDAVDummyAuthorization.Codeunit.al new file mode 100644 index 0000000000..77bff4b1a0 --- /dev/null +++ b/Modules/System Test Libraries/WebDAV/src/WebDAVDummyAuthorization.Codeunit.al @@ -0,0 +1,12 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +codeunit 135679 "Dummy WebDAV Authorization" implements "WebDAV Authorization" +{ + procedure Authorize(var HttpRequestMessage: HttpRequestMessage); + begin + // Does nothing + end; +} \ No newline at end of file diff --git a/Modules/System Test Libraries/WebDAV/src/WebDAVTestLibrary.Codeunit.al b/Modules/System Test Libraries/WebDAV/src/WebDAVTestLibrary.Codeunit.al new file mode 100644 index 0000000000..e812af7754 --- /dev/null +++ b/Modules/System Test Libraries/WebDAV/src/WebDAVTestLibrary.Codeunit.al @@ -0,0 +1,204 @@ +codeunit 136789 "WebDAV Test Library" +{ + EventSubscriberInstance = Manual; + + var + RequestMessage: HttpRequestMessage; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"WebDAV Request Helper", 'OnBeforeSendRequest', '', false, false)] + local procedure RunOnBeforeSendRequest(HttpRequestMessage: HttpRequestMessage; var WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; var IsHandled: Boolean; Method: Text) + var + HttpHeaders: HttpHeaders; + Uri: Text; + begin + IsHandled := true; + RequestMessage := HttpRequestMessage; + HttpRequestMessage.GetHeaders(HttpHeaders); + Uri := HttpRequestMessage.GetRequestUri; + + case HttpRequestMessage.Method of + 'PROPFIND': + begin + if HttpHeaders.Contains('Depth') then + if GetDepth(HttpHeaders) then + GetPropfindRecursiveResponse(Uri, WebDAVOperationResponse) + else + GetPropfindResponse(Uri, WebDAVOperationResponse); + end; + 'MKCOL': + GetCreatedResponse(Uri, WebDAVOperationResponse); + 'GET': + GetResponseText(Uri, WebDAVOperationResponse); + 'COPY': + GetSuccessfullResponse(Uri, WebDAVOperationResponse); + 'MOVE': + GetSuccessfullResponse(Uri, WebDAVOperationResponse); + 'DELETE': + GetSuccessfullResponse(Uri, WebDAVOperationResponse); + 'PUT': + GetSuccessfullResponse(Uri, WebDAVOperationResponse); + else + Error('No matching test response for %1', Uri); + end; + end; + + procedure GetRequestMessage(): HttpRequestMessage + begin + exit(RequestMessage); + end; + + local procedure GetCreatedResponse(Uri: Text; var WebDAVOperationResponse: Codeunit "WebDAV Operation Response") + var + HttpHeaders: HttpHeaders; + begin + WebDAVOperationResponse.SetHttpResponse('', HttpHeaders, 201, true, 'Created'); + end; + + local procedure GetResponseText(Uri: Text; var WebDAVOperationResponse: Codeunit "WebDAV Operation Response") + var + HttpHeaders: HttpHeaders; + begin + WebDAVOperationResponse.SetHttpResponse('This is a test string.', HttpHeaders, 400, true, ''); + end; + + local procedure GetSuccessfullResponse(Uri: Text; var WebDAVOperationResponse: Codeunit "WebDAV Operation Response") + var + HttpHeaders: HttpHeaders; + begin + WebDAVOperationResponse.SetHttpResponse('', HttpHeaders, 400, true, ''); + end; + + local procedure GetPropfindResponse(Uri: Text; var WebDAVOperationResponse: Codeunit "WebDAV Operation Response") + var + HttpHeaders: HttpHeaders; + ResponseContent: TextBuilder; + begin + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(''); + + // Folders = 4; Files = 33 + // Uri Folder + AddPropfindFolder(ResponseContent, Uri, GetLastUrlItemName(Uri), 'Sun, 01 Jan 2023 12:00:00 GMT', 'Sun, 01 Jan 2023 12:00:00 GMT'); + AddPropFindFile(ResponseContent, Uri, 'index.html', 'text/html', 123, 'Sun, 01 Jan 2023 12:01:01 GMT', 'Sun, 01 Jan 2023 12:01:01 GMT'); + AddPropFindFile(ResponseContent, Uri, 'logo.png', 'image/png', 4567, 'Sun, 01 Jan 2023 12:02:02 GMT', 'Sun, 01 Jan 2023 12:02:02 GMT'); + AddPropFindFile(ResponseContent, Uri, 'response.xml', 'text/xml', 890, 'Sun, 01 Jan 2023 12:03:03 GMT', 'Sun, 01 Jan 2023 12:03:03 GMT'); + + // Folder1 + AddPropfindFolder(ResponseContent, Uri, '/Folder1', 'Mon, 02 Jan 2023 12:00:00 GMT', 'Mon, 02 Jan 2023 12:00:00 GMT'); + // Folder2 + AddPropfindFolder(ResponseContent, Uri, 'Folder2', 'Fri, 06 Jan 2023 12:00:00 GMT', 'Fri, 06 Jan 2023 12:00:00 GMT'); + // Folder3 + AddPropfindFolder(ResponseContent, Uri, 'Folder3', 'Mon, 09 Jan 2023 12:00:00 GMT', 'Mon, 09 Jan 2023 12:00:00 GMT'); + + ResponseContent.AppendLine(''); + WebDAVOperationResponse.SetHttpResponse(ResponseContent.ToText(), HttpHeaders, 400, true, ''); + end; + + local procedure GetPropfindRecursiveResponse(Uri: Text; var WebDAVOperationResponse: Codeunit "WebDAV Operation Response") + var + HttpHeaders: HttpHeaders; + ResponseContent: TextBuilder; + begin + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(''); + + // Folders = 10; Files = 13 + // Uri Folder + AddPropfindFolder(ResponseContent, Uri, GetLastUrlItemName(Uri), 'Sun, 01 Jan 2023 12:00:00 GMT', 'Sun, 01 Jan 2023 12:00:00 GMT'); + AddPropFindFile(ResponseContent, Uri, 'index.html', 'text/html', 123, 'Sun, 01 Jan 2023 12:01:01 GMT', 'Sun, 01 Jan 2023 12:01:01 GMT'); + AddPropFindFile(ResponseContent, Uri, 'logo.png', 'image/png', 4567, 'Sun, 01 Jan 2023 12:02:02 GMT', 'Sun, 01 Jan 2023 12:02:02 GMT'); + AddPropFindFile(ResponseContent, Uri, 'response.xml', 'text/xml', 890, 'Sun, 01 Jan 2023 12:03:03 GMT', 'Sun, 01 Jan 2023 12:03:03 GMT'); + + // Folder1 + AddPropfindFolder(ResponseContent, Uri, '/Folder1', 'Mon, 02 Jan 2023 12:00:00 GMT', 'Mon, 02 Jan 2023 12:00:00 GMT'); + AddPropFindFile(ResponseContent, Uri + '/Folder1', 'pic.jpg', 'image/jpeg', 4666, 'Mon, 02 Jan 2023 13:13:13 GMT', 'Mon, 02 Jan 2023 13:13:13 GMT'); + AddPropFindFile(ResponseContent, Uri + '/Folder1', 'pic.gif', 'image/gif', 466, 'Mon, 02 Jan 2023 14:14:14 GMT', 'Mon, 02 Jan 2023 14:14:14 GMT'); + // Folder1/Subfolder1 + AddPropfindFolder(ResponseContent, Uri + '/Folder1', 'SubFolder1', 'Tue, 03 Jan 2023 12:00:00 GMT', 'Tue, 03 Jan 2023 12:00:00 GMT'); + AddPropFindFile(ResponseContent, Uri + '/Folder1/Subfolder1', 'file1.txt', 'text/plain', 21, 'Tue, 03 Jan 2023 13:13:13 GMT', 'Tue, 03 Jan 2023 13:13:13 GMT'); + AddPropFindFile(ResponseContent, Uri + '/Folder1/Subfolder1', 'file2.txt', 'text/plain', 500, 'Tue, 03 Jan 2023 15:06:59 GMT', 'Tue, 03 Jan 2023 15:06:59 GMT'); + AddPropFindFile(ResponseContent, Uri + '/Folder1/Subfolder1', 'file3.txt', 'text/plain', 33, 'Tue, 03 Jan 2023 00:00:00 GMT', 'Tue, 03 Jan 2023 00:00:00 GMT'); + // Folder1/Subfolder2 + AddPropfindFolder(ResponseContent, Uri + '/Folder1', 'SubFolder2', 'Wed, 04 Jan 2023 12:00:00 GMT', 'Wed, 04 Jan 2023 12:00:00 GMT'); + AddPropFindFile(ResponseContent, Uri + '/Folder1/Subfolder2', 'file1.pdf', 'application/pdf', 53950, 'Wed, 04 Jan 2023 23:59:59 GMT', 'Wed, 04 Jan 2023 23:59:59 GMT'); + AddPropFindFile(ResponseContent, Uri + '/Folder1/Subfolder2', 'file2.fob', 'application/octet-stream', 373137165, 'Wed, 04 Jan 2023 11:59:59 GMT', 'Wed, 04 Jan 2023 11:59:59 GMT'); + // Folder1/Subfolder3 + AddPropfindFolder(ResponseContent, Uri + '/Folder1', 'SubFolder3', 'Thu, 05 Jan 2023 12:00:00 GMT', 'Thu, 05 Jan 2023 12:00:00 GMT'); + // Folder2 + AddPropfindFolder(ResponseContent, Uri, 'Folder2', 'Fri, 06 Jan 2023 12:00:00 GMT', 'Fri, 06 Jan 2023 12:00:00 GMT'); + AddPropfindFolder(ResponseContent, Uri + '/Folder2', 'SubFolder1', 'Sat, 07 Jan 2023 12:00:00 GMT', 'Sat, 07 Jan 2023 12:00:00 GMT'); + AddPropfindFolder(ResponseContent, Uri + '/Folder2/SubFolder1', 'SubSubFolder1', 'Sat, 07 Jan 2023 20:00:00 GMT', 'Sat, 07 Jan 2023 20:00:00 GMT'); + AddPropfindFolder(ResponseContent, Uri + '/Folder2', 'SubFolder2', 'Sun, 08 Jan 2023 12:00:00 GMT', 'Sun, 08 Jan 2023 12:00:00 GMT'); + // Folder3 + AddPropfindFolder(ResponseContent, Uri, 'Folder3', 'Mon, 09 Jan 2023 12:00:00 GMT', 'Mon, 09 Jan 2023 12:00:00 GMT'); + AddPropFindFile(ResponseContent, Uri + '/Folder3', 'file1.txt', 'text/plain', 21, 'Mon, 09 Jan 2023 13:13:13 GMT', 'Sun, 31 Dec 2023 23:59:59 GMT'); + AddPropFindFile(ResponseContent, Uri + '/Folder3', 'file2.txt', 'text/plain', 500, 'Mon, 09 Jan 2023 15:06:59 GMT', 'Mon, 09 Jan 2023 15:06:59 GMT'); + AddPropFindFile(ResponseContent, Uri + '/Folder3', 'file3.txt', 'text/plain', 33, 'Mon, 09 Jan 2023 00:00:00 GMT', 'Mon, 09 Jan 2023 00:00:00 GMT'); + + ResponseContent.AppendLine(''); + WebDAVOperationResponse.SetHttpResponse(ResponseContent.ToText(), HttpHeaders, 400, true, ''); + end; + + + local procedure AddPropfindFolder(var ResponseContent: TextBuilder; Uri: Text; FolderName: Text; CreationDate: Text; LastModifiedDate: Text) + begin + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(StrSubstNo('%1', Uri + '/' + FolderName)); + ResponseContent.AppendLine(''); + ResponseContent.AppendLine('HTTP/1.1 200 OK'); + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(StrSubstNo('%1', LastModifiedDate)); + ResponseContent.AppendLine(StrSubstNo('%1', FolderName)); + ResponseContent.AppendLine('0'); + ResponseContent.AppendLine(StrSubstNo('%1', CreationDate)); + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(''); + end; + + local procedure AddPropfindFile(var ResponseContent: TextBuilder; Uri: Text; FileName: Text; ContentType: Text; ContentLength: Integer; CreationDate: Text; LastModifiedDate: Text) + begin + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(StrSubstNo('%1', Uri + '/' + Filename)); + ResponseContent.AppendLine(''); + ResponseContent.AppendLine('HTTP/1.1 200 OK'); + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(StrSubstNo('%1', ContentType)); + ResponseContent.AppendLine(StrSubstNo('%1', LastModifiedDate)); + ResponseContent.AppendLine(StrSubstNo('%1', Filename)); + ResponseContent.AppendLine(StrSubstNo('%1', ContentLength)); + ResponseContent.AppendLine(StrSubstNo('%1', CreationDate)); + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(''); + ResponseContent.AppendLine(''); + end; + + local procedure GetLastUrlItemName(Uri: Text) LastUriItemName: Text; + var + UriParts: List of [Text]; + begin + UriParts := Uri.Split('/'); + UriParts.Get(UriParts.Count, LastUriItemName); + end; + + local procedure GetDepth(HttpHeaders: HttpHeaders) IsRecursive: Boolean; + var + Values: List of [Text]; + begin + HttpHeaders.GetValues('Depth', Values); + case Values.Get(1) of + 'infinity': + exit(true); + '1': + exit(false); + // TODO + '0': + Error('Not yet implemented'); + end; + end; +} \ No newline at end of file diff --git a/Modules/System Tests/WebDAV/app.json b/Modules/System Tests/WebDAV/app.json new file mode 100644 index 0000000000..d58b37372e --- /dev/null +++ b/Modules/System Tests/WebDAV/app.json @@ -0,0 +1,46 @@ +{ + "id": "ff0caa38-65a2-49c5-a7e2-6a0475cfc60e", + "name": "SharePoint Test Library", + "publisher": "Microsoft", + "version": "21.4.0.0", + "brief": "Test libraries for the SharePoint module", + "description": "Provides a set of AL functionality and Helper libraries to make use of SharePoint REST API", + "privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009", + "EULA": "https://go.microsoft.com/fwlink/?linkid=2009120", + "help": "https://go.microsoft.com/fwlink/?linkid=2103698", + "url": "https://go.microsoft.com/fwlink/?linkid=724011", + "logo": "", + "dependencies": [ + { + "id": "199527d2-53dd-48e1-8732-8850d4f9e45b", + "name": "WebDAV", + "publisher": "Microsoft", + "version": "21.4.0.0" + }, + { + "id": "ff0caa38-65a2-49c5-a7e2-6a0475cfc60e", + "name": "SharePoint Test Library", + "publisher": "Microsoft", + "version": "21.4.0.0" + } + ], + "screenshots": [ + + ], + "features": [ + + ], + "platform": "21.0.0.0", + "idRanges": [ + { + "from": 135690, + "to": 135699 + } + ], + "contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?linkid=2206603", + "resourceExposurePolicy": { + "allowDebugging": true, + "allowDownloadingSource": true, + "includeSourceInSymbolFile": true + } +} \ No newline at end of file diff --git a/Modules/System Tests/WebDAV/src/WebDAVClientTest.Codeunit.al b/Modules/System Tests/WebDAV/src/WebDAVClientTest.Codeunit.al new file mode 100644 index 0000000000..a6626aca3c --- /dev/null +++ b/Modules/System Tests/WebDAV/src/WebDAVClientTest.Codeunit.al @@ -0,0 +1,309 @@ +codeunit 135690 "WebDAV Client Test" +{ + Subtype = Test; + + var + Assert: Codeunit "Library Assert"; + Any: Codeunit Any; + WebDAVClient: Codeunit "WebDAV Client"; + WebDAVTestLibrary: Codeunit "WebDAV Test Library"; + DummyWebDAVAuthorization: Codeunit "Dummy WebDAV Authorization"; + XmlNamespaceManager: XmlNamespaceManager; + BaseUrl: Text; + IsInitialized: Boolean; + DiffValueLbl: Label 'Different %1 value expected'; + + [TEST] + procedure TestGetCollections() + var + WebDAVContent: Record "WebDAV Content"; + IsSuccess: Boolean; + begin + Initialize(); + + IsSuccess := WebDAVClient.GetCollections(WebDAVContent, false); + Assert.AreEqual(true, IsSuccess, 'Successfull operation expected'); + Assert.AreEqual(4, WebDAVContent.Count, 'Expected 4 Records'); + + WebDAVContent.FindFirst(); + WebDAVContent.Next(2); + + Assert.AreEqual('Folder2', WebDAVContent.Name, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Name))); + Assert.AreEqual(0, WebDAVContent."Content Length", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Length"))); + Assert.AreEqual('', WebDAVContent."Content Type", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Type"))); + + Assert.AreEqual(true, WebDAVContent."Is Collection", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Is Collection"))); + Assert.AreEqual(1, WebDAVContent.Level, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Level))); + Assert.AreEqual(BaseUrl + '/Folder2', WebDAVContent."Full Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Full Url"))); + Assert.AreEqual('Folder2', WebDAVContent."Relative Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Relative Url"))); + Assert.AreEqual('2023-01-06T12:00:00Z', Format(WebDAVContent."Creation Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Creation Date"))); + Assert.AreEqual('2023-01-06T12:00:00Z', Format(WebDAVContent."Last Modified Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Last Modified Date"))); + end; + + [TEST] + procedure TestGetFiles() + var + WebDAVContent: Record "WebDAV Content"; + IsSuccess: Boolean; + begin + Initialize(); + + IsSuccess := WebDAVClient.GetFiles(WebDAVContent, false); + Assert.AreEqual(true, IsSuccess, 'Successfull operation expected'); + + Assert.AreEqual(3, WebDAVContent.Count, 'Expected 3 records'); + WebDAVContent.FindFirst(); + WebDAVContent.Next(); + + Assert.AreEqual('logo.png', WebDAVContent.Name, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Name))); + Assert.AreEqual(4567, WebDAVContent."Content Length", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Length"))); + Assert.AreEqual('image/png', WebDAVContent."Content Type", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Type"))); + + Assert.AreEqual(false, WebDAVContent."Is Collection", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Is Collection"))); + Assert.AreEqual(1, WebDAVContent.Level, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Level))); + Assert.AreEqual(BaseUrl + '/logo.png', WebDAVContent."Full Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Full Url"))); + Assert.AreEqual('logo.png', WebDAVContent."Relative Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Relative Url"))); + Assert.AreEqual('2023-01-01T12:02:02Z', Format(WebDAVContent."Creation Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Creation Date"))); + Assert.AreEqual('2023-01-01T12:02:02Z', Format(WebDAVContent."Last Modified Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Last Modified Date"))); + end; + + [TEST] + procedure TestFilesAndCollectionCount() + var + WebDAVContent: Record "WebDAV Content"; + IsSuccess: Boolean; + begin + Initialize(); + + IsSuccess := WebDAVClient.GetFilesAndCollections(WebDAVContent, false); + Assert.AreEqual(true, IsSuccess, 'Successfull operation expected'); + + Assert.AreEqual(7, WebDAVContent.Count, 'Expected 7 records'); + WebDAVContent.FindFirst(); + WebDAVContent.Next(3); + + Assert.AreEqual('response.xml', WebDAVContent.Name, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Name))); + Assert.AreEqual(890, WebDAVContent."Content Length", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Length"))); + Assert.AreEqual('text/xml', WebDAVContent."Content Type", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Type"))); + + Assert.AreEqual(false, WebDAVContent."Is Collection", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Is Collection"))); + Assert.AreEqual(1, WebDAVContent.Level, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Level))); + Assert.AreEqual(BaseUrl + '/response.xml', WebDAVContent."Full Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Full Url"))); + Assert.AreEqual('response.xml', WebDAVContent."Relative Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Relative Url"))); + Assert.AreEqual('2023-01-01T12:03:03Z', Format(WebDAVContent."Creation Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Creation Date"))); + Assert.AreEqual('2023-01-01T12:03:03Z', Format(WebDAVContent."Last Modified Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Last Modified Date"))); + + WebDAVContent.Next(3); + Assert.AreEqual('Folder3', WebDAVContent.Name, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Name))); + Assert.AreEqual(0, WebDAVContent."Content Length", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Length"))); + Assert.AreEqual('', WebDAVContent."Content Type", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Type"))); + + Assert.AreEqual(true, WebDAVContent."Is Collection", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Is Collection"))); + Assert.AreEqual(1, WebDAVContent.Level, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Level))); + Assert.AreEqual(BaseUrl + '/Folder3', WebDAVContent."Full Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Full Url"))); + Assert.AreEqual('Folder3', WebDAVContent."Relative Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Relative Url"))); + Assert.AreEqual('2023-01-09T12:00:00Z', Format(WebDAVContent."Creation Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Creation Date"))); + Assert.AreEqual('2023-01-09T12:00:00Z', Format(WebDAVContent."Last Modified Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Last Modified Date"))); + end; + + [TEST] + procedure TestCollectionCountRecursive() + var + WebDAVContent: Record "WebDAV Content"; + IsSuccess: Boolean; + begin + Initialize(); + + IsSuccess := WebDAVClient.GetCollections(WebDAVContent, true); + Assert.AreEqual(true, IsSuccess, 'Successfull operation expected'); + Assert.AreEqual(10, WebDAVContent.Count, 'Expected 10 Records'); + + WebDAVContent.FindFirst(); + WebDAVContent.Next(2); + + Assert.AreEqual('SubFolder1', WebDAVContent.Name, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Name))); + Assert.AreEqual(0, WebDAVContent."Content Length", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Length"))); + Assert.AreEqual('', WebDAVContent."Content Type", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Type"))); + + Assert.AreEqual(true, WebDAVContent."Is Collection", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Is Collection"))); + Assert.AreEqual(2, WebDAVContent.Level, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Level))); + Assert.AreEqual(BaseUrl + '/Folder1/SubFolder1', WebDAVContent."Full Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Full Url"))); + Assert.AreEqual('Folder1/SubFolder1', WebDAVContent."Relative Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Relative Url"))); + Assert.AreEqual('2023-01-03T12:00:00Z', Format(WebDAVContent."Creation Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Creation Date"))); + Assert.AreEqual('2023-01-03T12:00:00Z', Format(WebDAVContent."Last Modified Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Last Modified Date"))); + end; + + [TEST] + procedure TestFileCountRecursive() + var + WebDAVContent: Record "WebDAV Content"; + IsSuccess: Boolean; + begin + Initialize(); + + IsSuccess := WebDAVClient.GetFiles(WebDAVContent, true); + Assert.AreEqual(true, IsSuccess, 'Successfull operation expected'); + + Assert.AreEqual(13, WebDAVContent.Count, 'Expected 13 records'); + WebDAVContent.FindFirst(); + WebDAVContent.Next(8); + + Assert.AreEqual('file1.pdf', WebDAVContent.Name, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Name))); + Assert.AreEqual(53950, WebDAVContent."Content Length", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Length"))); + Assert.AreEqual('application/pdf', WebDAVContent."Content Type", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Type"))); + + Assert.AreEqual(false, WebDAVContent."Is Collection", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Is Collection"))); + Assert.AreEqual(3, WebDAVContent.Level, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Level))); + Assert.AreEqual(BaseUrl + '/Folder1/Subfolder2/file1.pdf', WebDAVContent."Full Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Full Url"))); + Assert.AreEqual('Folder1/Subfolder2/file1.pdf', WebDAVContent."Relative Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Relative Url"))); + Assert.AreEqual('2023-01-04T23:59:59Z', Format(WebDAVContent."Creation Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Creation Date"))); + Assert.AreEqual('2023-01-04T23:59:59Z', Format(WebDAVContent."Last Modified Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Last Modified Date"))); + end; + + [TEST] + procedure TestFilesAndCollectionCountRecursive() + var + WebDAVContent: Record "WebDAV Content"; + IsSuccess: Boolean; + begin + Initialize(); + + IsSuccess := WebDAVClient.GetFilesAndCollections(WebDAVContent, true); + Assert.AreEqual(true, IsSuccess, 'Successfull operation expected'); + + Assert.AreEqual(23, WebDAVContent.Count, 'Expected 23 records'); + WebDAVContent.FindFirst(); + WebDAVContent.Next(17); + + Assert.AreEqual('SubSubFolder1', WebDAVContent.Name, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Name))); + Assert.AreEqual(0, WebDAVContent."Content Length", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Length"))); + Assert.AreEqual('', WebDAVContent."Content Type", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Type"))); + + Assert.AreEqual(true, WebDAVContent."Is Collection", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Is Collection"))); + Assert.AreEqual(3, WebDAVContent.Level, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Level))); + Assert.AreEqual(BaseUrl + '/Folder2/SubFolder1/SubSubFolder1', WebDAVContent."Full Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Full Url"))); + Assert.AreEqual('Folder2/SubFolder1/SubSubFolder1', WebDAVContent."Relative Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Relative Url"))); + Assert.AreEqual('2023-01-07T20:00:00Z', Format(WebDAVContent."Creation Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Creation Date"))); + Assert.AreEqual('2023-01-07T20:00:00Z', Format(WebDAVContent."Last Modified Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Last Modified Date"))); + + WebDAVContent.FindLast(); + WebDAVContent.Next(-2); + + Assert.AreEqual('file1.txt', WebDAVContent.Name, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Name))); + Assert.AreEqual(21, WebDAVContent."Content Length", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Length"))); + Assert.AreEqual('text/plain', WebDAVContent."Content Type", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Content Type"))); + + Assert.AreEqual(false, WebDAVContent."Is Collection", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Is Collection"))); + Assert.AreEqual(2, WebDAVContent.Level, StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption(Level))); + Assert.AreEqual(BaseUrl + '/Folder3/file1.txt', WebDAVContent."Full Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Full Url"))); + Assert.AreEqual('Folder3/file1.txt', WebDAVContent."Relative Url", StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Relative Url"))); + Assert.AreEqual('2023-01-09T13:13:13Z', Format(WebDAVContent."Creation Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Creation Date"))); + Assert.AreEqual('2023-12-31T23:59:59Z', Format(WebDAVContent."Last Modified Date", 0, 9), StrSubstNo(DiffValueLbl, WebDAVContent.FieldCaption("Last Modified Date"))); + end; + + [TEST] + procedure TestMakeCollection() + var + IsSuccess: Boolean; + begin + Initialize(); + IsSuccess := WebDAVClient.MakeCollection('SuccessFolder'); + Assert.AreEqual(true, IsSuccess, 'Successfull operation expected'); + end; + + + [TEST] + procedure TestPut() + var + IsSuccess: Boolean; + begin + Initialize(); + IsSuccess := WebDAVClient.Put('This is a test string'); + Assert.AreEqual(true, IsSuccess, 'Successfull operation expected'); + end; + + [TEST] + procedure TestGetFileContent() + var + ResponseText: Text; + IsSuccess: Boolean; + begin + Initialize(); + IsSuccess := WebDAVClient.GetFileContentAsText(ResponseText); + Assert.AreEqual(true, IsSuccess, 'Successfull operation expected'); + + Assert.AreEqual('This is a test string.', ResponseText, 'Different value expected.'); + end; + + [TEST] + procedure TestDelete() + var + IsSuccess: Boolean; + begin + Initialize(); + IsSuccess := WebDAVClient.Delete('Success.txt'); + Assert.AreEqual(true, IsSuccess, 'Successfull operation expected'); + end; + + + [TEST] + procedure TestCopy() + var + RequestHeaders: HttpHeaders; + RequestMessage: HttpRequestMessage; + Values: List of [Text]; + Destination: Text; + IsSuccess: Boolean; + begin + Initialize(); + Destination := BaseUrl + '/Destination/File.extension'; + IsSuccess := WebDAVClient.Copy(Destination); + Assert.AreEqual(true, IsSuccess, 'Successfull operation expected'); + + RequestMessage := WebDAVTestLibrary.GetRequestMessage(); + RequestMessage.GetHeaders(RequestHeaders); + Assert.AreEqual(true, RequestHeaders.Contains('Destination'), 'Destination Header expected.'); + + RequestHeaders.GetValues('Destination', Values); + Assert.AreEqual(Destination, Values.Get(1), 'Different Uri expected.'); + end; + + [TEST] + procedure TestMove() + var + RequestHeaders: HttpHeaders; + RequestMessage: HttpRequestMessage; + Values: List of [Text]; + Destination: Text; + IsSuccess: Boolean; + begin + Initialize(); + Destination := BaseUrl + '/Destination/File.extension'; + IsSuccess := WebDAVClient.Move(Destination); + Assert.AreEqual(true, IsSuccess, 'Successfull operation expected'); + + RequestMessage := WebDAVTestLibrary.GetRequestMessage(); + RequestMessage.GetHeaders(RequestHeaders); + Assert.AreEqual(true, RequestHeaders.Contains('Destination'), 'Destination Header expected.'); + + RequestHeaders.GetValues('Destination', Values); + Assert.AreEqual(Destination, Values.Get(1), 'Different Uri expected.'); + end; + + local procedure Initialize() + begin + if IsInitialized then + exit; + + BindSubscription(WebDAVTestLibrary); + BaseUrl := GenerateRandomUri(); + WebDAVClient.Initialize(BaseUrl, DummyWebDAVAuthorization); + IsInitialized := true; + end; + + local procedure GenerateRandomUri(): Text + begin + exit(StrSubstNo('http://%1.%2.org/%3', Any.AlphabeticText(20), Any.AlphabeticText(10), Any.AlphabeticText(10))); + end; + +} \ No newline at end of file diff --git a/Modules/System/WebDAV/src/Helper/WebDAVOperationResponse.Codeunit.al b/Modules/System/WebDAV/src/Helper/WebDAVOperationResponse.Codeunit.al index 3af2bb38a4..2ecddf49e3 100644 --- a/Modules/System/WebDAV/src/Helper/WebDAVOperationResponse.Codeunit.al +++ b/Modules/System/WebDAV/src/Helper/WebDAVOperationResponse.Codeunit.al @@ -9,19 +9,19 @@ codeunit 5684 "WebDAV Operation Response" [NonDebuggable] [TryFunction] - internal procedure GetResultAsText(var Result: Text); + internal procedure GetResponseAsText(var Response: Text); var - ResultInStream: InStream; + ResponseInStream: InStream; begin - TempBlobContent.CreateInStream(ResultInStream); - ResultInStream.Read(Result); + TempBlobContent.CreateInStream(ResponseInStream); + ResponseInStream.Read(Response); end; [NonDebuggable] [TryFunction] - internal procedure GetResultAsStream(var ResultInStream: InStream) + internal procedure GetResponseAsStream(var ResponseInStream: InStream) begin - TempBlobContent.CreateInStream(ResultInStream); + TempBlobContent.CreateInStream(ResponseInStream); end; [NonDebuggable] @@ -75,13 +75,13 @@ codeunit 5684 "WebDAV Operation Response" [NonDebuggable] local procedure GetErrorDescription(): Text var - Result: Text; + Response: Text; JObject: JsonObject; JToken: JsonToken; begin - GetResultAsText(Result); - if Result <> '' then - if JObject.ReadFrom(Result) then + GetResponseAsText(Response); + if Response <> '' then + if JObject.ReadFrom(Response) then if JObject.Get('error_description', JToken) then exit(JToken.AsValue().AsText()); end; diff --git a/Modules/System/WebDAV/src/Helper/WebDAVRequestHelper.Codeunit.al b/Modules/System/WebDAV/src/Helper/WebDAVRequestHelper.Codeunit.al index 747c2a5853..ef3e1c7d93 100644 --- a/Modules/System/WebDAV/src/Helper/WebDAVRequestHelper.Codeunit.al +++ b/Modules/System/WebDAV/src/Helper/WebDAVRequestHelper.Codeunit.al @@ -6,17 +6,15 @@ codeunit 5683 "WebDAV Request Helper" Authorization: Interface "WebDAV Authorization"; OperationNotSuccessfulErr: Label 'An error has occurred'; - procedure SetAuthorization(InitAuthorization: Interface "WebDAV Authorization") begin Authorization := InitAuthorization; end; - [NonDebuggable] - procedure MkCol(Uri: Text) WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; + procedure MkCol(Uri: Text; CollectionName: Text) WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; begin - WebDAVOperationResponse := SendRequest(PrepareRequestMsg('MKCOL', Uri)) + WebDAVOperationResponse := SendRequest(PrepareRequestMsg('MKCOL', NormalizeUri(Uri) + CollectionName)) end; [NonDebuggable] @@ -36,9 +34,9 @@ codeunit 5683 "WebDAV Request Helper" end; [NonDebuggable] - procedure Delete(Uri: Text) WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; + procedure Delete(Uri: Text; MemberName: Text) WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; begin - WebDAVOperationResponse := SendRequest(PrepareRequestMsg(Enum::"Http Request Type"::DELETE, Uri)) + WebDAVOperationResponse := SendRequest(PrepareRequestMsg(Enum::"Http Request Type"::DELETE, NormalizeUri(Uri) + MemberName)); end; [NonDebuggable] @@ -78,8 +76,9 @@ codeunit 5683 "WebDAV Request Helper" RequestMessage := PrepareRequestMsg('PROPFIND', Uri, WebDAVHttpContent); RequestMessage.GetHeaders(Headers); + // TODO Depth = 0? // Recursive - if Headers.Contains('Dephth') then + if Headers.Contains('Depth') then Headers.Remove('Depth'); if Recursive then Headers.Add('Depth', 'infinity') @@ -172,6 +171,15 @@ codeunit 5683 "WebDAV Request Helper" XMlDoc.Add(Propfind); end; + local procedure NormalizeUri(Uri: Text) NewUri: Text + begin + NewUri := Uri; + if not Uri.EndsWith('/') then + NewUri += '/'; + if NewUri = '/' then + NewUri := ''; + end; + [InternalEvent(false, true)] local procedure OnBeforeSendRequest(HttpRequestMessage: HttpRequestMessage; var WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; var IsHandled: Boolean; Method: Text) begin diff --git a/Modules/System/WebDAV/src/Model/WebDAVContent.Table.al b/Modules/System/WebDAV/src/Model/WebDAVContent.Table.al index 9c9f099b66..e072db8ad2 100644 --- a/Modules/System/WebDAV/src/Model/WebDAVContent.Table.al +++ b/Modules/System/WebDAV/src/Model/WebDAVContent.Table.al @@ -2,7 +2,7 @@ table 5678 "WebDAV Content" { Access = Public; DataClassification = SystemMetadata; // Data classification is SystemMetadata as the table is temporary - Caption = 'WebDAV Folder'; + Caption = 'WebDAV Content'; TableType = Temporary; Extensible = false; diff --git a/Modules/System/WebDAV/src/Model/WebDAVContentParser.Codeunit.al b/Modules/System/WebDAV/src/Model/WebDAVContentParser.Codeunit.al index c976226080..cb605600d3 100644 --- a/Modules/System/WebDAV/src/Model/WebDAVContentParser.Codeunit.al +++ b/Modules/System/WebDAV/src/Model/WebDAVContentParser.Codeunit.al @@ -30,6 +30,7 @@ codeunit 5682 "WebDAV Content Parser" [NonDebuggable] procedure ParseSingle(XmlNode: XmlNode; var WebDAVContent: Record "WebDAV Content") begin + WebDAVContent.Init(); WebDAVContent."Is Collection" := HasNode(XmlNode, 'dav:propstat/dav:prop/dav:resourcetype/dav:collection'); if OnlyCollections then @@ -39,23 +40,23 @@ codeunit 5682 "WebDAV Content Parser" if WebDAVContent."Is Collection" then exit; - WebDAVContent."Full Url" := GetValueAsText(XmlNode, 'dav:href'); + WebDAVContent."Full Url" := GetXmlNodePropertyInnerText(XmlNode, 'dav:href'); WebDAVContent."Relative Url" := GetRelativeUrl(WebDAVContent."Full Url"); WebDAVContent.Level := GetLevelFromPath(WebDAVContent."Relative Url"); - WebDAVContent."Name" := GetValueAsText(XmlNode, 'dav:propstat/dav:prop/dav:displayname'); - WebDAVContent."Content Type" := GetValueAsText(XmlNode, 'dav:propstat/dav:prop/dav:getcontenttype'); - if Evaluate(WebDAVContent."Content Length", GetValueAsText(XmlNode, 'dav:propstat/dav:prop/dav:getcontentlength')) then; + WebDAVContent."Name" := GetXmlNodePropertyInnerText(XmlNode, 'dav:propstat/dav:prop/dav:displayname'); + WebDAVContent."Content Type" := GetXmlNodePropertyInnerText(XmlNode, 'dav:propstat/dav:prop/dav:getcontenttype'); + if Evaluate(WebDAVContent."Content Length", GetXmlNodePropertyInnerText(XmlNode, 'dav:propstat/dav:prop/dav:getcontentlength')) then; - if Evaluate(WebDAVContent."Creation Date", GetValueAsText(XmlNode, 'dav:propstat/dav:prop/dav:creationdate')) then; - if Evaluate(WebDAVContent."Last Modified Date", GetValueAsText(XmlNode, 'dav:propstat/dav:prop/dav:getlastmodified')) then; + if Evaluate(WebDAVContent."Creation Date", GetXmlNodePropertyInnerText(XmlNode, 'dav:propstat/dav:prop/dav:creationdate')) then; + if Evaluate(WebDAVContent."Last Modified Date", GetXmlNodePropertyInnerText(XmlNode, 'dav:propstat/dav:prop/dav:getlastmodified')) then; WebDAVContent."Entry No." := GetNextEntryNo(); WebDAVContent.Insert(); end; [NonDebuggable] - procedure GetValueAsText(XmlNode: XmlNode; PropertyName: Text): Text + procedure GetXmlNodePropertyInnerText(XmlNode: XmlNode; PropertyName: Text): Text var ChildNode: XmlNode; XmlElement: XmlElement; diff --git a/Modules/System/WebDAV/src/WebDAVClient.Codeunit.al b/Modules/System/WebDAV/src/WebDAVClient.Codeunit.al index 1d224b71b9..5a019a825b 100644 --- a/Modules/System/WebDAV/src/WebDAVClient.Codeunit.al +++ b/Modules/System/WebDAV/src/WebDAVClient.Codeunit.al @@ -11,15 +11,15 @@ codeunit 5678 "WebDAV Client" end; // [NonDebuggable] - procedure MakeCollection(): Boolean + procedure MakeCollection(CollectionName: Text): Boolean begin - Exit(WebDAVClientImpl.MakeCollection()); + Exit(WebDAVClientImpl.MakeCollection(CollectionName)); end; // [NonDebuggable] - procedure Delete(): Boolean + procedure Delete(MemberName: Text): Boolean begin - Exit(WebDAVClientImpl.Delete()); + Exit(WebDAVClientImpl.Delete(MemberName)); end; // [NonDebuggable] @@ -53,9 +53,9 @@ codeunit 5678 "WebDAV Client" end; // [NonDebuggable] - procedure GetContent(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean + procedure GetFilesAndCollections(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean begin - Exit(WebDAVClientImpl.GetContent(WebDAVContent, Recursive)); + Exit(WebDAVClientImpl.GetFilesAndCollections(WebDAVContent, Recursive)); end; // [NonDebuggable] @@ -81,4 +81,26 @@ codeunit 5678 "WebDAV Client" begin Exit(WebDAVClientImpl.GetFileContentAsText(ResponseText)); end; + + /// + /// Returns detailed information on last API call. + /// + /// Codeunit holding http resonse status, reason phrase, headers and possible error information for tha last API call + procedure GetDiagnostics(): Interface "HTTP Diagnostics" + begin + exit(WebDAVClientImpl.GetDiagnostics()); + end; + + [TryFunction] + procedure GetResponseAsText(var Response: Text) + begin + WebDAVClientImpl.GetResponseAsText(Response); + end; + + [TryFunction] + internal procedure GetResponseAsStream(var ResponseInStream: InStream) + begin + WebDAVClientImpl.GetResponseAsStream(ResponseInStream); + end; + } \ No newline at end of file diff --git a/Modules/System/WebDAV/src/WebDAVClientImpl.Codeunit.al b/Modules/System/WebDAV/src/WebDAVClientImpl.Codeunit.al index 291a6d5639..2c48248134 100644 --- a/Modules/System/WebDAV/src/WebDAVClientImpl.Codeunit.al +++ b/Modules/System/WebDAV/src/WebDAVClientImpl.Codeunit.al @@ -19,29 +19,29 @@ codeunit 5679 "WebDAV Client Impl." end; [NonDebuggable] - procedure MakeCollection(): Boolean + procedure MakeCollection(CollectionName: Text): Boolean var WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; begin WebDAVRequestHelper.SetAuthorization(Authorization); - WebDAVOperationResponse := WebDAVRequestHelper.MkCol(Uri); + WebDAVOperationResponse := WebDAVRequestHelper.MkCol(Uri, CollectionName); if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then - Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); + Exit(false); Exit(true); end; [NonDebuggable] - procedure Delete(): Boolean + procedure Delete(MemberName: Text): Boolean var WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; begin WebDAVRequestHelper.SetAuthorization(Authorization); - WebDAVOperationResponse := WebDAVRequestHelper.Delete(Uri); + WebDAVOperationResponse := WebDAVRequestHelper.Delete(Uri, MemberName); if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then - Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); + Exit(false); Exit(true); end; @@ -74,7 +74,7 @@ codeunit 5679 "WebDAV Client Impl." WebDAVOperationResponse := WebDAVRequestHelper.Put(Uri, Content); if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then - Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); + Exit(false); Exit(true); end; @@ -88,7 +88,7 @@ codeunit 5679 "WebDAV Client Impl." WebDAVOperationResponse := WebDAVRequestHelper.Move(Uri, Destination); if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then - Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); + Exit(false); Exit(true); end; @@ -103,14 +103,14 @@ codeunit 5679 "WebDAV Client Impl." WebDAVOperationResponse := WebDAVRequestHelper.Copy(Uri, Destination); if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then - Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); + Exit(false); Exit(true); end; [NonDebuggable] - procedure GetContent(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean + procedure GetFilesAndCollections(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean var WebDAVContentParser: Codeunit "WebDAV Content Parser"; ResponseContent: Text; @@ -157,10 +157,11 @@ codeunit 5679 "WebDAV Client Impl." WebDAVRequestHelper.SetAuthorization(Authorization); WebDAVOperationResponse := WebDAVRequestHelper.Propfind(Uri, Recursive); + // TODO Success?? if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); - WebDAVOperationResponse.GetResultAsText(ResponseContent); + WebDAVOperationResponse.GetResponseAsText(ResponseContent); end; [NonDebuggable] @@ -172,11 +173,10 @@ codeunit 5679 "WebDAV Client Impl." WebDAVOperationResponse := WebDAVRequestHelper.Get(Uri); if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then - Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); + Exit(false); - WebDAVOperationResponse.GetResultAsStream(ResponseInStream); - - Exit(true); + if WebDAVOperationResponse.GetResponseAsStream(ResponseInStream) then + Exit(true); end; [NonDebuggable] @@ -189,4 +189,20 @@ codeunit 5679 "WebDAV Client Impl." Exit(true); end; + procedure GetDiagnostics(): Interface "HTTP Diagnostics" + begin + exit(WebDAVOperationResponse.GetDiagnostics()); + end; + + [TryFunction] + procedure GetResponseAsText(var Response: Text) + begin + WebDAVOperationResponse.GetResponseAsText(Response); + end; + + [TryFunction] + internal procedure GetResponseAsStream(var ResponseInStream: InStream) + begin + WebDAVOperationResponse.GetResponseAsStream(ResponseInStream); + end; } \ No newline at end of file From 2d96efa2179d67dd5f43baa4bf20bf986ba80470 Mon Sep 17 00:00:00 2001 From: Julian Tillmann Date: Mon, 13 Feb 2023 11:36:31 +0100 Subject: [PATCH 4/4] Adapted Suggestions by PeterConijn --- .../WebDAVAuthorization.Interface.al | 5 + .../WebDAVBasicAuthImpl.Codeunit.al | 5 + .../WebDAVBasicAuthorization.Codeunit.al | 13 ++- .../src/Helper/WebDAVDiagnostics.Codeunit.al | 6 - .../WebDAVOperationResponse.Codeunit.al | 24 ++-- .../Helper/WebDAVRequestHelper.Codeunit.al | 61 ++++++---- .../WebDAV/src/Model/WebDAVContent.Table.al | 11 +- .../src/Model/WebDAVContentParser.Codeunit.al | 13 ++- .../WebDAV/src/WebDAVClient.Codeunit.al | 108 +++++++++++++++--- .../WebDAV/src/WebDAVClientImpl.Codeunit.al | 72 +++++------- 10 files changed, 200 insertions(+), 118 deletions(-) diff --git a/Modules/System/WebDAV/src/Authorization/WebDAVAuthorization.Interface.al b/Modules/System/WebDAV/src/Authorization/WebDAVAuthorization.Interface.al index 932863f4e6..808283da77 100644 --- a/Modules/System/WebDAV/src/Authorization/WebDAVAuthorization.Interface.al +++ b/Modules/System/WebDAV/src/Authorization/WebDAVAuthorization.Interface.al @@ -1,3 +1,8 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + interface "WebDAV Authorization" { procedure Authorize(var HttpRequestMessage: HttpRequestMessage); diff --git a/Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthImpl.Codeunit.al b/Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthImpl.Codeunit.al index d1e600c22e..d459569e9f 100644 --- a/Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthImpl.Codeunit.al +++ b/Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthImpl.Codeunit.al @@ -1,3 +1,8 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + codeunit 5681 "WebDAV Basic Auth. Impl." implements "WebDAV Authorization" { Access = Internal; diff --git a/Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthorization.Codeunit.al b/Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthorization.Codeunit.al index 00be621438..63c02ab95a 100644 --- a/Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthorization.Codeunit.al +++ b/Modules/System/WebDAV/src/Authorization/WebDAVBasicAuthorization.Codeunit.al @@ -1,13 +1,24 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + codeunit 5680 "WebDAV Basic Authorization" { Access = Public; + /// + /// GetWebDAVBasicAuth. + /// + /// Text. + /// Text. + /// Return value of type Interface "WebDAV Authorization". procedure GetWebDAVBasicAuth(Username: Text; Password: Text): Interface "WebDAV Authorization" var WebDAVBasicAuthImpl: Codeunit "WebDAV Basic Auth. Impl."; begin WebDAVBasicAuthImpl.SetUserNameAndPassword(Username, Password); - Exit(WebDAVBasicAuthImpl); + exit(WebDAVBasicAuthImpl); end; } \ No newline at end of file diff --git a/Modules/System/WebDAV/src/Helper/WebDAVDiagnostics.Codeunit.al b/Modules/System/WebDAV/src/Helper/WebDAVDiagnostics.Codeunit.al index 929a7fe1b1..c5a879335a 100644 --- a/Modules/System/WebDAV/src/Helper/WebDAVDiagnostics.Codeunit.al +++ b/Modules/System/WebDAV/src/Helper/WebDAVDiagnostics.Codeunit.al @@ -19,7 +19,6 @@ codeunit 5685 "WebDAV Diagnostics" implements "HTTP Diagnostics" /// Gets reponse details. /// /// HttpResponseMessage.IsSuccessStatusCode - [NonDebuggable] procedure IsSuccessStatusCode(): Boolean begin exit(SuccessStatusCode); @@ -29,7 +28,6 @@ codeunit 5685 "WebDAV Diagnostics" implements "HTTP Diagnostics" /// Gets response details. /// /// HttpResponseMessage.StatusCode - [NonDebuggable] procedure GetHttpStatusCode(): Integer begin exit(HttpStatusCode); @@ -39,7 +37,6 @@ codeunit 5685 "WebDAV Diagnostics" implements "HTTP Diagnostics" /// Gets response details. /// /// Retry-after header value - [NonDebuggable] procedure GetHttpRetryAfter(): Integer begin exit(RetryAfter); @@ -49,7 +46,6 @@ codeunit 5685 "WebDAV Diagnostics" implements "HTTP Diagnostics" /// Gets reponse details /// /// Error message - [NonDebuggable] procedure GetErrorMessage(): Text begin exit(ErrorMessage); @@ -59,13 +55,11 @@ codeunit 5685 "WebDAV Diagnostics" implements "HTTP Diagnostics" /// Gets response details. /// /// HttpResponseMessage.ResponseReasonPhrase - [NonDebuggable] procedure GetResponseReasonPhrase(): Text begin exit(ResponseReasonPhrase); end; - [NonDebuggable] internal procedure SetParameters(NewIsSuccesss: Boolean; NewHttpStatusCode: Integer; NewResponseReasonPhrase: Text; NewRetryAfter: Integer; NewErrorMessage: Text) begin SuccessStatusCode := NewIsSuccesss; diff --git a/Modules/System/WebDAV/src/Helper/WebDAVOperationResponse.Codeunit.al b/Modules/System/WebDAV/src/Helper/WebDAVOperationResponse.Codeunit.al index 2ecddf49e3..cbda6a92c0 100644 --- a/Modules/System/WebDAV/src/Helper/WebDAVOperationResponse.Codeunit.al +++ b/Modules/System/WebDAV/src/Helper/WebDAVOperationResponse.Codeunit.al @@ -7,9 +7,13 @@ codeunit 5684 "WebDAV Operation Response" { Access = Internal; - [NonDebuggable] + var + TempBlobContent: Codeunit "Temp Blob"; + WebDAVDiagnostics: Codeunit "WebDAV Diagnostics"; + HttpHeaders: HttpHeaders; + [TryFunction] - internal procedure GetResponseAsText(var Response: Text); + internal procedure TryGetResponseAsText(var Response: Text); var ResponseInStream: InStream; begin @@ -17,14 +21,12 @@ codeunit 5684 "WebDAV Operation Response" ResponseInStream.Read(Response); end; - [NonDebuggable] [TryFunction] - internal procedure GetResponseAsStream(var ResponseInStream: InStream) + internal procedure TryGetResponseAsStream(var ResponseInStream: InStream) begin TempBlobContent.CreateInStream(ResponseInStream); end; - [NonDebuggable] internal procedure SetHttpResponse(HttpResponseMessage: HttpResponseMessage) var ContentOutStream: OutStream; @@ -39,7 +41,6 @@ codeunit 5684 "WebDAV Operation Response" WebDAVDiagnostics.SetParameters(HttpResponseMessage.IsSuccessStatusCode, HttpResponseMessage.HttpStatusCode, HttpResponseMessage.ReasonPhrase, GetRetryAfterHeaderValue(), GetErrorDescription()); end; - [NonDebuggable] internal procedure SetHttpResponse(ResponseContent: Text; ResponseHttpHeaders: HttpHeaders; ResponseHttpStatusCode: Integer; ResponseIsSuccessStatusCode: Boolean; ResponseReasonPhrase: Text) var ContentOutStream: OutStream; @@ -50,7 +51,6 @@ codeunit 5684 "WebDAV Operation Response" WebDAVDiagnostics.SetParameters(ResponseIsSuccessStatusCode, ResponseHttpStatusCode, ResponseReasonPhrase, GetRetryAfterHeaderValue(), GetErrorDescription()); end; - [NonDebuggable] internal procedure GetHeaderValueFromResponseHeaders(HeaderName: Text): Text var Values: array[100] of Text; @@ -60,7 +60,6 @@ codeunit 5684 "WebDAV Operation Response" exit(Values[1]); end; - [NonDebuggable] internal procedure GetRetryAfterHeaderValue() RetryAfter: Integer; var HeaderValue: Text; @@ -72,28 +71,21 @@ codeunit 5684 "WebDAV Operation Response" exit(0); end; - [NonDebuggable] local procedure GetErrorDescription(): Text var Response: Text; JObject: JsonObject; JToken: JsonToken; begin - GetResponseAsText(Response); + TryGetResponseAsText(Response); if Response <> '' then if JObject.ReadFrom(Response) then if JObject.Get('error_description', JToken) then exit(JToken.AsValue().AsText()); end; - [NonDebuggable] internal procedure GetDiagnostics(): Interface "HTTP Diagnostics" begin exit(WebDAVDiagnostics); end; - - var - TempBlobContent: Codeunit "Temp Blob"; - WebDAVDiagnostics: Codeunit "WebDAV Diagnostics"; - HttpHeaders: HttpHeaders; } diff --git a/Modules/System/WebDAV/src/Helper/WebDAVRequestHelper.Codeunit.al b/Modules/System/WebDAV/src/Helper/WebDAVRequestHelper.Codeunit.al index ef3e1c7d93..e42dffd85e 100644 --- a/Modules/System/WebDAV/src/Helper/WebDAVRequestHelper.Codeunit.al +++ b/Modules/System/WebDAV/src/Helper/WebDAVRequestHelper.Codeunit.al @@ -1,3 +1,7 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ codeunit 5683 "WebDAV Request Helper" { Access = Internal; @@ -78,19 +82,19 @@ codeunit 5683 "WebDAV Request Helper" // TODO Depth = 0? // Recursive - if Headers.Contains('Depth') then - Headers.Remove('Depth'); + if Headers.Contains(GetDepth()) then + Headers.Remove(GetDepth()); if Recursive then - Headers.Add('Depth', 'infinity') + Headers.Add(GetDepth(), 'infinity') else - Headers.Add('Depth', '1'); + Headers.Add(GetDepth(), '1'); WebDAVOperationResponse := SendRequest(RequestMessage); end; local procedure PrepareRequestMsg(HttpRequestType: Enum "Http Request Type"; Uri: Text): HttpRequestMessage begin - Exit(PrepareRequestMsg(Format(HttpRequestType), Uri)); + exit(PrepareRequestMsg(Format(HttpRequestType), Uri)); end; local procedure PrepareRequestMsg(HttpRequestType: Text; Uri: Text) RequestMessage: HttpRequestMessage @@ -101,7 +105,7 @@ codeunit 5683 "WebDAV Request Helper" local procedure PrepareRequestMsg(HttpRequestType: Enum "Http Request Type"; Uri: Text; WebDAVHttpContent: Codeunit "WebDAV Http Content") RequestMessage: HttpRequestMessage begin - Exit(PrepareRequestMsg(Format(HttpRequestType), Uri, WebDAVHttpContent)); + exit(PrepareRequestMsg(Format(HttpRequestType), Uri, WebDAVHttpContent)); end; local procedure PrepareRequestMsg(HttpRequestType: Text; Uri: Text; var WebDAVHttpContent: Codeunit "WebDAV Http Content") RequestMessage: HttpRequestMessage @@ -111,21 +115,21 @@ codeunit 5683 "WebDAV Request Helper" begin RequestMessage.Method(HttpRequestType); RequestMessage.SetRequestUri(Uri); - RequestMessage.GetHeaders(Headers); - if WebDAVHttpContent.GetContentLength() > 0 then begin - HttpContent := WebDAVHttpContent.GetContent(); - HttpContent.GetHeaders(Headers); + if WebDAVHttpContent.GetContentLength() = 0 then + exit; + + HttpContent := WebDAVHttpContent.GetContent(); + HttpContent.GetHeaders(Headers); - if Headers.Contains('Content-Type') then - Headers.Remove('Content-Type'); + if Headers.Contains(GetContentType) then + Headers.Remove(GetContentType); - if WebDAVHttpContent.GetContentType() <> '' then - Headers.Add('Content-Type', WebDAVHttpContent.GetContentType()); + if WebDAVHttpContent.GetContentType() <> '' then + Headers.Add(GetContentType, WebDAVHttpContent.GetContentType()); - RequestMessage.Content(HttpContent); - end; + RequestMessage.Content(HttpContent); end; local procedure SendRequest(HttpRequestMessage: HttpRequestMessage) OperationResponse: Codeunit "WebDAV Operation Response" @@ -135,15 +139,14 @@ codeunit 5683 "WebDAV Request Helper" IsHandled: Boolean; begin OnBeforeSendRequest(HttpRequestMessage, OperationResponse, IsHandled, HttpRequestMessage.Method()); + if IsHandled then + exit; - if not IsHandled then begin - Authorization.Authorize(HttpRequestMessage); - if not HttpClient.Send(HttpRequestMessage, HttpResponseMessage) then - Error(OperationNotSuccessfulErr); - - OperationResponse.SetHttpResponse(HttpResponseMessage); + Authorization.Authorize(HttpRequestMessage); + if not HttpClient.Send(HttpRequestMessage, HttpResponseMessage) then + Error(OperationNotSuccessfulErr); - end; + OperationResponse.SetHttpResponse(HttpResponseMessage); end; local procedure PreparePropfindRequest() XMLDoc: XmlDocument @@ -166,7 +169,6 @@ codeunit 5683 "WebDAV Request Helper" Prop.Add(XmlElement.Create('creationdate', 'DAV:')); Prop.Add(XmlElement.Create('getlastmodified', 'DAV:')); - Propfind.Add(Prop); XMlDoc.Add(Propfind); end; @@ -180,9 +182,18 @@ codeunit 5683 "WebDAV Request Helper" NewUri := ''; end; + local procedure GetContentType(): Text + begin + exit('Content-Type'); + end; + + local procedure GetDepth(): Text + begin + exit('Depth'); + end; + [InternalEvent(false, true)] local procedure OnBeforeSendRequest(HttpRequestMessage: HttpRequestMessage; var WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; var IsHandled: Boolean; Method: Text) begin end; - } \ No newline at end of file diff --git a/Modules/System/WebDAV/src/Model/WebDAVContent.Table.al b/Modules/System/WebDAV/src/Model/WebDAVContent.Table.al index e072db8ad2..554f510fb9 100644 --- a/Modules/System/WebDAV/src/Model/WebDAVContent.Table.al +++ b/Modules/System/WebDAV/src/Model/WebDAVContent.Table.al @@ -1,3 +1,8 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + table 5678 "WebDAV Content" { Access = Public; @@ -15,7 +20,7 @@ table 5678 "WebDAV Content" } field(10; Name; Text[250]) { - Caption = 'Title'; + Caption = 'Name'; } field(11; "Full Url"; Text[2048]) { @@ -52,10 +57,6 @@ table 5678 "WebDAV Content" } } - - - - keys { key(PK; "Entry No.") diff --git a/Modules/System/WebDAV/src/Model/WebDAVContentParser.Codeunit.al b/Modules/System/WebDAV/src/Model/WebDAVContentParser.Codeunit.al index cb605600d3..4afb8f4332 100644 --- a/Modules/System/WebDAV/src/Model/WebDAVContentParser.Codeunit.al +++ b/Modules/System/WebDAV/src/Model/WebDAVContentParser.Codeunit.al @@ -1,4 +1,7 @@ - +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ codeunit 5682 "WebDAV Content Parser" { @@ -63,7 +66,7 @@ codeunit 5682 "WebDAV Content Parser" begin if XmlNode.SelectSingleNode(PropertyName, XmlNamespaceManager, ChildNode) then begin XmlElement := ChildNode.AsXmlElement(); - Exit(XmlElement.InnerText()); + exit(XmlElement.InnerText()); end; end; @@ -73,18 +76,18 @@ codeunit 5682 "WebDAV Content Parser" ChildNode: XmlNode; XmlElement: XmlElement; begin - Exit(XmlNode.SelectSingleNode(PropertyName, XmlNamespaceManager, ChildNode)); + exit(XmlNode.SelectSingleNode(PropertyName, XmlNamespaceManager, ChildNode)); end; local procedure GetNextEntryNo(): Integer; begin NextEntryNo += 1; - Exit(NextEntryNo); + exit(NextEntryNo); end; local procedure GetLevelFromPath(Path: Text): Integer begin - Exit(Path.Split('/').Count); + exit(Path.Split('/').Count); end; local procedure GetRelativeUrl(FullUrl: Text) RelativeUrl: Text diff --git a/Modules/System/WebDAV/src/WebDAVClient.Codeunit.al b/Modules/System/WebDAV/src/WebDAVClient.Codeunit.al index 5a019a825b..58ddf5ac3e 100644 --- a/Modules/System/WebDAV/src/WebDAVClient.Codeunit.al +++ b/Modules/System/WebDAV/src/WebDAVClient.Codeunit.al @@ -1,3 +1,7 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ codeunit 5678 "WebDAV Client" { Access = Public; @@ -5,81 +9,143 @@ codeunit 5678 "WebDAV Client" var WebDAVClientImpl: Codeunit "WebDAV Client Impl."; + /// + /// Initialize. + /// + /// Text. + /// Interface "WebDAV Authorization". procedure Initialize(BaseUrl: Text; WebDAVAuthorization: Interface "WebDAV Authorization") begin WebDAVClientImpl.Initialize(BaseUrl, WebDAVAuthorization); end; + /// + /// MakeCollection. + /// + /// Text. + /// Return value of type Boolean. // [NonDebuggable] procedure MakeCollection(CollectionName: Text): Boolean begin - Exit(WebDAVClientImpl.MakeCollection(CollectionName)); + exit(WebDAVClientImpl.MakeCollection(CollectionName)); end; + /// + /// Delete. + /// + /// Text. + /// Return value of type Boolean. // [NonDebuggable] procedure Delete(MemberName: Text): Boolean begin - Exit(WebDAVClientImpl.Delete(MemberName)); + exit(WebDAVClientImpl.Delete(MemberName)); end; + /// + /// Move. + /// + /// Text. + /// Return value of type Boolean. // [NonDebuggable] procedure Move(Destination: Text): Boolean begin - Exit(WebDAVClientImpl.Move(Destination)); + exit(WebDAVClientImpl.Move(Destination)); end; + /// + /// Copy. + /// + /// Text. + /// Return value of type Boolean. // [NonDebuggable] procedure Copy(Destination: Text): Boolean begin - Exit(WebDAVClientImpl.Copy(Destination)); + exit(WebDAVClientImpl.Copy(Destination)); end; + /// + /// Put. + /// + /// Text. + /// Return value of type Boolean. // [NonDebuggable] procedure Put(Content: Text): Boolean begin - Exit(WebDAVClientImpl.Put(Content)); + exit(WebDAVClientImpl.Put(Content)); end; + /// + /// Put. + /// + /// InStream. + /// Return value of type Boolean. // [NonDebuggable] procedure Put(Content: InStream): Boolean begin - Exit(WebDAVClientImpl.Put(Content)); + exit(WebDAVClientImpl.Put(Content)); end; + /// + /// Put. + /// + /// HttpContent. + /// Return value of type Boolean. // [NonDebuggable] procedure Put(Content: HttpContent): Boolean begin - Exit(WebDAVClientImpl.Put(Content)); + exit(WebDAVClientImpl.Put(Content)); end; + /// + /// GetFilesAndCollections. + /// + /// VAR Record "WebDAV Content". + /// Boolean. + /// Return value of type Boolean. // [NonDebuggable] procedure GetFilesAndCollections(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean begin - Exit(WebDAVClientImpl.GetFilesAndCollections(WebDAVContent, Recursive)); + exit(WebDAVClientImpl.GetFilesAndCollections(WebDAVContent, Recursive)); end; + /// + /// GetCollections. + /// + /// VAR Record "WebDAV Content". + /// Boolean. + /// Return value of type Boolean. // [NonDebuggable] procedure GetCollections(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean begin - Exit(WebDAVClientImpl.GetCollections(WebDAVContent, Recursive)); + exit(WebDAVClientImpl.GetCollections(WebDAVContent, Recursive)); end; // [NonDebuggable] procedure GetFiles(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean begin - Exit(WebDAVClientImpl.GetFiles(WebDAVContent, Recursive)); + exit(WebDAVClientImpl.GetFiles(WebDAVContent, Recursive)); end; + /// + /// GetFileContent. + /// + /// VAR InStream. + /// Return value of type Boolean. [NonDebuggable] procedure GetFileContent(var ResponseInStream: InStream): Boolean begin - Exit(WebDAVClientImpl.GetFileContent(ResponseInStream)); + exit(WebDAVClientImpl.GetFileContent(ResponseInStream)); end; + /// + /// GetFileContentAsText. + /// + /// VAR Text. + /// Return value of type Boolean. [NonDebuggable] procedure GetFileContentAsText(var ResponseText: Text): Boolean begin - Exit(WebDAVClientImpl.GetFileContentAsText(ResponseText)); + exit(WebDAVClientImpl.GetFileContentAsText(ResponseText)); end; /// @@ -91,16 +157,26 @@ codeunit 5678 "WebDAV Client" exit(WebDAVClientImpl.GetDiagnostics()); end; + /// + /// TryGetResponseAsText. + /// + /// VAR Text. + /// False if an runtime error occurred. Otherwise true. [TryFunction] - procedure GetResponseAsText(var Response: Text) + procedure TryGetResponseAsText(var Response: Text) begin - WebDAVClientImpl.GetResponseAsText(Response); + WebDAVClientImpl.TryGetResponseAsText(Response); end; + /// + /// TryGetResponseAsStream. + /// + /// VAR InStream. + /// False if an runtime error occurred. Otherwise true. [TryFunction] - internal procedure GetResponseAsStream(var ResponseInStream: InStream) + internal procedure TryGetResponseAsStream(var ResponseInStream: InStream) begin - WebDAVClientImpl.GetResponseAsStream(ResponseInStream); + WebDAVClientImpl.TryGetResponseAsStream(ResponseInStream); end; } \ No newline at end of file diff --git a/Modules/System/WebDAV/src/WebDAVClientImpl.Codeunit.al b/Modules/System/WebDAV/src/WebDAVClientImpl.Codeunit.al index 2c48248134..423bd29fdf 100644 --- a/Modules/System/WebDAV/src/WebDAVClientImpl.Codeunit.al +++ b/Modules/System/WebDAV/src/WebDAVClientImpl.Codeunit.al @@ -1,24 +1,22 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ codeunit 5679 "WebDAV Client Impl." { Access = Internal; var - - [NonDebuggable] WebDAVOperationResponse: Codeunit "WebDAV Operation Response"; - [NonDebuggable] Authorization: Interface "WebDAV Authorization"; - [NonDebuggable] Uri: Text; - [NonDebuggable] procedure Initialize(InitUri: Text; InitAuthorization: Interface "WebDAV Authorization") begin Uri := InitUri; Authorization := InitAuthorization; end; - [NonDebuggable] procedure MakeCollection(CollectionName: Text): Boolean var WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; @@ -27,12 +25,11 @@ codeunit 5679 "WebDAV Client Impl." WebDAVOperationResponse := WebDAVRequestHelper.MkCol(Uri, CollectionName); if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then - Exit(false); + exit(false); - Exit(true); + exit(true); end; - [NonDebuggable] procedure Delete(MemberName: Text): Boolean var WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; @@ -41,31 +38,27 @@ codeunit 5679 "WebDAV Client Impl." WebDAVOperationResponse := WebDAVRequestHelper.Delete(Uri, MemberName); if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then - Exit(false); + exit(false); - Exit(true); + exit(true); end; - - [NonDebuggable] procedure Put(Content: InStream): Boolean var HttpContent: HttpContent; begin HttpContent.WriteFrom(Content); - Exit(Put(HttpContent)); + exit(Put(HttpContent)); end; - [NonDebuggable] procedure Put(Content: Text): Boolean var HttpContent: HttpContent; begin HttpContent.WriteFrom(Content); - Exit(Put(HttpContent)); + exit(Put(HttpContent)); end; - [NonDebuggable] procedure Put(Content: HttpContent): Boolean var WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; @@ -74,12 +67,11 @@ codeunit 5679 "WebDAV Client Impl." WebDAVOperationResponse := WebDAVRequestHelper.Put(Uri, Content); if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then - Exit(false); + exit(false); - Exit(true); + exit(true); end; - [NonDebuggable] procedure Move(Destination: Text): Boolean var WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; @@ -88,13 +80,11 @@ codeunit 5679 "WebDAV Client Impl." WebDAVOperationResponse := WebDAVRequestHelper.Move(Uri, Destination); if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then - Exit(false); + exit(false); - Exit(true); + exit(true); end; - - [NonDebuggable] procedure Copy(Destination: Text): Boolean var WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; @@ -103,13 +93,11 @@ codeunit 5679 "WebDAV Client Impl." WebDAVOperationResponse := WebDAVRequestHelper.Copy(Uri, Destination); if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then - Exit(false); + exit(false); - Exit(true); + exit(true); end; - - [NonDebuggable] procedure GetFilesAndCollections(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean var WebDAVContentParser: Codeunit "WebDAV Content Parser"; @@ -120,10 +108,9 @@ codeunit 5679 "WebDAV Client Impl." WebDAVContentParser.Initialize(Uri, false, false); WebDAVContentParser.Parse(ResponseContent, WebDAVContent); - Exit(true); + exit(true); end; - [NonDebuggable] procedure GetCollections(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean var WebDAVContentParser: Codeunit "WebDAV Content Parser"; @@ -133,10 +120,9 @@ codeunit 5679 "WebDAV Client Impl." WebDAVContentParser.Initialize(Uri, false, true); WebDAVContentParser.Parse(ResponseContent, WebDAVContent); - Exit(true); + exit(true); end; - [NonDebuggable] procedure GetFiles(var WebDAVContent: Record "WebDAV Content"; Recursive: Boolean): Boolean var WebDAVContentParser: Codeunit "WebDAV Content Parser"; @@ -147,7 +133,7 @@ codeunit 5679 "WebDAV Client Impl." WebDAVContentParser.Initialize(Uri, true, false); WebDAVContentParser.Parse(ResponseContent, WebDAVContent); - Exit(true); + exit(true); end; local procedure GetPropfindResponse(Recursive: Boolean) ResponseContent: Text; @@ -161,10 +147,9 @@ codeunit 5679 "WebDAV Client Impl." if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then Error('%1: %2', WebDAVOperationResponse.GetDiagnostics().GetHttpStatusCode(), WebDAVOperationResponse.GetDiagnostics().GetResponseReasonPhrase()); - WebDAVOperationResponse.GetResponseAsText(ResponseContent); + WebDAVOperationResponse.TryGetResponseAsText(ResponseContent); end; - [NonDebuggable] procedure GetFileContent(var ResponseInStream: InStream): Boolean var WebDAVRequestHelper: Codeunit "WebDAV Request Helper"; @@ -173,20 +158,19 @@ codeunit 5679 "WebDAV Client Impl." WebDAVOperationResponse := WebDAVRequestHelper.Get(Uri); if not WebDAVOperationResponse.GetDiagnostics().IsSuccessStatusCode() then - Exit(false); + exit(false); - if WebDAVOperationResponse.GetResponseAsStream(ResponseInStream) then - Exit(true); + if WebDAVOperationResponse.TryGetResponseAsStream(ResponseInStream) then + exit(true); end; - [NonDebuggable] procedure GetFileContentAsText(var ResponseText: Text): Boolean var ResponseInStream: InStream; begin GetFileContent(ResponseInStream); ResponseInStream.Read(ResponseText); - Exit(true); + exit(true); end; procedure GetDiagnostics(): Interface "HTTP Diagnostics" @@ -195,14 +179,14 @@ codeunit 5679 "WebDAV Client Impl." end; [TryFunction] - procedure GetResponseAsText(var Response: Text) + procedure TryGetResponseAsText(var Response: Text) begin - WebDAVOperationResponse.GetResponseAsText(Response); + WebDAVOperationResponse.TryGetResponseAsText(Response); end; [TryFunction] - internal procedure GetResponseAsStream(var ResponseInStream: InStream) + internal procedure TryGetResponseAsStream(var ResponseInStream: InStream) begin - WebDAVOperationResponse.GetResponseAsStream(ResponseInStream); + WebDAVOperationResponse.TryGetResponseAsStream(ResponseInStream); end; } \ No newline at end of file