Skip to content

Commit

Permalink
✨ Handle base URI
Browse files Browse the repository at this point in the history
Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev>
  • Loading branch information
mhkarimi1383 committed Oct 18, 2024
1 parent dcd0d85 commit b27d639
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 17 deletions.
39 changes: 31 additions & 8 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package cmd

import (
"bytes"
"io"
"mime"
"net/http"
neturl "net/url"
"os"
"path/filepath"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -81,7 +86,7 @@ func init() {
rootCmd.PersistentFlags().StringVar(&cfg.JWTSecret, "jwt-secret", "superdupersecret", "jwt secret to sign tokens with, strongly recommended to change")
rootCmd.PersistentFlags().BoolVar(&cfg.AddRefererQueryParam, "add-referer-query-param", true, "Add 'referer' query param to redirect url or not")
rootCmd.PersistentFlags().IntVar(&cfg.RandomGeneratorMax, "random-generator-max", 10000, "Generator will use this to generate shortcodes (higher value = bigger shortcodes), at least 10000 should be set")
rootCmd.PersistentFlags().StringVarP(&cfg.RootRedirect, "root-redirect", "r", "/ui/", "Path/URL to redirect when someone comes to root url")
rootCmd.PersistentFlags().StringVarP(&cfg.RootRedirect, "root-redirect", "r", "/BASE_URI/ui/", "Path/URL to redirect when someone comes to root url")
rootCmd.PersistentFlags().StringVar(&cfg.BaseURI, "base-uri", "/", "Base URL of the project")
}

Expand Down Expand Up @@ -110,6 +115,7 @@ func start(_ *cobra.Command, _ []string) {
}

cfg.BaseURI = strings.TrimSuffix(cfg.BaseURI, "/")
cfg.RootRedirect = strings.ReplaceAll(cfg.RootRedirect, "/BASE_URI/", cfg.BaseURI+"/")

log.Logger.Info("Initializing database engine")
database.Init()
Expand Down Expand Up @@ -202,14 +208,31 @@ func start(_ *cobra.Command, _ []string) {
entityGroup.POST("/", entity.Create)
entityGroup.DELETE("/:"+constrains.IdParamName+"/", entity.Delete)

uiGroup := e.Group("/ui")
uiGroup := rootGroup.Group("/ui")
uiGroup.Any("", nil, addTrailingSlashMiddleware)
uiGroup.StaticFS("/", ui.MainFS)
uiGroup.StaticFS("/assets/", ui.AssetsFS)
uiGroup.FileFS("/*.html", "index.html", ui.MainFS)
uiGroup.FileFS("/logo.svg", "logo.svg", ui.MainFS)
rootGroup.FileFS("/favicon.ico", "favicon.ico", ui.MainFS)
e.FileFS("/ui/favicon.ico", "favicon.ico", ui.MainFS)
uiGroup.GET("/*", func(c echo.Context) error {
prefix := filepath.Join("/"+strings.TrimPrefix(cfg.BaseURI, "/"), "/ui/")
filePath := strings.TrimPrefix(strings.TrimPrefix(c.Request().URL.Path, prefix), "/")
file, err := ui.MainFS.Open(filePath)
if err != nil {
filePath = "index.html"
file, _ = ui.MainFS.Open(filePath)
}
defer file.Close()
buf := new(bytes.Buffer)
_, err = io.Copy(buf, file)
if err != nil {
return err
}
newURI, err := neturl.JoinPath("/BASE_URI/", "../"+cfg.BaseURI+"/")
if err != nil {
return err
}
println(newURI)
modifiedContent := strings.ReplaceAll(buf.String(), "/BASE_URI/", newURI)
fileParts := strings.Split(filePath, ".")
return c.Blob(200, mime.TypeByExtension("."+fileParts[len(fileParts)-1]), []byte(modifiedContent))
})

if configuration.CurrentConfig.RunServer {
log.Logger.Info("WebServer Started", zap.String("listen-address", configuration.CurrentConfig.ListenAddress))
Expand Down
16 changes: 12 additions & 4 deletions internal/endpoint/url/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,17 @@ func Create(c echo.Context) error {
return err
}

shortcode, err := controller.CreateUrl(r, user)
shortCode, err := controller.CreateUrl(r, user)
if err != nil {
return err
}
shortURL, err := url.JoinPath(c.Scheme()+"://"+c.Request().Host, configuration.CurrentConfig.BaseURI, "/"+shortCode)
if err != nil {
return err
}
return c.JSON(http.StatusCreated, responseschemas.Create{
ShortCode: shortcode,
ShortUrl: c.Scheme() + "://" + c.Request().Host + "/" + shortcode,
ShortCode: shortCode,
ShortUrl: shortURL,
})
}

Expand Down Expand Up @@ -95,7 +99,11 @@ func List(c echo.Context) error {
}

for i, item := range list.Result {
list.Result[i].ShortUrl = c.Scheme() + "://" + c.Request().Host + "/" + item.ShortCode
shortURL, err := url.JoinPath(c.Scheme()+"://"+c.Request().Host, configuration.CurrentConfig.BaseURI, "/"+item.ShortCode)
if err != nil {
return err
}
list.Result[i].ShortUrl = shortURL
}

return c.JSON(http.StatusOK, list)
Expand Down
2 changes: 1 addition & 1 deletion ui/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ watch(
margin-right: 0.25%;`"
title="URL Shortener"
:avatar="{
src: '/ui/logo.svg',
src: '/BASE_URI/ui/logo.svg',
shape: 'square',
style: currentTheme === 'dark' && 'filter: invert(100%);',
}"
Expand Down
2 changes: 1 addition & 1 deletion ui/src/lib/api/client.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import router from '@/router';
import axios, { type AxiosError } from 'axios';

const apiBaseURL = '/api';
const apiBaseURL = '/BASE_URI/api';
let userToken: undefined | string = undefined;

const client = axios.create({
Expand Down
2 changes: 1 addition & 1 deletion ui/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ const app = createApp(App);
app.use(router);
app.use(Antd);
app.use(VueCookies, {
path: '/ui/',
secure: true,
expires: '20d',
sameSite: 'Strict',
path: '/BASE_URI/ui/',
domain: window.location.hostname,
});

Expand Down
2 changes: 1 addition & 1 deletion ui/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import HomeView from '../views/HomeView.vue';
import { createRouter, createWebHistory } from 'vue-router';

const router = createRouter({
history: createWebHistory('/ui'),
history: createWebHistory('/BASE_URI/ui'),
routes: [
{
path: '/',
Expand Down
2 changes: 1 addition & 1 deletion ui/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { URL, fileURLToPath } from 'node:url';

// https://vitejs.dev/config/
export default defineConfig({
base: "/ui",
base: "/BASE_URI/ui",
plugins: [
vue(),
],
Expand Down

0 comments on commit b27d639

Please sign in to comment.