Skip to content

Commit

Permalink
tech debt: refactor the URL router, potentially resolve #236, log all…
Browse files Browse the repository at this point in the history
… HTTP headers instead of just a subset
  • Loading branch information
tayloraswift committed May 25, 2024
1 parent ef5f94c commit 7b15b7b
Show file tree
Hide file tree
Showing 36 changed files with 1,471 additions and 1,423 deletions.
2 changes: 2 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ let package:Package = .init(
.target(name: "HTTP"),
.target(name: "IP"),
.target(name: "UA"),
.target(name: "URI"),

.product(name: "HTML", package: "swift-dom"),
.product(name: "Atomics", package: "swift-atomics"),
Expand Down Expand Up @@ -531,6 +532,7 @@ let package:Package = .init(
.target(name: "MarkdownRendering"),
.target(name: "Media"),
.target(name: "UA"),
.target(name: "URI"),
]),

.target(name: "UnidocQueries",
Expand Down
38 changes: 11 additions & 27 deletions Sources/HTTPServer/HTTP.ServerIntegralRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,18 @@ import IP
import NIOCore
import NIOHPACK
import NIOHTTP1
import URI

extension HTTP
{
public
protocol ServerIntegralRequest:Sendable
{
init?(get path:String,
headers:borrowing HPACKHeaders,
origin:IP.Origin)
init?(get uri:URI, headers:HPACKHeaders, origin:IP.Origin)
init?(get uri:URI, headers:HTTPHeaders, origin:IP.Origin)

init?(get path:String,
headers:borrowing HTTPHeaders,
origin:IP.Origin)

init?(post path:String,
headers:borrowing HPACKHeaders,
origin:IP.Origin,
body:borrowing [UInt8])

init?(post path:String,
headers:borrowing HTTPHeaders,
origin:IP.Origin,
body:consuming [UInt8])
init?(post path:URI, headers:HPACKHeaders, origin:IP.Origin, body:borrowing [UInt8])
init?(post path:URI, headers:HTTPHeaders, origin:IP.Origin, body:borrowing [UInt8])
}
}
extension HTTP.ServerIntegralRequest
Expand All @@ -36,12 +25,10 @@ extension HTTP.ServerIntegralRequest
/// Servers that expect to handle a lot of HTTP/1.1 GET requests should override this with
/// a more efficient implementation.
@inlinable public
init?(get path:String,
headers:borrowing HTTPHeaders,
origin:IP.Origin)
init?(get uri:URI, headers:HTTPHeaders, origin:IP.Origin)
{
self.init(get: path,
headers: .init(httpHeaders: copy headers),
self.init(get: uri,
headers: .init(httpHeaders: headers),
origin: origin)
}

Expand All @@ -51,13 +38,10 @@ extension HTTP.ServerIntegralRequest
/// Servers that expect to handle a lot of HTTP/1.1 POST requests should override this with
/// a more efficient implementation.
@inlinable public
init?(post path:String,
headers:borrowing HTTPHeaders,
origin:IP.Origin,
body:consuming [UInt8])
init?(post uri:URI, headers:HTTPHeaders, origin:IP.Origin, body:borrowing [UInt8])
{
self.init(post: path,
headers: .init(httpHeaders: copy headers),
self.init(post: uri,
headers: .init(httpHeaders: headers),
origin: origin,
body: body)
}
Expand Down
18 changes: 16 additions & 2 deletions Sources/HTTPServer/HTTP.ServerLoop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import NIOHTTP1
import NIOHTTP2
import NIOPosix
import NIOSSL
import URI

extension NIOHTTP2Handler.AsyncStreamMultiplexer:@unchecked Sendable
{
Expand Down Expand Up @@ -323,13 +324,19 @@ extension HTTP.ServerLoop
as _:Authority.Type) async throws -> HTTP.ServerResponse
where Authority:HTTP.ServerAuthority
{
guard let path:URI = .init(h1.uri)
else
{
return .resource("Malformed URI", status: 400)
}

switch h1.method
{
case .HEAD:
fallthrough

case .GET:
if let request:IntegralRequest = .init(get: h1.uri,
if let request:IntegralRequest = .init(get: path,
headers: h1.headers,
origin: origin)
{
Expand Down Expand Up @@ -377,7 +384,7 @@ extension HTTP.ServerLoop
}
}

if let request:IntegralRequest = .init(post: h1.uri,
if let request:IntegralRequest = .init(post: path,
headers: h1.headers,
origin: origin,
body: /* consume */ body) // https://github.com/apple/swift/issues/71605
Expand Down Expand Up @@ -578,6 +585,13 @@ extension HTTP.ServerLoop
return .resource("Missing headers", status: 400)
}

guard
let path:URI = .init(path)
else
{
return .resource("Malformed URI", status: 400)
}

switch method
{
case "HEAD":
Expand Down
7 changes: 4 additions & 3 deletions Sources/HTTPServer/HTTP.ServerStreamedRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@ import IP
import NIOCore
import NIOHPACK
import NIOHTTP1
import URI

extension HTTP
{
public
protocol ServerStreamedRequest:Sendable
{
init?(put path:String, headers:borrowing HPACKHeaders)
init?(put path:URI, headers:borrowing HPACKHeaders)

init?(put path:String, headers:borrowing HTTPHeaders)
init?(put path:URI, headers:borrowing HTTPHeaders)
}
}
extension HTTP.ServerStreamedRequest
{
@inlinable public
init?(put path:String, headers:borrowing HTTPHeaders)
init?(put path:URI, headers:borrowing HTTPHeaders)
{
self.init(put: path, headers: .init(httpHeaders: copy headers))
}
Expand Down
26 changes: 0 additions & 26 deletions Sources/UnidocProfiling/HTTP.ProfileHeaders.swift

This file was deleted.

31 changes: 0 additions & 31 deletions Sources/UnidocProfiling/ServerTour.Request.swift

This file was deleted.

1 change: 1 addition & 0 deletions Sources/UnidocRecords/Building/Unidoc.BuildReport.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import BSON
import UnidocAPI

extension Unidoc
{
Expand Down
50 changes: 13 additions & 37 deletions Sources/UnidocRender/Unidoc.ServerRoot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import URI
extension Unidoc
{
@frozen public
enum ServerRoot
enum ServerRoot:String, Sendable
{
case account
case admin
case api
case asset
case auth
case blog
case blog = "articles"
case docs
case docc
case help
Expand All @@ -23,11 +23,20 @@ extension Unidoc
case pdct
case realm
case really
case robots_txt = "robots.txt"
case sitemap_xml = "sitemap.xml"
case ssgc
case stats
case tags
case telescope
case user

/// Deprecated.
case guides
/// Deprecated.
case reference
/// Deprecated.
case sitemaps
}
}
extension Unidoc.ServerRoot
Expand All @@ -45,43 +54,10 @@ extension Unidoc.ServerRoot
extension Unidoc.ServerRoot:CustomStringConvertible
{
@inlinable public
var description:String { "/\(self.id)" }
}
extension Unidoc.ServerRoot:Identifiable
{
@inlinable public
var id:String
{
switch self
{
case .account: "account"
case .admin: "admin"
case .api: "api"
case .asset: "asset"
case .auth: "auth"
case .blog: "articles"
case .docs: "docs"
case .docc: "docc"
case .help: "help"
case .hist: "hist"
case .hook: "hook"
case .login: "login"
case .lunr: "lunr"
case .plugin: "plugin"
case .ptcl: "ptcl"
case .pdct: "pdct"
case .realm: "realm"
case .really: "really"
case .ssgc: "ssgc"
case .stats: "stats"
case .tags: "tags"
case .telescope: "telescope"
case .user: "user"
}
}
var description:String { "/\(self.rawValue)" }
}
extension Unidoc.ServerRoot
{
@inlinable public
var uri:URI { [.push(self.id)] }
var uri:URI { [.push(self.rawValue)] }
}
13 changes: 13 additions & 0 deletions Sources/UnidocServer/Administration/HTTP.Headers.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import HTTP
import NIOHTTP1
import NIOHPACK

extension HTTP
{
@frozen @usableFromInline
enum Headers:Equatable, Sendable
{
case http1_1(HTTPHeaders)
case http2(HPACKHeaders)
}
}
66 changes: 66 additions & 0 deletions Sources/UnidocServer/Administration/ServerTour.Request.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import HTML
import HTTP
import HTTPServer
import IP
import NIOHPACK
import URI

extension ServerTour
{
@frozen @usableFromInline
struct Request:Equatable, Sendable
{
var version:HTTP
var headers:HTTP.Headers
var origin:IP.Origin
var uri:URI

init(
version:HTTP,
headers:HTTP.Headers,
origin:IP.Origin,
uri:URI)
{
self.version = version
self.headers = headers
self.origin = origin
self.uri = uri
}
}
}
extension ServerTour.Request:HTML.OutputStreamable
{
@usableFromInline static
func += (dl:inout HTML.ContentEncoder, self:Self)
{
let uri:String = "\(self.uri)"

dl[.dt] = "Path"
dl[.dd] { $0[.a] { $0.href = "\(uri)" } = "\(uri)" }

dl[.dt] = "IP address"
dl[.dd] = "\(self.origin.address)"

switch self.headers
{
case .http1_1(let headers):
for (name, value):(String, String) in headers
{
dl[.dt] = name
dl[.dd] = value
}

case .http2(let headers):
for (name, value, _):(String, String, HPACKIndexing) in headers
{
if case ":"? = name.first
{
continue
}

dl[.dt] = name
dl[.dd] = value
}
}
}
}
Loading

0 comments on commit 7b15b7b

Please sign in to comment.