Skip to content

Add nullable header / query / params for HTTP #326

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

Merged
merged 3 commits into from
Sep 16, 2020
Merged
Show file tree
Hide file tree
Changes from all 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 azure-functions-language-worker-protobuf/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Azure Functions Languge Worker Protobuf
# Azure Functions Language Worker Protobuf

This repository contains the protobuf definition file which defines the gRPC service which is used between the [Azure Functions Host](https://github.com/Azure/azure-functions-host) and the Azure Functions language workers. This repo is shared across many repos in many languages (for each worker) by using git commands.

Expand Down Expand Up @@ -39,7 +39,7 @@ From within the Azure Functions language worker repo:
## Releasing a Language Worker Protobuf version

1. Draft a release in the GitHub UI
- Be sure to inculde details of the release
- Be sure to include details of the release
2. Create a release version, following semantic versioning guidelines ([semver.org](https://semver.org/))
3. Tag the version with the pattern: `v<M>.<m>.<p>-protofile` (example: `v1.1.0-protofile`)
3. Merge `dev` to `master`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ message WorkerInitRequest {
// inform worker of supported categories and their levels
// i.e. Worker = Verbose, Function.MyFunc = None
map<string, RpcLog.Level> log_categories = 3;

// Full path of worker.config.json location
string worker_directory = 4;
}

// Worker responds with the result of initializing itself
Expand Down Expand Up @@ -481,4 +484,7 @@ message RpcHttp {
TypedData rawBody = 17;
repeated RpcClaimsIdentity identities = 18;
repeated RpcHttpCookie cookies = 19;
map<string,NullableString> nullable_headers = 20;
map<string,NullableString> nullable_params = 21;
map<string,NullableString> nullable_query = 22;
}
3 changes: 2 additions & 1 deletion src/WorkerChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ export class WorkerChannel implements IWorkerChannel {
RpcHttpTriggerMetadataRemoved: "true",
RpcHttpBodyOnly: "true",
IgnoreEmptyValuedRpcHttpHeaders: "true",
WorkerStatus: "true"
WorkerStatus: "true",
UseNullableValueDictionaryForHttp: "true"
};
this._eventStream.write({
requestId: requestId,
Expand Down
23 changes: 19 additions & 4 deletions src/converters/RpcHttpConverters.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { AzureFunctionsRpcMessages as rpc } from '../../azure-functions-language-worker-protobuf/src/rpc';
import {
AzureFunctionsRpcMessages as rpc,
INullableString
} from '../../azure-functions-language-worker-protobuf/src/rpc';
import { HttpMethod, Cookie } from '../public/Interfaces';
import { RequestProperties } from '../http/Request';
import { Dict } from '../Context';
Expand All @@ -21,9 +24,9 @@ export function fromRpcHttp(rpcHttp: rpc.IRpcHttp): RequestProperties {
method: <HttpMethod>rpcHttp.method,
url: <string>rpcHttp.url,
originalUrl: <string>rpcHttp.url,
headers: <Dict<string>>rpcHttp.headers,
query: <Dict<string>>rpcHttp.query,
params: <Dict<string>>rpcHttp.params,
headers: fromNullableMapping(rpcHttp.nullableHeaders, rpcHttp.headers),
query: fromNullableMapping(rpcHttp.nullableQuery, rpcHttp.query),
params: fromNullableMapping(rpcHttp.nullableParams, rpcHttp.params),
body: fromTypedData(<rpc.ITypedData>rpcHttp.body),
rawBody: fromRpcHttpBody(<rpc.ITypedData>rpcHttp.body),
};
Expand All @@ -46,6 +49,18 @@ function fromRpcHttpBody(body: rpc.ITypedData) {
}
}

function fromNullableMapping(nullableMapping: { [k: string]: INullableString } | null | undefined, originalMapping?: { [k: string]: string } | null): Dict<string> {
let converted = {};
if (nullableMapping && Object.keys(nullableMapping).length > 0) {
for (const key in nullableMapping) {
converted[key] = nullableMapping[key].value || "";
}
} else if (originalMapping && Object.keys(originalMapping).length > 0) {
converted = <Dict<string>>originalMapping;
}
return converted;
}

/**
* Converts the HTTP 'Response' object to an 'ITypedData' 'http' type to be sent through the RPC layer.
* 'http' types are a special case from other 'ITypedData' types, which come from primitive types.
Expand Down
3 changes: 2 additions & 1 deletion test/WorkerChannelTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ describe('WorkerChannel', () => {
'RpcHttpBodyOnly': "true",
'RpcHttpTriggerMetadataRemoved': "true",
'IgnoreEmptyValuedRpcHttpHeaders': "true",
'WorkerStatus': "true"
'WorkerStatus': "true",
'UseNullableValueDictionaryForHttp': "true"
},
result: {
status: rpc.StatusResult.Status.Success
Expand Down