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

Custom httpStatusCode in redirect() #324

Closed
wants to merge 45 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
81a1145
Parse IP address to see what domain to use
ire4ever1190 Dec 1, 2022
d6cd0bc
add startup callback to settings for httpbeast
bung87 Aug 6, 2023
8851d5c
ci
bung87 Aug 15, 2023
dd857cc
Fix CI
ThomasTJdev Aug 20, 2023
a4111d9
Add common intellij paths to .gitignore
torbencarstens Sep 18, 2023
ad46aa4
Use 1.6.14 in CI instead of pre-1.6.0 git sha
torbencarstens Sep 18, 2023
08bec4a
Add 2.0.0 to test matrix
torbencarstens Sep 18, 2023
2fe8aa7
Only test nim-in-action-code/Chapter7 for nim versions < 2.0
torbencarstens Sep 18, 2023
c631652
Bump actions/checkout and iffy/install-nim
torbencarstens Sep 18, 2023
f05bd2b
Run 'git submodule update --init' for 'nimble test' to ensure that al…
torbencarstens Sep 18, 2023
88b2ace
Add 'nimble refresh' and 'nimble install' for 'nimble test' task befo…
torbencarstens Sep 18, 2023
5c9e5d3
Remove trailing whitespace
torbencarstens Sep 18, 2023
fef495a
Add support for duplicate keys in parameters by adding `paramValuesAs…
torbencarstens Sep 18, 2023
b8374b4
Adapt `params` to use `cgi.decodeData` instead of `parseUrlQuery`
torbencarstens Sep 18, 2023
f916b25
Add tests for #247
torbencarstens Sep 18, 2023
d330fad
Fix argument name to iffy/install-nim
torbencarstens Sep 18, 2023
1cce8cc
Auto accept nimble for refresh/install
torbencarstens Sep 18, 2023
944dc39
Run debug actions in CI
torbencarstens Sep 18, 2023
149d5bf
Only debug 2.0.0
torbencarstens Sep 18, 2023
88e4a29
Remove debug actions
torbencarstens Sep 18, 2023
cda4d39
Run nim2 with '--mm:refc'
torbencarstens Sep 18, 2023
85b2692
Remove nim2 from CI
torbencarstens Sep 18, 2023
84035bf
Remove debug when
torbencarstens Sep 18, 2023
44d5868
Revert "Add common intellij paths to .gitignore"
torbencarstens Sep 19, 2023
946814b
Custom http status code in redirect template
ThomasTJdev Oct 5, 2023
79c809c
Update readme
ThomasTJdev Jan 19, 2024
c6bd588
Update nimble for nim v2.0
ThomasTJdev Jan 19, 2024
b12cbbd
Update tests
ThomasTJdev Jan 19, 2024
d8f0457
Bump required nim version
ThomasTJdev Jan 19, 2024
cf3d359
Remove submodules
ThomasTJdev Jan 19, 2024
c104122
Fix test cases
ThomasTJdev Jan 19, 2024
8446b24
Submodules - remove
ThomasTJdev Jan 19, 2024
92d7799
Add nim-in-action tests
ThomasTJdev Jan 19, 2024
189234f
Fix test dep
ThomasTJdev Jan 19, 2024
ad0974c
Merge branch 'master' into startup
ThomasTJdev Jan 19, 2024
c4024e4
Merge branch 'master' into ipv6address
ThomasTJdev Jan 19, 2024
c824fef
Merge branch 'master' into allowDuplicateQueryKeys
ThomasTJdev Jan 19, 2024
6af5231
Merge pull request #3 from ThomasTJdev/startup
ThomasTJdev Jan 20, 2024
b303134
Merge pull request #2 from ThomasTJdev/allowDuplicateQueryKeys
ThomasTJdev Jan 20, 2024
e99b3db
Merge branch 'master' into ipv6address
ThomasTJdev Jan 20, 2024
9071e05
gitignore
ThomasTJdev Jan 20, 2024
3f34d94
Bump min nim version to 1.6.18 (domain in serve*)
ThomasTJdev Jan 20, 2024
6172292
Merge pull request #1 from ThomasTJdev/ipv6address
ThomasTJdev Jan 20, 2024
1f83405
Readme update
ThomasTJdev Jan 20, 2024
bb2f1d2
Merge branch 'master' into redirectHttpStatus
ThomasTJdev Jan 20, 2024
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
31 changes: 13 additions & 18 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,28 @@
name: tests
name: Main test

on:
push:
pull_request:
branches: [master]
schedule:
- cron: '0 0 * * 1'

jobs:
tests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
nimversion:
- 1.4.8
- git:6b97889f44d06f66
nim:
- 1.6.18
- 2.0.2
os:
- ubuntu-latest
- macOS-latest
- windows-latest
steps:
- uses: actions/checkout@v1
with:
submodules: true
- uses: iffy/[email protected]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
nimversion: ${{ matrix.nimversion }}
- name: Test
run: |
nimble test
nimble refresh
- uses: actions/checkout@v3
- name: Setup nim
uses: jiro4989/setup-nim-action@v1
with:
nim-version: ${{ matrix.nim }}
- run: |
nimble test -Y
nimble refresh
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/tests/*
!/tests/*.nim
!/tests/*/
!/tests/nim-in-action-code/*
/tests/nim-in-action-code/Chapter7/Tweeter/src/tweeter

nimcache
3 changes: 0 additions & 3 deletions .gitmodules

This file was deleted.

31 changes: 24 additions & 7 deletions jester.nim
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,14 @@ type
of RouteCode:
data: ResponseData

Startup = proc () {.closure, gcsafe.}

const jesterVer = "0.6.0"

proc doNothing(): Startup {.gcsafe.} =
result = proc () {.closure, gcsafe.} =
discard

proc toStr(headers: Option[RawHeaders]): string =
return $newHttpHeaders(headers.get(@({:})))

Expand Down Expand Up @@ -421,7 +427,8 @@ proc handleRequest(jes: Jester, httpReq: NativeRequest): Future[void] =
proc newSettings*(
port = Port(5000), staticDir = getCurrentDir() / "public",
appName = "", bindAddr = "", reusePort = false, maxBody = 8388608, numThreads = 0,
futureErrorHandler: proc (fut: Future[void]) {.closure, gcsafe.} = nil
futureErrorHandler: proc (fut: Future[void]) {.closure, gcsafe.} = nil,
startup: Startup = doNothing()
): Settings =
result = Settings(
staticDir: normalizedPath(staticDir),
Expand All @@ -431,7 +438,8 @@ proc newSettings*(
reusePort: reusePort,
maxBody: maxBody,
numThreads: numThreads,
futureErrorHandler: futureErrorHandler
futureErrorHandler: futureErrorHandler,
startup: startup
)

proc register*(self: var Jester, matcher: MatchProc) =
Expand Down Expand Up @@ -524,20 +532,29 @@ proc serve*(
[$self.settings.port, self.settings.appName])

var jes = self
let domain = block:
if self.settings.bindAddr != "":
let ip = self.settings.bindAddr.parseIpAddress()
if ip.family == IPv4:
AF_INET
else:
AF_INET6
else:
AF_INET
when useHttpBeast:
run(
proc (req: httpbeast.Request): Future[void] =
{.gcsafe.}:
{.gcsafe.}:
result = handleRequest(jes, req),
httpbeast.initSettings(self.settings.port, self.settings.bindAddr, self.settings.numThreads)
httpbeast.initSettings(self.settings.port, self.settings.bindAddr, self.settings.numThreads, startup = self.settings.startup, domain = domain)
)
else:
self.httpServer = newAsyncHttpServer(reusePort=self.settings.reusePort, maxBody=self.settings.maxBody)
let serveFut = self.httpServer.serve(
self.settings.port,
proc (req: asynchttpserver.Request): Future[void] {.gcsafe, closure.} =
result = handleRequest(jes, req),
self.settings.bindAddr)
self.settings.bindAddr, domain = domain)
if not self.settings.futureErrorHandler.isNil:
serveFut.callback = self.settings.futureErrorHandler
else:
Expand Down Expand Up @@ -612,15 +629,15 @@ template resp*(code: HttpCode): typed =
result.matched = true
break route

template redirect*(url: string, halt = true): typed =
template redirect*(url: string, halt = true, httpStatusCode = Http303): typed =
## Redirects to ``url``. Returns from this request handler immediately.
##
## If ``halt`` is true, skips executing future handlers, too.
##
## Any set response headers are preserved for this request.
bind TCActionSend, newHttpHeaders
result[0] = TCActionSend
result[1] = Http303
result[1] = httpStatusCode
setHeader(result[2], "Location", url)
result[3] = ""
result.matched = true
Expand Down
10 changes: 8 additions & 2 deletions jester.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,17 @@ skipDirs = @["tests"]

# Deps

requires "nim >= 1.0.0"
requires "nim >= 1.6.18"

when not defined(windows):
requires "httpbeast >= 0.4.0"
when NimMajor >= 2:
requires "https://github.com/ThomasTJdev/httpbeast_fork >= 0.4.2"
else:
requires "https://github.com/ThomasTJdev/httpbeast_fork >= 0.4.0"

task test, "Runs the test suite.":
when NimMajor >= 2:
# Due to tests/nim-in-action-code/Chapter7
exec "nimble install -y [email protected]"
exec "nimble install -y asynctools@#0e6bdc3ed5bae8c7cc9"
exec "nim c -r tests/tester"
1 change: 1 addition & 0 deletions jester/private/utils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type
maxBody*: int
futureErrorHandler*: proc (fut: Future[void]) {.closure, gcsafe.}
numThreads*: int # Only available with Httpbeast (`useHttpBeast = true`)
startup*: proc () {.closure, gcsafe.} # Only available with Httpbeast (`useHttpBeast = true`)

JesterError* = object of Exception

Expand Down
59 changes: 47 additions & 12 deletions jester/request.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import uri, cgi, tables, logging, strutils, re, options
from sequtils import map

import jester/private/utils
import private/utils

when useHttpBeast:
import httpbeast except Settings
Expand Down Expand Up @@ -93,28 +94,62 @@ proc ip*(req: Request): string =

proc params*(req: Request): Table[string, string] =
## Parameters from the pattern and the query string.
##
## Note that this doesn't allow for duplicated keys (it simply returns the last occuring value)
## Use `paramValuesAsSeq` if you need multiple values for a key
if req.patternParams.isSome():
result = req.patternParams.get()
else:
result = initTable[string, string]()

when useHttpBeast:
let query = req.req.path.get("").parseUri().query
var queriesToDecode: seq[string] = @[]
queriesToDecode.add query(req)

let contentType = req.headers.getOrDefault("Content-Type")
if contentType.startswith("application/x-www-form-urlencoded"):
queriesToDecode.add req.body

for query in queriesToDecode:
try:
for key, val in cgi.decodeData(query):
result[key] = decodeUrl(val)
except CgiError:
logging.warn("Incorrect query. Got: $1" % [query])

proc paramValuesAsSeq*(req: Request): Table[string, seq[string]] =
## Parameters from the pattern and the query string.
##
## This allows for duplicated keys in the query (in contrast to `params`)
if req.patternParams.isSome():
let patternParams: Table[string, string] = req.patternParams.get()
var patternParamsSeq: seq[(string, string)] = @[]
for key, val in pairs(patternParams):
patternParamsSeq.add (key, val)

# We are not url-decoding the key/value for the patternParams (matches implementation in `params`
result = sequtils.map(patternParamsSeq,
proc(entry: (string, string)): (string, seq[string]) =
(entry[0], @[entry[1]])
).toTable()
else:
let query = req.req.url.query
result = initTable[string, seq[string]]()

try:
for key, val in cgi.decodeData(query):
result[key] = decodeUrl(val)
except CgiError:
logging.warn("Incorrect query. Got: $1" % [query])
var queriesToDecode: seq[string] = @[]
queriesToDecode.add query(req)

let contentType = req.headers.getOrDefault("Content-Type")
if contentType.startswith("application/x-www-form-urlencoded"):
queriesToDecode.add req.body

for query in queriesToDecode:
try:
parseUrlQuery(req.body, result)
except:
logging.warn("Could not parse URL query.")
for key, value in cgi.decodeData(query):
if result.hasKey(key):
result[key].add value
else:
result[key] = @[value]
except CgiError:
logging.warn("Incorrect query. Got: $1" % [query])

proc formData*(req: Request): MultiData =
let contentType = req.headers.getOrDefault("Content-Type")
Expand Down
13 changes: 13 additions & 0 deletions readme.markdown
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# FORK OF Jester

This repo with jester is updated to work with Nim version 2.0

**Reason:**
* Pull requests not being merged (or closed) in main repo
* Dependency to `httpbeast` does not support Nim 2.0
* Full support for Nim 2.0

The minimum Nim version the fork supports is 1.6.18. Test are done with
Nim 1.6.18 and stable (2.x.x) versions.


# 🃏 Jester 🃏

The sinatra-like web framework for Nim. Jester provides a DSL for quickly
Expand Down
9 changes: 9 additions & 0 deletions tests/alltest.nim
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,12 @@ routes:
setHeader(responseHeaders, "foo", "foo")
setHeader(responseHeaders, "bar", "bar")
resp Http200, {"Content-Type": "text/plain"}, "result"

get "/redirectDefault":
redirect("/")

get "/redirect301":
redirect("/", httpStatusCode = Http301)

get "/redirect302":
redirect("/", httpStatusCode = Http302)
41 changes: 41 additions & 0 deletions tests/issue247.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from std/cgi import decodeUrl
from std/strformat import fmt
from std/strutils import join
import jester

settings:
port = Port(5454)
bindAddr = "127.0.0.1"

proc formatParams(params: Table[string, string]): string =
result = ""
for key, value in params.pairs:
result.add fmt"{key}: {value}"

proc formatSeqParams(params: Table[string, seq[string]]): string =
result = ""
for key, values in params.pairs:
let value = values.join ","
result.add fmt"{key}: {value}"

routes:
get "/":
resp Http200
get "/params":
let params = params request
resp formatParams params
get "/params/@val%23ue":
let params = params request
resp formatParams params
post "/params/@val%23ue":
let params = params request
resp formatParams params
get "/multi":
let params = paramValuesAsSeq request
resp formatSeqParams(params)
get "/@val%23ue":
let params = paramValuesAsSeq request
resp formatSeqParams(params)
post "/@val%23ue":
let params = paramValuesAsSeq request
resp formatSeqParams(params)
1 change: 0 additions & 1 deletion tests/nim-in-action-code
Submodule nim-in-action-code deleted from f81230
11 changes: 11 additions & 0 deletions tests/nim-in-action-code copy/Chapter7/Tweeter/Tweeter.nimble
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Package

version = "0.1.0"
author = "Dominik Picheta"
description = "A simple Twitter clone developed in Nim in Action."
license = "MIT"

# Dependencies

requires "nim >= 0.13.1"
requires "jester >= 0.0.1"
Loading