Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Rest Client] Support for Cookies + Fix secret headers + Collectible errors #2474

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/System Application/App/Rest Client/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@
"idRanges": [
{
"from": 2350,
"to": 2361
"to": 2362
}
],
"target": "OnPrem",
"runtime": "12.0",
"runtime": "14.0",
ajkauffmann marked this conversation as resolved.
Show resolved Hide resolved
"resourceExposurePolicy": {
"allowDebugging": true,
"allowDownloadingSource": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace System.RestClient;

codeunit 2361 "HttpAuthOAuthClientCredentials" implements "Http Authentication"
{
Access = Public;
InherentEntitlements = X;
InherentPermissions = X;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace System.RestClient;
/// <summary>Implementation of the "Http Authentication" interface for a anonymous request.</summary>
codeunit 2358 "Http Authentication Anonymous" implements "Http Authentication"
{
Access = Public;
InherentEntitlements = X;
InherentPermissions = X;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ using System;

codeunit 2359 "Http Authentication Basic" implements "Http Authentication"
{
Access = Public;
InherentEntitlements = X;
InherentPermissions = X;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace System.RestClient;

/// <summary>
/// This enum contains the exceptions of the Rest Client.
/// </summary>
enum 2351 "Rest Client Exception"
{
value(100; UnknownException)
{
Caption = 'Unknown Exception';
}
value(101; ConnectionFailed)
{
Caption = 'Connection Failed';
}
value(102; BlockedByEnvironment)
{
Caption = 'Blocked By Environment';
}
value(103; RequestFailed)
{
Caption = 'Request Failed';
}
value(201; InvalidJson)
{
Caption = 'Invalid Json';
}
value(202; InvalidXml)
{
Caption = 'Invalid Xml';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace System.RestClient;

codeunit 2362 "Rest Client Exception Builder"
{
ajkauffmann marked this conversation as resolved.
Show resolved Hide resolved
Access = Public;
InherentEntitlements = X;
InherentPermissions = X;

procedure CreateException(RestClientException: Enum "Rest Client Exception"; ErrorMessage: Text) Exception: ErrorInfo
begin
Exception := CreateException(RestClientException, ErrorMessage, IsCollectingErrors());
end;

procedure CreateException(RestClientException: Enum "Rest Client Exception"; ErrorMessage: Text; Collectible: Boolean) Exception: ErrorInfo
begin
Exception.Message := ErrorMessage;
Exception.CustomDimensions.Add('ExceptionCode', Format(RestClientException.AsInteger()));
Exception.CustomDimensions.Add('ExceptionName', RestClientException.Names.Get(RestClientException.Ordinals.IndexOf(RestClientException.AsInteger())));
Exception.Collectible := Collectible;
end;

procedure GetRestClientException(ErrInfo: ErrorInfo) RestClientException: Enum "Rest Client Exception"
var
ExceptionCode: Integer;
begin
Evaluate(ExceptionCode, ErrInfo.CustomDimensions.Get('ExceptionCode'));
RestClientException := Enum::"Rest Client Exception".FromInteger(ExceptionCode);
end;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace System.RestClient;

codeunit 2360 "Http Client Handler" implements "Http Client Handler"
{
Access = Public;
InherentEntitlements = X;
InherentPermissions = X;

Expand All @@ -14,6 +15,6 @@ codeunit 2360 "Http Client Handler" implements "Http Client Handler"
ResponseMessage: HttpResponseMessage;
begin
Success := HttpClient.Send(HttpRequestMessage.GetHttpRequestMessage(), ResponseMessage);
HttpResponseMessage.SetResponseMessage(ResponseMessage);
HttpResponseMessage := HttpResponseMessage.Create(ResponseMessage);
end;
}
133 changes: 52 additions & 81 deletions src/System Application/App/Rest Client/src/HttpContent.Codeunit.al
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ using System.Utilities;
/// <summary>Holder object for the Http Content data.</summary>
codeunit 2354 "Http Content"
{
Access = Public;
InherentEntitlements = X;
InherentPermissions = X;

Expand All @@ -20,130 +21,134 @@ codeunit 2354 "Http Content"
/// <param name="Content">The content to send to the server.</param>
/// <returns>The Http Content object.</returns>
/// <remarks>The Content-Type header will be set to 'text/plain'.</remarks>
procedure Create(Content: Text) HttpContent: Codeunit "Http Content"
procedure Create(Content: Text): Codeunit "Http Content"
begin
HttpContent := Create(Content, '');
HttpContentImpl := HttpContentImpl.Create(Content);
exit(this);
end;

/// <summary>Initializes a new instance of the Http Content class with the specified SecretText content.</summary>
/// <param name="Content">The content to send to the server.</param>
/// <returns>The Http Content object.</returns>
/// <remarks>The Content-Type header will be set to 'text/plain'.</remarks>
procedure Create(Content: SecretText) HttpContent: Codeunit "Http Content"
procedure Create(Content: SecretText): Codeunit "Http Content"
begin
HttpContent := Create(Content, '');
HttpContentImpl := HttpContentImpl.Create(Content);
exit(this);
end;

/// <summary>Initializes a new instance of the Http Content class with the specified Text content and content type.</summary>
/// <param name="Content">The content to send to the server.</param>
/// <param name="ContentType">The content type of the content to send to the server.</param>
/// <returns>The Http Content object.</returns>
/// <remarks>If the ContentType parameter is not specified, it will be set to 'text/plain'.</remarks>
procedure Create(Content: Text; ContentType: Text) HttpContent: Codeunit "Http Content"
procedure Create(Content: Text; ContentType: Text): Codeunit "Http Content"
begin
SetContent(Content, ContentType);
HttpContent.SetHttpContentImpl(HttpContentImpl);
HttpContentImpl := HttpContentImpl.Create(Content, ContentType);
exit(this);
end;

/// <summary>Initializes a new instance of the Http Content class with the specified SecretText content and content type.</summary>
/// <param name="Content">The content to send to the server.</param>
/// <param name="ContentType">The content type of the content to send to the server.</param>
/// <returns>The Http Content object.</returns>
/// <remarks>If the ContentType parameter is not specified, it will be set to 'text/plain'.</remarks>
procedure Create(Content: SecretText; ContentType: Text) HttpContent: Codeunit "Http Content"
procedure Create(Content: SecretText; ContentType: Text): Codeunit "Http Content"
begin
SetContent(Content, ContentType);
HttpContent.SetHttpContentImpl(HttpContentImpl);
HttpContentImpl := HttpContentImpl.Create(Content, ContentType);
exit(this);
end;

/// <summary>Initializes a new instance of the Http Content class with the specified JsonObject content.</summary>
/// <param name="Content">The content to send to the server.</param>
/// <returns>The Http Content object.</returns>
/// <remarks>The Content-Type header will be set to 'application/json'.</remarks>
procedure Create(Content: JsonObject) HttpContent: Codeunit "Http Content"
procedure Create(Content: JsonObject): Codeunit "Http Content"
begin
SetContent(Content);
HttpContent.SetHttpContentImpl(HttpContentImpl);
HttpContentImpl := HttpContentImpl.Create(Content);
exit(this);
end;

/// <summary>Initializes a new instance of the Http Content class with the specified JsonArray content.</summary>
/// <param name="Content">The content to send to the server.</param>
/// <returns>The Http Content object.</returns>
/// <remarks>The Content-Type header will be set to 'application/json'.</remarks>
procedure Create(Content: JsonArray) HttpContent: Codeunit "Http Content"
procedure Create(Content: JsonArray): Codeunit "Http Content"
begin
SetContent(Content);
HttpContent.SetHttpContentImpl(HttpContentImpl);
HttpContentImpl := HttpContentImpl.Create(Content);
exit(this);
end;

/// <summary>Initializes a new instance of the Http Content class with the specified JsonToken content.</summary>
/// <param name="Content">The content to send to the server.</param>
/// <returns>The Http Content object.</returns>
/// <remarks>The Content-Type header will be set to 'application/json'.</remarks>
procedure Create(Content: JsonToken) HttpContent: Codeunit "Http Content"
procedure Create(Content: JsonToken): Codeunit "Http Content"
begin
SetContent(Content);
HttpContent.SetHttpContentImpl(HttpContentImpl);
HttpContentImpl := HttpContentImpl.Create(Content);
exit(this);
end;

/// <summary>Initializes a new instance of the Http Content class with the specified XmlDocument content.</summary>
/// <param name="Content">The content to send to the server.</param>
/// <returns>The Http Content object.</returns>
/// <remarks>The Content-Type header will be set to 'text/xml'.</remarks>
procedure Create(Content: XmlDocument) HttpContent: Codeunit "Http Content"
procedure Create(Content: XmlDocument): Codeunit "Http Content"
begin
SetContent(Content);
HttpContent.SetHttpContentImpl(HttpContentImpl);
HttpContentImpl := HttpContentImpl.Create(Content);
exit(this);
end;

/// <summary>Initializes a new instance of the Http Content class with the specified "Temp Blob" Codeunit content.</summary>
/// <param name="Content">The content to send to the server.</param>
/// <returns>The Http Content object.</returns>
/// <remarks>The Content-Type header will be set to 'application/octet-stream'.</remarks>
procedure Create(Content: Codeunit "Temp Blob") HttpContent: Codeunit "Http Content"
procedure Create(Content: Codeunit "Temp Blob"): Codeunit "Http Content"
begin
HttpContent := Create(Content, '');
HttpContentImpl := HttpContentImpl.Create(Content);
exit(this);
end;

/// <summary>Initializes a new instance of the Http Content class with the specified "Temp Blob" Codeunit content and content type.</summary>
/// <param name="Content">The content to send to the server.</param>
/// <param name="ContentType">The content type of the content to send to the server.</param>
/// <returns>The Http Content object.</returns>
/// <remarks>If the ContentType parameter is not specified, it will be set to 'application/octet-stream'.</remarks>
procedure Create(Content: Codeunit "Temp Blob"; ContentType: Text) HttpContent: Codeunit "Http Content"
procedure Create(Content: Codeunit "Temp Blob"; ContentType: Text): Codeunit "Http Content"
begin
SetContent(Content, ContentType);
HttpContent.SetHttpContentImpl(HttpContentImpl);
HttpContentImpl := HttpContentImpl.Create(Content, ContentType);
exit(this);
end;

/// <summary>Initializes a new instance of the Http Content class with the specified InStream content.</summary>
/// <param name="Content">The content to send to the server.</param>
/// <returns>The Http Content object.</returns>
/// <remarks>The Content-Type header will be set to 'application/octet-stream'.</remarks>
procedure Create(Content: InStream) HttpContent: Codeunit "Http Content"
procedure Create(Content: InStream): Codeunit "Http Content"
begin
HttpContent := Create(Content, '');
HttpContentImpl := HttpContentImpl.Create(Content);
exit(this);
end;

/// <summary>Initializes a new instance of the Http Content class with the specified InStream content and content type.</summary>
/// <param name="Content">The content to send to the server.</param>
/// <param name="ContentType">The content type of the content to send to the server.</param>
/// <returns>The Http Content object.</returns>
/// <remarks>If the ContentType parameter is not specified, it will be set to 'application/octet-stream'.</remarks>
procedure Create(Content: InStream; ContentType: Text) HttpContent: Codeunit "Http Content"
procedure Create(Content: InStream; ContentType: Text): Codeunit "Http Content"
begin
SetContent(Content, ContentType);
HttpContent.SetHttpContentImpl(HttpContentImpl);
HttpContentImpl := HttpContentImpl.Create(Content, ContentType);
exit(this);
end;

/// <summary>Initializes a new instance of the Http Content object with the specified HttpContent object.</summary>
/// <param name="Content">The HttpContent object.</param>
/// <returns>The HttpContent object.</returns>
/// <remarks>The HttpContent must be properly prepared including the Content-Type header.</remarks>
procedure Create(Content: HttpContent) HttpContent: Codeunit "Http Content"
procedure Create(Content: HttpContent): Codeunit "Http Content"
begin
SetContent(Content);
HttpContent.SetHttpContentImpl(HttpContentImpl);
HttpContentImpl := HttpContentImpl.Create(Content);
exit(this);
end;
#endregion

Expand Down Expand Up @@ -232,57 +237,23 @@ codeunit 2354 "Http Content"
begin
JsonToken := HttpContentImpl.AsJson();
end;
#endregion

#region Internal Methods
internal procedure SetContent(Content: Text; ContentType: Text)
begin
HttpContentImpl.SetContent(Content, ContentType);
end;

internal procedure SetContent(Content: SecretText; ContentType: Text)
begin
HttpContentImpl.SetContent(Content, ContentType);
end;

internal procedure SetContent(Content: InStream; ContentType: Text)
begin
HttpContentImpl.SetContent(Content, ContentType);
end;

internal procedure SetContent(TempBlob: Codeunit "Temp Blob"; ContentType: Text)
begin
HttpContentImpl.SetContent(TempBlob, ContentType);
end;

internal procedure SetContent(Content: XmlDocument)
begin
HttpContentImpl.SetContent(Content);
end;

internal procedure SetContent(Content: JsonObject)
begin
SetContent(Content.AsToken());
end;

internal procedure SetContent(Content: JsonArray)
begin
SetContent(Content.AsToken());
end;

internal procedure SetContent(Content: JsonToken)
begin
HttpContentImpl.SetContent(Content);
end;

internal procedure SetContent(var Value: HttpContent)
/// <summary>Gets the content of the HTTP response message as a JsonObject.</summary>
/// <returns>The content of the HTTP response message as a JsonObject.</returns>
/// <remarks>Returns an empty JsonObject in case there is no content.
/// Fails in case the content is not a valid JSON document.</remarks>
procedure AsJsonObject() JsonObject: JsonObject
begin
HttpContentImpl.SetContent(Value);
JsonObject := HttpContentImpl.AsJsonObject();
end;

internal procedure SetHttpContentImpl(Value: Codeunit "Http Content Impl.")
/// <summary>Gets the content of the HTTP response message as a JsonArray.</summary>
/// <returns>The content of the HTTP response message as a JsonArray.</returns>
/// <remarks>Returns an empty JsonArray in case there is no content.
/// Fails in case the content is not a valid JSON document.</remarks>
procedure AsJsonArray() JsonArray: JsonArray
begin
HttpContentImpl := Value;
JsonArray := HttpContentImpl.AsJsonArray();
end;
#endregion
}
Loading
Loading