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

feat: ic-kit-http #25

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6a2a1fb
feat: initial impl ic-kit-http, supports only GET
ozwaldorf Sep 17, 2022
4c0bc29
feat: update call upgrade, [post, put, delete, option, head] macros
ozwaldorf Sep 17, 2022
d4d6b8c
feat: HttpRequest header helper, HttpResponse builder, pastebin retur…
ozwaldorf Sep 17, 2022
31f822c
feat: add basic index templating to pastebin example (canister side r…
ozwaldorf Sep 17, 2022
0ca7480
docs: pastebin readme
ozwaldorf Sep 17, 2022
66010ec
docs: add more to examples readme
ozwaldorf Sep 17, 2022
ddab442
chore: update dependencies to latest candid 0.8 and ic-types 0.6
ozwaldorf Oct 2, 2022
c9951a6
chore: minor tweaks on http stuff
ozwaldorf Oct 2, 2022
c3c8ce6
feat: dynamic url on pastebin example
ozwaldorf Oct 2, 2022
404e8f3
Merge branch 'main' into feat/ic-kit-http
ozwaldorf Oct 12, 2022
fbb012d
fix: duplicate imports
ozwaldorf Oct 12, 2022
9375d76
chore: move dep injection helpers to their own module
ozwaldorf Oct 13, 2022
3c75abd
feat: http method dependency injection
ozwaldorf Oct 13, 2022
124c135
feat: use dependency injection in the http pastebin example!
ozwaldorf Oct 13, 2022
2cbe627
feat: http mutable DI error message when not upgraded to update call
ozwaldorf Oct 13, 2022
ceda296
chore: bump all versions
ozwaldorf Oct 13, 2022
61e4cdb
refactor: export service now reuses new di::wrap, entry let's use take
ozwaldorf Oct 13, 2022
c6e77e5
chore: remove unused Method implementation from ic-kit-http
ozwaldorf Oct 13, 2022
e729c20
feat: hello example
ozwaldorf Oct 13, 2022
9cd689f
docs: update examples README
ozwaldorf Oct 13, 2022
2347558
docs: ic-kit-http cargo doc
ozwaldorf Oct 13, 2022
f47aeaa
refactor: simplify and fmt exports
ozwaldorf Oct 14, 2022
5a23ae6
refactor: experimental-http feature; patch, path, head, options
ozwaldorf Oct 14, 2022
e35a024
chore: fix cdk version metadata macro
ozwaldorf Nov 4, 2022
4ad4b0c
chore: hardcode cdk version metadata (for now)
ozwaldorf Nov 4, 2022
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
13 changes: 4 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
/target


# Added by cargo
#
# already existing elements were commented out

#/target
target/
Cargo.lock
.dfx
.dfx
*.old*
.idea/
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
[workspace]
members = [
"e2e",
"examples/hello",
"examples/counter",
"examples/factory_counter",
"examples/fib",
"examples/multi_counter",
"examples/naming_system",
"examples/pastebin",
"ic-kit",
"ic-kit-certified",
"ic-kit-macros",
"ic-kit-management",
"ic-kit-runtime",
"ic-kit-stable",
"ic-kit-sys",
"ic-kit-http",
]

[profile.canister-release]
Expand Down
11 changes: 11 additions & 0 deletions dfx.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
{
"version": 1,
"dfx": "0.11.1",
"canisters": {
"hello": {
"candid": "examples/hello/candid.did",
"package": "ic_kit_example_hello",
"type": "rust"
},
"counter": {
"candid": "examples/counter/candid.did",
"package": "ic_kit_example_counter",
Expand All @@ -15,6 +21,11 @@
"candid": "examples/naming_system/candid.did",
"package": "naming_system",
"type": "rust"
},
"pastebin": {
"candid": "examples/pastebin/candid.did",
"package": "ic_kit_example_pastebin",
"type": "rust"
}
},
"networks": {
Expand Down
22 changes: 21 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,25 @@ This directory contains some example canister's implemented using the IC Kit. Ea
to be as simple as possible to demonstrate one aspect of the IC Kit and a possible design pattern
you can also use to develop canisters.

Hello World:

- [Hello](hello/): A simple canister that returns a greeting.

Simple State Manipulation:
- Counter

- [Counter](counter/): A simple canister that allows incrementing and decrementing a counter.

Inter Canister Communication:

- [Multi Counter](multi_counter/): A canister that allows incrementing and decrementing a counter
that is stored in separate canisters.

Child Canister Creation:

- [Factory Counter](factory_counter/): A canister that allows incrementing and decrementing a counter
that is stored in separate canisters that are created on demand.

Inbound HTTP Server:

- [Pastebin](pastebin/): A canister that allows storing and retrieving unencrypted text snippets through http routing.
Also features a simple canister generated frontend, that serves plaintext or html depending on the request client.
4 changes: 3 additions & 1 deletion examples/counter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ic-kit = {path="../../ic-kit"}
# With the `http` feature enabled, and no configured routes, the canister will provide status info at the index path.
ic-kit = { path = "../../ic-kit" }


[[bin]]
name = "ic_kit_example_counter"
Expand Down
14 changes: 14 additions & 0 deletions examples/hello/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "ic_kit_example_hello"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
# With the `http` feature enabled, and no configured routes, the canister will provide status info at the index path.
ic-kit = { path = "../../ic-kit", features = ["http"] }

[[bin]]
name = "ic_kit_example_hello"
path = "src/main.rs"
1 change: 1 addition & 0 deletions examples/hello/candid.did
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
service : { hello : () -> (text) query }
13 changes: 13 additions & 0 deletions examples/hello/src/canister.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use ic_kit::prelude::*;

#[query]
fn hello() -> String {
"Hello, World!".to_string()
}

// When the http feature is enabled, the `http_request` function is generated, with a single index route.
// This index route returns the balance of the canister in cycles, in JSON.

#[derive(KitCanister)]
#[candid_path("candid.did")]
struct HelloCanister;
1 change: 1 addition & 0 deletions examples/hello/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod canister;
3 changes: 3 additions & 0 deletions examples/hello/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod canister;

fn main() {}
15 changes: 15 additions & 0 deletions examples/pastebin/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "ic_kit_example_pastebin"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ic-kit = {path="../../ic-kit", features = ["http"]}
tinytemplate = "1.1"
serde = { version = "1.0", features = ["derive"] }

[[bin]]
name = "ic_kit_example_pastebin"
path = "src/main.rs"
23 changes: 23 additions & 0 deletions examples/pastebin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# IC Pastebin

This directory contains an example HTTP canister implemented using the IC Kit. It is a simple HTTP pastebin that allows you to store and retrieve text.

## How to use

1. Build and deploy the canister:
```bash
dfx deploy pastebin
```
2. View the canister's HTML UI at `http://rrkah-fqaaa-aaaaa-aaaaq-cai.localhost:8000/`
3. View the canister's manpage:
```bash
curl rrkah-fqaaa-aaaaa-aaaaq-cai.localhost:8000
```
5. upload some text:
```bash
curl -T file.txt rrkah-fqaaa-aaaaa-aaaaq-cai.localhost:8000
```
5. download some text:
```bash
curl rrkah-fqaaa-aaaaa-aaaaq-cai.localhost:8000/file.txt
```
1 change: 1 addition & 0 deletions examples/pastebin/candid.did
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
service : {}
115 changes: 115 additions & 0 deletions examples/pastebin/src/canister.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
use std::collections::HashMap;

use serde::Serialize;
use tinytemplate::TinyTemplate;

use ic_kit::prelude::*;

pub type Data = HashMap<String, Vec<u8>>;

#[derive(Serialize)]
struct HtmlContext {
manpage: String,
}

#[derive(Serialize)]
struct ManpageContext {
url: String,
}

static HTML_TEMPLATE: &str = r#"
<!DOCTYPE html>
<html>
<head>
<title>IC Pastebin</title>
<style>
body \{
background: #1e1e1e;
color: #d4d4d4;
\}
</style>
</head>
<body>
<pre>
<code>
{manpage}
</code>
</pre>
</body>
</html>
"#;

static MANPAGE_TEMPLATE: &str = r#"
IC PASTEBIN(1) IC PASTEBIN IC PASTEBIN(1)

NAME

ic-pastebin - HTTP pastebin canister for the Internet Computer

DESCRIPTION

The ic-pastebin canister is a simple pastebin canister that allows users to
upload text and get a URL to share it with others.

The canister is written in Rust and uses the ic-kit library to provide
access to the Internet Computer.

USAGE

curl -T file.txt {url}
curl {url}/file.txt
"#;

/// Index handler
#[get(route = "/")]
fn index_handler(r: HttpRequest, _: Params) -> HttpResponse {
ic::print(format!("{:?}", r));
let url = match r.header("host") {
Some(host) => format!("http://{}", host),
None => format!("https://{}.raw.ic0.app", id()),
};

let mut tt = TinyTemplate::new();

tt.add_template("manpage", MANPAGE_TEMPLATE).unwrap();
let manpage = tt.render("manpage", &ManpageContext { url }).unwrap();

// Just return the manpage if client is a terminal (curl or wget)
if let Some(ua) = r.header("User-Agent") {
if ua.starts_with("curl") || ua.starts_with("wget") {
return HttpResponse::ok().body(manpage);
}
}

tt.add_template("html", HTML_TEMPLATE).unwrap();
let html = tt.render("html", &HtmlContext { manpage }).unwrap();

HttpResponse::ok().body(html)
}

/// Get paste handler
#[get(route = "/:file")]
fn get_file_handler(data: &Data, _: HttpRequest, p: Params) -> HttpResponse {
let file = p.get("file").unwrap();
match data.get(file) {
Some(content) => HttpResponse::ok().body(content.clone()),
None => HttpResponse::new(404).body(format!("file not found `{}`\n", file)),
}
}

/// Upload paste handler
#[put(route = "/:file", upgrade = true)]
fn put_file_handler(data: &mut Data, req: HttpRequest, p: Params) -> HttpResponse {
let filename = p.get("file").unwrap();
let host = req.header("host").unwrap_or("unknown");

let res = format!("{}/{}", host, filename);

data.insert(filename.to_string(), req.body);

HttpResponse::ok().body(res)
}

#[derive(KitCanister)]
#[candid_path("candid.did")]
pub struct PastebinCanister;
2 changes: 2 additions & 0 deletions examples/pastebin/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod canister;
pub use canister::PastebinCanister;
3 changes: 3 additions & 0 deletions examples/pastebin/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod canister;

fn main() {}
10 changes: 5 additions & 5 deletions ic-kit-certified/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ic-kit-certified"
version = "0.1.0-alpha.0"
version = "0.1.0-alpha.1"
edition = "2018"
description = "Certified variable friendly data structures for the Internet Computer."
authors = ["Parsa Ghadimi <[email protected]>", "Ossian Mapes <[email protected]>"]
Expand All @@ -14,11 +14,11 @@ keywords = ["internet-computer", "canister", "fleek", "psychedelic"]
include = ["src", "Cargo.toml", "README.md"]

[dependencies]
ic-kit-stable = {path="../ic-kit-stable"}
ic-types = "0.4.1"
candid = "0.7"
ic-kit-stable = { path = "../ic-kit-stable" }
ic-types = "0.6"
candid = "0.8"
sha2 = "0.10.2"
serde = { version="1.0.116", features = ["derive"] }
serde = { version = "1.0.116", features = ["derive"] }
serde_bytes = "0.11.5"
serde_cbor = "0.11.2"
hex = "0.4.3"
23 changes: 23 additions & 0 deletions ic-kit-http/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "ic-kit-http"
version = "0.1.0-alpha.2"
edition = "2021"
authors = ["Ossian Mapes <[email protected]>", "Parsa Ghadimi <[email protected]>"]
description = "IC-Kit's macros for canister development"
license = "MIT"
readme = "README.md"
repository = "https://github.com/Psychedelic/ic-kit"
documentation = "https://docs.rs/ic-kit-http"
homepage = "https://sly.ooo"
categories = ["api-bindings"]
keywords = ["internet-computer", "canister", "fleek", "psychedelic"]
include = ["src", "Cargo.toml", "README.md"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ic-kit-macros = { path = "../ic-kit-macros", features = ["http"], version = "0.2.0-alpha.0" }
candid = "0.8"
serde = "1.0"
matchit = "0.6.0"
lazy_static = "1.4"
3 changes: 3 additions & 0 deletions ic-kit-http/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Ic Kit Http

Types and macro export for canister http routing
Loading