mirror of
https://github.com/minoplhy/chhoto-url.git
synced 2024-12-23 04:07:55 +00:00
commit
753b73c4a3
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,4 +1,4 @@
|
||||
# Ignore cargo build outputs
|
||||
# Ignore build outputs
|
||||
actix/target
|
||||
|
||||
# Ignore SQLite file
|
||||
@ -7,3 +7,5 @@ urls.sqlite
|
||||
# Ignore irrelevant dotfiles
|
||||
.vscode/
|
||||
**/.directory
|
||||
.env
|
||||
|
||||
|
10
Dockerfile
10
Dockerfile
@ -7,20 +7,20 @@ COPY ./actix/src ./src
|
||||
RUN cargo chef prepare --recipe-path recipe.json
|
||||
|
||||
FROM chef as builder
|
||||
ARG target=x86_64-unknown-linux-musl
|
||||
RUN apt-get update && apt-get install -y musl-tools
|
||||
RUN rustup target add x86_64-unknown-linux-musl
|
||||
RUN rustup target add $target
|
||||
|
||||
COPY --from=planner /chhoto-url/recipe.json recipe.json
|
||||
# Build dependencies - this is the caching Docker layer
|
||||
RUN cargo chef cook --release --target=x86_64-unknown-linux-musl --recipe-path recipe.json
|
||||
RUN cargo chef cook --release --target=$target --recipe-path recipe.json
|
||||
|
||||
COPY ./actix/Cargo.toml ./actix/Cargo.lock .
|
||||
COPY ./actix/src ./src
|
||||
# Build application
|
||||
RUN cargo build --release --target=x86_64-unknown-linux-musl --locked --bin chhoto-url
|
||||
RUN cargo build --release --target=$target --locked --bin chhoto-url
|
||||
|
||||
FROM scratch
|
||||
COPY --from=builder /chhoto-url/target/x86_64-unknown-linux-musl/release/chhoto-url /chhoto-url
|
||||
COPY --from=builder /chhoto-url/target/$target/release/chhoto-url /chhoto-url
|
||||
COPY ./resources /resources
|
||||
ENTRYPOINT ["/chhoto-url"]
|
||||
|
||||
|
15
Dockerfile.multiarch
Normal file
15
Dockerfile.multiarch
Normal file
@ -0,0 +1,15 @@
|
||||
FROM scratch as builder-amd64
|
||||
COPY ./actix/target/x86_64-unknown-linux-musl/release/chhoto-url /chhoto-url
|
||||
|
||||
FROM scratch as builder-arm64
|
||||
COPY ./actix/target/aarch64-unknown-linux-musl/release/chhoto-url /chhoto-url
|
||||
|
||||
FROM scratch as builder-arm
|
||||
COPY ./actix/target/armv7-unknown-linux-musleabihf/release/chhoto-url /chhoto-url
|
||||
|
||||
ARG TARGETARCH
|
||||
FROM builder-$TARGETARCH
|
||||
COPY ./resources /resources
|
||||
|
||||
ENTRYPOINT ["/chhoto-url"]
|
||||
|
43
Makefile
Normal file
43
Makefile
Normal file
@ -0,0 +1,43 @@
|
||||
# .env file has the variables $DOCKER_USERNAME and $PASSWORD defined
|
||||
include .env
|
||||
|
||||
setup:
|
||||
cargo install cross
|
||||
rustup target add x86_64-unknown-linux-musl
|
||||
docker buildx create --use --platform=linux/arm64,linux/amd64 --name multi-platform-builder
|
||||
docker buildx inspect --bootstrap
|
||||
|
||||
build-dev:
|
||||
cargo build --release --locked --manifest-path=actix/Cargo.toml --target x86_64-unknown-linux-musl
|
||||
|
||||
docker-local: build-dev
|
||||
docker build --tag chhoto-url --build-arg TARGETARCH=amd64 -f Dockerfile.multiarch .
|
||||
|
||||
docker-test: docker-local
|
||||
docker ps -q --filter "name=chhoto-url" | xargs -r docker stop
|
||||
docker ps -aq --filter "name=chhoto-url" | xargs -r docker rm
|
||||
docker run -p 4567:4567 --name chhoto-url -e password="${PASSWORD}" -d chhoto-url
|
||||
docker logs chhoto-url -f
|
||||
|
||||
docker-dev: build-dev
|
||||
docker build --push --tag ${DOCKER_USERNAME}/chhoto-url:dev --build-arg TARGETARCH=amd64 -f Dockerfile.multiarch .
|
||||
|
||||
build-release:
|
||||
cross build --release --locked --manifest-path=actix/Cargo.toml --target aarch64-unknown-linux-musl
|
||||
cross build --release --locked --manifest-path=actix/Cargo.toml --target armv7-unknown-linux-musleabihf
|
||||
cross build --release --locked --manifest-path=actix/Cargo.toml --target x86_64-unknown-linux-musl
|
||||
|
||||
V_PATCH := $(shell cat actix/Cargo.toml | sed -rn 's/^version = "(.+)"$$/\1/p')
|
||||
V_MINOR := $(shell cat actix/Cargo.toml | sed -rn 's/^version = "(.+)\..+"$$/\1/p')
|
||||
V_MAJOR := $(shell cat actix/Cargo.toml | sed -rn 's/^version = "(.+)\..+\..+"$$/\1/p')
|
||||
docker-release: build-release
|
||||
docker buildx build --push --tag ${DOCKER_USERNAME}/chhoto-url:${V_MAJOR} --tag ${DOCKER_USERNAME}/chhoto-url:${V_MINOR} \
|
||||
--tag ${DOCKER_USERNAME}/chhoto-url:${V_PATCH} --tag ${DOCKER_USERNAME}/chhoto-url:latest \
|
||||
--platform linux/amd64,linux/arm64,linux/arm/v7 -f Dockerfile.multiarch .
|
||||
|
||||
clean:
|
||||
docker ps -q --filter "name=chhoto-url" | xargs -r docker stop
|
||||
docker ps -aq --filter "name=chhoto-url" | xargs -r docker rm
|
||||
cargo clean --manifest-path=actix/Cargo.toml
|
||||
|
||||
.PHONY: build-dev docker-local build-release
|
19
README.md
19
README.md
@ -18,8 +18,12 @@ If you feel like a feature is missing, please let me know by creating an issue
|
||||
using the "feature request" template.
|
||||
|
||||
## But why another URL shortener?
|
||||
I've looked at a couple popular URL shorteners, however they either have
|
||||
unnecessary features, or they didn't have all the features I wanted.
|
||||
Most URL shorteners are either bloated with unnecessary features, or are a pain to set up.
|
||||
Even fewer are written with simplicity and lightness in mind. When I saw the simply-shorten
|
||||
project (linked below), I really liked the idea but thought that it missed some details. Also,
|
||||
I didn't like the fact that a simple app like this had a ~200 MB docker image (mostly due to the
|
||||
included java runtime). So, I decided to rewrite it in Rust and add some features to it that I
|
||||
thought were essential (e.g. hit counting).
|
||||
|
||||
## What does the name mean?
|
||||
Chhoto (ছোট, [IPA](https://en.wikipedia.org/wiki/Help:IPA/Bengali): /tʃʰoʈo/) is the Bangla word
|
||||
@ -75,10 +79,17 @@ place, resulting in possibly unwanted behavior.
|
||||
|
||||
## Building and running with docker
|
||||
### `docker run` method
|
||||
0. (Only if you really want to) Build the image
|
||||
0. (Only if you really want to) Build the image for the default `x86_64-unknown-linux-musl` target:
|
||||
```
|
||||
docker build . -t chhoto-url:latest
|
||||
docker build . -t chhoto-url
|
||||
```
|
||||
For building on `arm64` or `arm/v7`, use the following:
|
||||
```
|
||||
docker build . -t chhoto-url --build-arg target=<desired-target>
|
||||
```
|
||||
Make sure that the desired target is a `musl` one, since the docker image is built from `scratch`.
|
||||
For cross-compilation, take a look at the `Makefile`. It builds and pushes for `linux/amd64`, `linux/aarch64`
|
||||
and `linux/arm/v7` architectures. For any other architectures, open a discussion, and I'll try to help you out.
|
||||
1. Run the image
|
||||
```
|
||||
docker run -p 4567:4567
|
||||
|
84
actix/Cargo.lock
generated
84
actix/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,20 +1,13 @@
|
||||
use rusqlite::Connection;
|
||||
|
||||
pub fn find_url(shortlink: &str, db: &Connection) -> String {
|
||||
pub fn find_url(shortlink: &str, db: &Connection) -> Option<String> {
|
||||
let mut statement = db
|
||||
.prepare_cached("SELECT long_url FROM urls WHERE short_url = ?1")
|
||||
.unwrap();
|
||||
|
||||
let links = statement
|
||||
.query_map([shortlink], |row| row.get("long_url"))
|
||||
.unwrap();
|
||||
|
||||
let mut longlink = String::new();
|
||||
for link in links {
|
||||
longlink = link.unwrap();
|
||||
}
|
||||
|
||||
longlink
|
||||
statement
|
||||
.query_row([shortlink], |row| row.get("long_url"))
|
||||
.ok()
|
||||
}
|
||||
|
||||
pub fn getall(db: &Connection) -> Vec<String> {
|
||||
|
@ -6,7 +6,7 @@ use actix_web::{
|
||||
http::StatusCode,
|
||||
middleware, post,
|
||||
web::{self, Redirect},
|
||||
App, HttpResponse, HttpServer, Responder,
|
||||
App, Either, HttpResponse, HttpServer, Responder,
|
||||
};
|
||||
use rusqlite::Connection;
|
||||
use std::env;
|
||||
@ -78,18 +78,22 @@ async fn error404() -> impl Responder {
|
||||
#[get("/{shortlink}")]
|
||||
async fn link_handler(shortlink: web::Path<String>, data: web::Data<AppState>) -> impl Responder {
|
||||
let shortlink_str = shortlink.to_string();
|
||||
let longlink = utils::get_longurl(shortlink_str, &data.db);
|
||||
if longlink.is_empty() {
|
||||
Redirect::to("/err/404")
|
||||
} else {
|
||||
if let Some(longlink) = utils::get_longurl(shortlink_str, &data.db) {
|
||||
let redirect_method = env::var("redirect_method").unwrap_or(String::from("PERMANENT"));
|
||||
database::add_hit(shortlink.as_str(), &data.db);
|
||||
if redirect_method == "TEMPORARY" {
|
||||
Redirect::to(longlink)
|
||||
Either::Left(Redirect::to(longlink))
|
||||
} else {
|
||||
// Defaults to permanent redirection
|
||||
Redirect::to(longlink).permanent()
|
||||
Either::Left(Redirect::to(longlink).permanent())
|
||||
}
|
||||
} else {
|
||||
Either::Right(
|
||||
NamedFile::open_async("./resources/static/404.html")
|
||||
.await
|
||||
.customize()
|
||||
.with_status(StatusCode::NOT_FOUND),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,11 @@ use rand::seq::SliceRandom;
|
||||
use regex::Regex;
|
||||
use rusqlite::Connection;
|
||||
|
||||
pub fn get_longurl(shortlink: String, db: &Connection) -> String {
|
||||
pub fn get_longurl(shortlink: String, db: &Connection) -> Option<String> {
|
||||
if validate_link(&shortlink) {
|
||||
database::find_url(shortlink.as_str(), db)
|
||||
} else {
|
||||
String::new()
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ pub fn add_link(req: String, db: &Connection) -> (bool, String) {
|
||||
shortlink = random_name();
|
||||
}
|
||||
|
||||
if validate_link(shortlink.as_str()) && get_longurl(shortlink.clone(), db).is_empty() {
|
||||
if validate_link(shortlink.as_str()) && get_longurl(shortlink.clone(), db).is_none() {
|
||||
(
|
||||
database::add_link(shortlink.clone(), longlink, db),
|
||||
shortlink,
|
||||
|
@ -1,37 +0,0 @@
|
||||
#!/bin/env bash
|
||||
|
||||
if [ "$1" == "dev" ]; then
|
||||
name="chhoto-url"
|
||||
docker build -t $name .
|
||||
docker tag $name sintan1729/$name:dev
|
||||
docker push sintan1729/$name:dev
|
||||
|
||||
elif [ "$1" == "release" ]; then
|
||||
v_patch=$(cat actix/Cargo.toml | sed -rn 's/^version = "(.+)"$/\1/p')
|
||||
v_minor=$(echo $v_patch | sed -rn 's/^(.+\..+)\..+$/\1/p')
|
||||
v_major=$(echo $v_minor | sed -rn 's/^(.+)\..+$/\1/p')
|
||||
|
||||
name="chhoto-url"
|
||||
|
||||
docker build -t $name .
|
||||
|
||||
for tag in $v_major $v_minor $v_patch latest
|
||||
do
|
||||
docker tag $name sintan1729/$name:$tag
|
||||
done
|
||||
|
||||
echo "Do you want to push these to Docker Hub?"
|
||||
select yn in "Yes" "No";
|
||||
do
|
||||
if [ "$yn"="Yes" ]; then
|
||||
for tag in $v_major $v_minor $v_patch latest
|
||||
do
|
||||
docker push sintan1729/$name:$tag
|
||||
done
|
||||
else
|
||||
echo "Okay! Not pushing."
|
||||
fi
|
||||
break
|
||||
done
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user