diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1acc7bb2d..da9c09502 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -19,7 +19,6 @@ /motoko/encrypted-notes-dapp-vetkd/ @dfinity/crypto-team /motoko/encrypted-notes-dapp/ @dfinity/crypto-team /motoko/hello_cycles/ @dfinity/languages -/motoko/http_counter/ @dfinity/networking /motoko/ic-pos/ @dfinity/div-Crypto /motoko/icrc2-swap/ @dfinity/div-Crypto /motoko/internet_identity_integration/ @dfinity/gix diff --git a/.github/workflows/motoko-http_counter-example.yaml b/.github/workflows/motoko-http_counter-example.yaml deleted file mode 100644 index 4f363d5fc..000000000 --- a/.github/workflows/motoko-http_counter-example.yaml +++ /dev/null @@ -1,40 +0,0 @@ -name: motoko-http_counter -on: - push: - branches: - - master - pull_request: - paths: - - motoko/http_counter/** - - .github/workflows/provision-darwin.sh - - .github/workflows/provision-linux.sh - - .github/workflows/motoko-http_counter-example.yaml - - .ic-commit -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true -jobs: - motoko-http_counter-darwin: - runs-on: macos-12 - steps: - - uses: actions/checkout@v1 - - name: Provision Darwin - run: bash .github/workflows/provision-darwin.sh - - name: Motoko Http Counter Darwin - run: | - dfx start --background - pushd motoko/http_counter - make test - popd - motoko-http_counter-linux: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v1 - - name: Provision Linux - run: bash .github/workflows/provision-linux.sh - - name: Motoko Http Counter Linux - run: | - dfx start --background - pushd motoko/http_counter - make test - popd diff --git a/motoko/http_counter/Makefile b/motoko/http_counter/Makefile deleted file mode 100644 index 985862cc6..000000000 --- a/motoko/http_counter/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -.PHONY: all -all: build - -.PHONY: build -.SILENT: build -build: - dfx canister create http_counter - dfx build - -.PHONY: install -.SILENT: install -install: build - dfx canister install http_counter --mode reinstall --yes - -.PHONY: upgrade -.SILENT: upgrade -upgrade: build - dfx canister install http_counter --mode=upgrade - -.PHONY: test -.SILENT: test -test: install - sh -c 'export CANISTER_ID=$$(dfx canister id http_counter); \ - export WEBSERVER_PORT=$$(dfx info webserver-port); \ - (curl -s "$$CANISTER_ID.localhost:$$WEBSERVER_PORT/" --resolve "$$CANISTER_ID.localhost:$$WEBSERVER_PORT:127.0.0.1" | grep "Counter is 0") && \ - (curl -s --compressed "$$CANISTER_ID.localhost:$$WEBSERVER_PORT/" --resolve "$$CANISTER_ID.localhost:$$WEBSERVER_PORT:127.0.0.1" | grep "query") && echo "PASS"' - -.PHONY: clean -.SILENT: clean -clean: - rm -fr .dfx diff --git a/motoko/http_counter/README.md b/motoko/http_counter/README.md deleted file mode 100644 index 8e3d77626..000000000 --- a/motoko/http_counter/README.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -keywords: [beginner, motoko, http, http counter, counter] ---- - -# HTTP counter - -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/http_counter) - -## Overview - -The example demonstrates a counter dapp and an HTTP interface. It is essentially an iteration on the counter canister which adds native HTTP interfaces. - -This sample dapp provides an interface that exposes the following methods: - -* `http_request`, which can: - * `GET` some static `gzip`ed data if `gzip` is accepted. - * `GET` the counter otherwise. - * Refer `POST`s to call `http_request_update`. - * Returns `400` for all other requests. -* `http_request_update`, which can: - * `POST` to increment the counter. - * returning some static `gzip`ed data if `gzip` is accepted. - * otherwise return the new counter value. - * Returns `400` for all other requests. - - -## Prerequisites - -This example requires an installation of: - -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` - -Begin by opening a terminal window. - -### Step 1: Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the command: - -```bash -cd examples/motoko/http_counter -dfx start --background -``` - -### Step 2: Deploy the canister: - -```bash -dfx deploy -``` - -### Step 3: Take note of the canister ID to form URLs at which the `http_counter` is accessible. - -```bash -CANISTER_ID=$(dfx canister id http_counter) - -echo "http://localhost:4943/?canisterId=$CANISTER_ID" - -echo "http://$CANISTER_ID.localhost:4943/" -``` - -### Step 4: All functionality of the canister can be exercised with the following commands: - -```bash -CANISTER_ID=$(dfx canister id http_counter) - -# Get the counter -curl "$CANISTER_ID.localhost:4943/" --resolve "$CANISTER_ID.localhost:4943:127.0.0.1" - -# Get the static gzipped query content -curl --compressed "$CANISTER_ID.localhost:4943/" --resolve "$CANISTER_ID.localhost:4943:127.0.0.1" - -# Increment the counter -curl -X POST "$CANISTER_ID.localhost:4943/" --resolve "$CANISTER_ID.localhost:4943:127.0.0.1" - -# Increment the counter and get the static gzipped update content -curl --compressed -X POST "$CANISTER_ID.localhost:4943/" --resolve "$CANISTER_ID.localhost:4943:127.0.0.1" -``` - - -## Security considerations and best practices - -If you base your application on this example, we recommend you familiarize yourself with and adhere to the [security best practices](https://internetcomputer.org/docs/current/references/security/) for developing on the Internet Computer. This example may not implement all the best practices. - -For example, the following aspect is particularly relevant for this app: -* [Use HTTP asset certification and avoid serving your dApp through raw.ic0.app](https://internetcomputer.org/docs/current/developer-docs/security/security-best-practices/data-integrity-and-authenticity#use-http-asset-certification-and-avoid-serving-your-dapp-through-rawicp0io), in case the HTTP responses should come with authenticity guarantees. diff --git a/motoko/http_counter/dfx.json b/motoko/http_counter/dfx.json deleted file mode 100644 index 38a339236..000000000 --- a/motoko/http_counter/dfx.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "canisters": { - "http_counter": { - "main": "src/main.mo" - } - }, - "version": 1 -} \ No newline at end of file diff --git a/motoko/http_counter/src/main.mo b/motoko/http_counter/src/main.mo deleted file mode 100644 index 145e11d5c..000000000 --- a/motoko/http_counter/src/main.mo +++ /dev/null @@ -1,149 +0,0 @@ -import Nat "mo:base/Nat"; -import Text "mo:base/Text"; -import Array "mo:base/Array"; -import Option "mo:base/Option"; -import Prim "mo:⛔"; -import Prelude "mo:base/Prelude"; - - -actor HttpCounter { - - type StreamingCallbackHttpResponse = { - body: Blob; - token: ?Token; - }; - - type Token = { - // Add whatever fields you'd like - arbitrary_data: Text; - }; - - type CallbackStrategy = { - callback: shared query (Token) -> async StreamingCallbackHttpResponse; - token: Token; - }; - - type StreamingStrategy = { - #Callback: CallbackStrategy; - }; - - type HeaderField = (Text, Text); - - type HttpResponse = { - status_code: Nat16; - headers: [HeaderField]; - body: Blob; - streaming_strategy: ?StreamingStrategy; - upgrade: ?Bool; - }; - - type HttpRequest = { - method: Text; - url: Text; - headers: [HeaderField]; - body: Blob; - }; - - func isGzip(x : HeaderField) : Bool { - Text.map(x.0 , Prim.charToLower) == "accept-encoding" and Text.contains(Text.map(x.1 , Prim.charToLower), #text "gzip"); - }; - - stable var counter = 0; - - public query func http_request(req : HttpRequest) : async HttpResponse { - switch (req.method, not Option.isNull(Array.find(req.headers, isGzip)), req.url) { - case ("GET", false, "/stream") {{ - status_code = 200; - headers = [ ("content-type", "text/plain") ]; - body = Text.encodeUtf8("Counter"); - streaming_strategy = ?#Callback({ - callback = http_streaming; - token = { - arbitrary_data = "start"; - } - }); - upgrade = ?false; - }}; - case ("GET", false, _) {{ - status_code = 200; - headers = [ ("content-type", "text/plain") ]; - body = Text.encodeUtf8("Counter is " # Nat.toText(counter) # "\n" # req.url # "\n"); - streaming_strategy = null; - upgrade = null; - }}; - case ("GET", true, _) {{ - status_code = 200; - headers = [ ("content-type", "text/plain"), ("content-encoding", "gzip") ]; - body = "\1f\8b\08\00\98\02\1b\62\00\03\2b\2c\4d\2d\aa\e4\02\00\d6\80\2b\05\06\00\00\00"; - streaming_strategy = null; - upgrade = null; - }}; - - case ("POST", _, _) {{ - status_code = 204; - headers = []; - body = ""; - streaming_strategy = null; - upgrade = ?true; - }}; - case _ {{ - status_code = 400; - headers = []; - body = "Invalid request"; - streaming_strategy = null; - upgrade = null; - }}; - } - }; - - public func http_request_update(req : HttpRequest) : async HttpResponse { - switch (req.method, not Option.isNull(Array.find(req.headers, isGzip))) { - case ("POST", false) { - counter += 1; - { - status_code = 201; - headers = [ ("content-type", "text/plain") ]; - body = Text.encodeUtf8("Counter updated to " # Nat.toText(counter) # "\n"); - streaming_strategy = null; - upgrade = null; - } - }; - case ("POST", true) { - counter += 1; - { - status_code = 201; - headers = [ ("content-type", "text/plain"), ("content-encoding", "gzip") ]; - body = "\1f\8b\08\00\37\02\1b\62\00\03\2b\2d\48\49\2c\49\e5\02\00\a8\da\91\6c\07\00\00\00"; - - streaming_strategy = null; - upgrade = null; - } - }; - case _ {{ - status_code = 400; - headers = []; - body = "Invalid request"; - streaming_strategy = null; - upgrade = null; - }}; - } - }; - - public query func http_streaming(token : Token) : async StreamingCallbackHttpResponse { - switch (token.arbitrary_data) { - case "start" {{ - body = Text.encodeUtf8(" is "); - token = ?{arbitrary_data = "next"}; - }}; - case "next" {{ - body = Text.encodeUtf8(Nat.toText(counter)); - token = ?{arbitrary_data = "last"}; - }}; - case "last" {{ - body = Text.encodeUtf8(" streaming\n"); - token = null; - }}; - case _ { Prelude.unreachable() }; - } - }; -};