Code Monkey home page Code Monkey logo

perfect-httpserver's People

Contributors

123flo321 avatar chizcake avatar iamjono avatar kjessup avatar mlilback avatar nerdo avatar rockfordwei avatar rodrigue-h avatar taplin avatar tengyifei avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

perfect-httpserver's Issues

HTTPServer.documentRoot file handler should allow filters

The static file handler which setting the HTTPServer.documentRoot property adds does not indicate "allowResponseFilters" as true. This can conflict with the content compression filter.

The static file handler should have allowResponseFilters = true.

Encodes Incorrect

Hi, the documetions say :

/// Encodes the Dictionary as a JSON string and converts that to a UTF-8 encoded [UInt8]
func setBody(json: [String:Any]) throws

and my code:

  let json: NSMutableDictionary = ["content": "观自在菩萨,行深般若波罗蜜多时,照见五蕴皆空,度一切苦厄。舍利子,色不异空,空不异色;色即是空,空即是色。受、想、行、识,亦复如是。舍利子,是诸法空相,不生不灭,不垢不净,不增不减,是故空中无色,无受、想、行、识;无眼、耳、鼻、舌、身、意;无色、声、香、味、触、法;无眼界,乃至无意识界;无无明,亦无无明尽;乃至无老死,亦无老死尽。无苦、集、灭、道,无智亦无得。以无所得故,菩提萨埵,依般若波罗蜜多故,心无罣碍,无罣碍故,无有恐怖,远离颠倒梦想,究竟涅槃。三世诸佛,依般若波罗蜜多故,得阿耨多罗三藐三菩提。故知般若波罗蜜多,是大神咒,是大明咒,是无上咒,是无等等咒,能除一切苦,真实不虚。故说般若波罗蜜多咒,即说咒曰:“揭谛、揭谛,波罗揭谛,波罗僧揭谛,菩提萨婆诃。”\n\n आर्यावलोकितेश्वरो बोधिसत्त्वो गंभीरायां प्रज्ञापारमितायां चर्यां चरमाणो व्यवलोकयति स्म । पंचस्कन्धाः । तांश्च स्वभावशून्यान्पश्यति स्म । इह शारिपुत्र रूपं शून्यता शून्यतैव रूपं रूपान्न पृथक्शून्यता शून्यताया न पृथग्रूपं यद्रूपं सा शून्यता या शून्यता तद्रूपं । एवमेव वेदनासंज्ञासंस्कारविज्ञानानि । इह शारिपुत्र सर्वधर्माः शून्यतालक्षणा अनुत्पन्ना अनिरुद्धा अमला न विमला नोना न परिपूर्णाः । तस्माच्छारिपुत्र शून्यतायां न रूपं न वेदना न संज्ञा न संस्कारा न विज्ञानानि । न चक्षुःश्रोत्रघ्राणजिह्वाकायमनांसी । न रूपशब्दगंधरसस्प्रष्टव्यधर्माः । न चक्षुर्धातुर्यावन्न मनोविज्ञानधातुः । न विद्या नाविद्या न विद्याक्षयो नाविद्याक्षयो यावन्न जरामरणं न जरामरणक्षयो न दुःखसमुदयनिरोधमार्गा न ज्ञानं न प्राप्तिः ॥ तस्मादप्राप्तित्वाद्बोधिसत्त्वाणां प्रज्ञापारमितामाश्रित्य विहरत्यचित्तावरणः । चित्तावरणनास्तित्वादत्रस्तो विपर्यासातिक्रान्तो निष्ठनिर्वाणः ।। त्र्यध्वव्यवस्थिताः सर्वबुद्धाः प्रज्ञापारमितामाश्रित्यानुत्तरां सम्यक्सम्बोधिमभिसंबुद्धाः ।। तस्माज्ज्ञातव्यं प्रज्ञापारमिता महामन्त्रो महाविद्यामन्त्रो ऽनुत्तरमन्त्रो ऽसमसममन्त्रः सर्वदुःखप्रशमनः । सत्यममिथ्यत्वात् । प्रज्ञपारमितायामुक्तो मन्त्रः । तद्यथा गते गते पारगते पारसंगते बोधि स्वाहा ।। इति प्रज्ञापारमिताहृदयं समाप्तम् \n\n", "age": 38,"height": 158]

 do {
        try response.setBody(json: json)
                .completed()

    }catch {

    }

i run it,the result:
https://www.wenjian.ml/WechatIMG949.jpeg

Api: http://frp1991.ml:8080/api/user

thanks.

LaunchFailure(message: "Server localhost:8181 - 1:Operation not permitted

when I run perfect server on Mac OS ,

LaunchFailure(message: "Server localhost:8181 - 1:Operation not permitted /Users/xxx/Library/Developer/Xcode/DerivedData/KubeWorkbench-amuiunavyuuwkvbhlqolywapxtmf/SourcePackages/checkouts/Perfect-Net/Sources/PerfectNet/Net.swift bind(port:address:) 273", configuration: PerfectHTTPServer.HTTPServer.Server(name: "localhost", port: 8181, address: "::", routes: PerfectHTTP.Routes(routes: [PerfectHTTP.Route(methods: [GET], uri: "/", handler: (Function)), PerfectHTTP.Route(methods: [GET], uri: "/**", handler: (Function))], moreRoutes: [], baseUri: "", handler: nil), requestFilters: [], responseFilters: [(PerfectHTTPServer.HTTPFilter.(unknown context at $1004668e8).(unknown context at $10046697c).CompressResponse(compressTypes: [/], ignoreTypes: [image/, video/, audio/*]), PerfectHTTP.HTTPFilterPriority.high)], tlsConfig: nil))
2020-11-22 08:28:11.512314+0800 KubeWorkbench[53616:962125] Metal API Validation Enabled

Content-Length header is incorrect for some responses generated with .setBody()

We're seeing an issue with Perfect-HTTP 3.1.6 where the Content-Length header is set incorrectly for some limited amount of responses (generated using response.setBody() ). In each case the reported content length is larger by 8 (for an empty response Content-Length was 8, for an empty json "{}" the reported length was 10).

We use the following code for success and failure cases, unfortunately the issue is very sporadic, hard to reproduce but nonetheless worrisome and trips up the client parsing.

response.setBody(string: error).completed(status: .badRequest)

try response.setBody(json: responseData)
if let responseETag = responseETag {
    response.addHeader(.eTag, value: "\"\(responseETag)\"")
}
response.completed(status: toReponseStatus())

Example client parsing issue:

NetworkManager.swift:141 WARNING: > Server Request Error: Response could not be serialized, input data was nil or zero length.
NetworkManager.swift:142 WARNING: > Request: GET (redacted)
NetworkManager.swift:143 WARNING: > Headers:
NetworkManager.swift:147 WARNING: > Body: 
NetworkManager.swift:148 WARNING: > Response: 200
NetworkManager.swift:149 WARNING: > Headers:
NetworkManager.swift:151 WARNING: >   Date: (redacted)
NetworkManager.swift:151 WARNING: >   Server: (redacted)
NetworkManager.swift:151 WARNING: >   Content-Encoding: deflate
NetworkManager.swift:151 WARNING: >   x-request-id: (redacted)
NetworkManager.swift:151 WARNING: >   Content-Length: 8
NetworkManager.swift:153 WARNING: > Body: (empty)
NetworkManager.swift:688 WARNING: Request failed: responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength)

Websocket doesn't work with compression

Thank you for a great framework.

Problem

My websocket code doesn't work, when I use compression.

My compression filter look like this:

let filter = try PerfectHTTPServer.HTTPFilter.contentCompression(data: [:])
setResponseFilters([(filter, .high)])

When I disable the compression code then websockets works fine.

I think there is a problem with websockets and/or compression.

Here is how the request/response look like, when I enable/disable the compression code.

Compression enabled - doesn't work

Request

GET /v1/run/share/demo HTTP/1.1
Host: localhost:8181
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://localhost:8181
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,da;q=0.8,pt-BR;q=0.7,pt;q=0.6
Cookie: VisualOpus-session=2A37E8F2-33CE-4B2E-8CE2-C4CABB884F35; CSRF-TOKEN=678F03DF-171D-4A3B-BD7D-6D386A320F9D
Sec-WebSocket-Key: NrZzVuYp4EutnVTGJ7dgQQ==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Protocol: v1

���ìçT|�°1�¿�7���t/�� ���8_©�&��

Response

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: qYA5nStEaTeirER6oXp7FJQcVrY=
Sec-WebSocket-Protocol: v1
Content-Encoding: deflate
Content-Length: 8
Set-Cookie: VisualOpus-session=2A37E8F2-33CE-4B2E-8CE2-C4CABB884F35;expires=Fri, 15-Jun-2018 17:08:05 GMT; path=/; domain=localhost; HttpOnly; sameSite=Lax
Set-Cookie: CSRF-TOKEN=678F03DF-171D-4A3B-BD7D-6D386A320F9D;expires=Fri, 15-Jun-2018 17:08:05 GMT; path=/; domain=localhost; HttpOnly; sameSite=Lax

Compression disabled - works correct

Request

GET /v1/run/share/demo HTTP/1.1
Host: localhost:8181
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://localhost:8181
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,da;q=0.8,pt-BR;q=0.7,pt;q=0.6
Cookie: VisualOpus-session=2A37E8F2-33CE-4B2E-8CE2-C4CABB884F35; CSRF-TOKEN=678F03DF-171D-4A3B-BD7D-6D386A320F9D
Sec-WebSocket-Key: KBOCil4S9o9WzcqkdlM1Ng==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Protocol: v1

��Ý#@�

Response

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: zK/ACrzzttER79e5U3Il2DqxrQA=
Sec-WebSocket-Protocol: v1
Content-Length: 0
Set-Cookie: VisualOpus-session=2A37E8F2-33CE-4B2E-8CE2-C4CABB884F35;expires=Fri, 15-Jun-2018 17:09:30 GMT; path=/; domain=localhost; HttpOnly; sameSite=Lax
Set-Cookie: CSRF-TOKEN=678F03DF-171D-4A3B-BD7D-6D386A320F9D;expires=Fri, 15-Jun-2018 17:09:30 GMT; path=/; domain=localhost; HttpOnly; sameSite=Lax

��MESSAGE: I'm a message 0��PROGRESS: 0.00% 0��PROGRESS: 2.56% 1��PROGRESS: 5.13% 2��PROGRESS: 7.69% 3��PROGRESS: 10.26% 4��PROGRESS: 12.82% 5��PROGRESS: 15.38% 6��PROGRESS: 17.95% 7��PROGRESS: 20.51% 8��PROGRESS: 23.08% 9��MESSAGE: I'm a message 10��PROGRESS: 25.64% 10��PROGRESS: 28.21% 11��PROGRESS: 30.77% 12��PROGRESS: 33.33% 13��PROGRESS: 35.90% 14��PROGRESS: 38.46% 15��PROGRESS: 41.03% 16��PROGRESS: 43.59% 17��PROGRESS: 46.15% 18��PROGRESS: 48.72% 19��MESSAGE: I'm a message 20��PROGRESS: 51.28% 20��PROGRESS: 53.85% 21��PROGRESS: 56.41% 22��PROGRESS: 58.97% 23��PROGRESS: 61.54% 24��PROGRESS: 64.10% 25��PROGRESS: 66.67% 26��PROGRESS: 69.23% 27��PROGRESS: 71.79% 28��PROGRESS: 74.36% 29��MESSAGE: I'm a message 30��PROGRESS: 76.92% 30��PROGRESS: 79.49% 31��PROGRESS: 82.05% 32��PROGRESS: 84.62% 33��PROGRESS: 87.18% 34��PROGRESS: 89.74% 35��PROGRESS: 92.31% 36��PROGRESS: 94.87% 37��PROGRESS: 97.44% 38��PROGRESS: 100.00% 39�

Browser

Chrome console output

Websocket connection to 'ws://localhost:8181/v1/run/share/demo' failed: Invalid frame header

Firefox console output

The connection to ws://localhost:8181/v1/run/share/demo was interrupted while the page was loading.

Setup

Xcode 9.4

macOS 10.13.4 High Sierra

Chrome 66.0.3359.181 (Official Build) (64-bit)

Firefox 60.0.2 (64-bit)

Solutions

Solution A

Make the websocket/compression code work together.

Solution B

Make it possible to enable/disable compression per route.

Can not build on Ubuntu18.04 with Swift 5.0.1.

System: Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.18.0-18-generic x86_64)

Swift Version:
Swift version 5.0.1 (swift-5.0.1-RELEASE)
Target: x86_64-unknown-linux-gnu

git clone https://github.com/PerfectlySoft/PerfectTemplate.git
cd PerfectTemplate
swift run

And occur some error.

[1/6] Compiling Swift Module 'PerfectCrypto' (7 sources)
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/ByteIO.swift:64:45: error: use of undeclared type 'BIO'
typealias BIOPointer = UnsafeMutablePointer?
^~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/ByteIO.swift:78:48: error: use of undeclared type 'BIO_METHOD'
fileprivate init(method: UnsafeMutablePointer<BIO_METHOD>?) {
^~~~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/ByteIO.swift:232:11: error: initializer does not override a designated initializer from its superclass
override init(bio: BIOPointer) {

/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/OpenSSLInternal.swift:281:25: error: use of undeclared type 'EVP_MD'
var evp: UnsafePointer<EVP_MD> {
^~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/OpenSSLInternal.swift:408:25: error: use of undeclared type 'EVP_CIPHER'
var evp: UnsafePointer<EVP_CIPHER> {
^~~~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/ByteIO.swift:64:45: error: use of undeclared type 'BIO'
typealias BIOPointer = UnsafeMutablePointer?
^~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/ByteIO.swift:78:48: error: use of undeclared type 'BIO_METHOD'
fileprivate init(method: UnsafeMutablePointer<BIO_METHOD>?) {
^~~~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/Keys.swift:35:35: error: use of undeclared type 'EVP_PKEY'
init(_ key: UnsafeMutablePointer<EVP_PKEY>?) {
^~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/Keys.swift:31:33: error: use of undeclared type 'EVP_PKEY'
let pkey: UnsafeMutablePointer<EVP_PKEY>?
^~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/Keys.swift:35:35: error: use of undeclared type 'EVP_PKEY'
init(_ key: UnsafeMutablePointer<EVP_PKEY>?) {
^~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/Keys.swift:71:32: error: use of undeclared type 'EVP_PKEY'
init(kp: UnsafeMutablePointer<EVP_PKEY>?) {
^~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/Keys.swift:80:32: error: use of undeclared type 'EVP_PKEY'
var kp: UnsafeMutablePointer<EVP_PKEY>? = nil
^~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/ByteIO.swift:64:45: error: use of undeclared type 'BIO'
typealias BIOPointer = UnsafeMutablePointer?
^~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/Keys.swift:198:32: error: use of undeclared type 'EVP_PKEY'
var kp: UnsafeMutablePointer<EVP_PKEY>?
^~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/ByteIO.swift:78:48: error: use of undeclared type 'BIO_METHOD'
fileprivate init(method: UnsafeMutablePointer<BIO_METHOD>?) {
^~~~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/OpenSSLInternal.swift:32:3: error: use of unresolved identifier 'ERR_load_crypto_strings'
ERR_load_crypto_strings()
^~~~~~~~~~~~~~~~~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/OpenSSLInternal.swift:34:3: error: use of unresolved identifier 'OPENSSL_add_all_algorithms_conf'
OPENSSL_add_all_algorithms_conf()
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/OpenSSLInternal.swift:36:20: error: use of unresolved identifier 'CRYPTO_num_locks'; did you mean 'CRYPTO_dynlock'?
for i in 0..<Int(CRYPTO_num_locks()) {
^~~~~~~~~~~~~~~~
CRYPTO_dynlock
COpenSSL.CRYPTO_dynlock:1:15: note: 'CRYPTO_dynlock' declared here
public struct CRYPTO_dynlock {
^
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/OpenSSLInternal.swift:49:3: error: use of unresolved identifier 'CRYPTO_set_locking_callback'
CRYPTO_set_locking_callback(lockingCallback)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/OpenSSLInternal.swift:59:3: error: use of unresolved identifier 'CRYPTO_set_id_callback'
CRYPTO_set_id_callback(threadIdCallback)
^~~~~~~~~~~~~~~~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/OpenSSLInternal.swift:275:30: error: use of undeclared type 'BIO'
func bio() -> UnsafePointer? {
^~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/OpenSSLInternal.swift:281:25: error: use of undeclared type 'EVP_MD'
var evp: UnsafePointer<EVP_MD> {
^~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/OpenSSLInternal.swift:408:25: error: use of undeclared type 'EVP_CIPHER'
var evp: UnsafePointer<EVP_CIPHER> {
^~~~~~~~~~
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/OpenSSLInternal.swift:304:19: error: use of unresolved identifier 'EVP_MD_CTX_create'
guard let ctx = EVP_MD_CTX_create() else {
^~~~~~~~~~~~~~~~~
COpenSSL.EVP_MD_CTX_free:1:13: note: did you mean 'EVP_MD_CTX_free'?
public func EVP_MD_CTX_free(_ ctx: OpaquePointer!)
^
COpenSSL.EVP_MD_CTX_reset:1:13: note: did you mean 'EVP_MD_CTX_reset'?
public func EVP_MD_CTX_reset(_ ctx: OpaquePointer!) -> Int32
^
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/OpenSSLInternal.swift:348:19: error: use of unresolved identifier 'EVP_MD_CTX_create'
guard let ctx = EVP_MD_CTX_create() else {
^~~~~~~~~~~~~~~~~
COpenSSL.EVP_MD_CTX_free:1:13: note: did you mean 'EVP_MD_CTX_free'?
public func EVP_MD_CTX_free(_ ctx: OpaquePointer!)
^
COpenSSL.EVP_MD_CTX_reset:1:13: note: did you mean 'EVP_MD_CTX_reset'?
public func EVP_MD_CTX_reset(_ ctx: OpaquePointer!) -> Int32
^
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/OpenSSLInternal.swift:308:4: error: use of unresolved identifier 'EVP_MD_CTX_destroy'
EVP_MD_CTX_destroy(ctx)
^~~~~~~~~~~~~~~~~~
COpenSSL.EVP_MD_CTX_ctrl:1:13: note: did you mean 'EVP_MD_CTX_ctrl'?
public func EVP_MD_CTX_ctrl(_ ctx: OpaquePointer!, _ cmd: Int32, _ p1: Int32, _ p2: UnsafeMutableRawPointer!) -> Int32
^
COpenSSL.EVP_MD_CTX_reset:1:13: note: did you mean 'EVP_MD_CTX_reset'?
public func EVP_MD_CTX_reset(_ ctx: OpaquePointer!) -> Int32
^
/home/tan/桌面/pfubuntu/PerfectTemplate/.build/checkouts/Perfect-Crypto/Sources/PerfectCrypto/OpenSSLInternal.swift:352:4: error: use of unresolved identifier 'EVP_MD_CTX_destroy'
EVP_MD_CTX_destroy(ctx)
^~~~~~~~~~~~~~~~~~
COpenSSL.EVP_MD_CTX_ctrl:1:13: note: did you mean 'EVP_MD_CTX_ctrl'?
public func EVP_MD_CTX_ctrl(_ ctx: OpaquePointer!, _ cmd: Int32, _ p1: Int32, _ p2: UnsafeMutableRawPointer!) -> Int32
^
COpenSSL.EVP_MD_CTX_reset:1:13: note: did you mean 'EVP_MD_CTX_reset'?
public func EVP_MD_CTX_reset(_ ctx: OpaquePointer!) -> Int32
^

Not possible to enumerate multiple instances of a HTTPResponse header.

When a HTTPResponse contains multiple headers, it is not possible to write a response filter that re-writes those headers, as HTTPResponse.header(_ named: HTTPResponseHeader.Name) -> String? only exposes the first instance of the header.

This is a problem for example when one wants to re-write cookies in a response filter, as there could be multiple Set-Cookie headers in the response.

Likewise, it is not possible to delete a header in a response filter.

Unable to configure HTTPS using wild card certificate

My company uses a domain wild card certificate from GoDaddy. This allows HTTPS on our main domain and any second level domains with the same certificate.

I'm very new to Perfect, so I may have made an error. That said, I followed the example code here almost to the letter:

https://github.com/PerfectExamples/HTTPS-Configuration/blob/master/Sources/main.swift

Here is my altered version:

import PerfectLib
import PerfectHTTP
import PerfectHTTPServer

// This 'handler' function serves port 80.
func handler80(data: [String:Any]) throws -> RequestHandler {
    return {
        request, response in
        response.appendBody(string: "<html><title>Hello, world!</title><body>Hello, world! Port 80</body></html>")
        // Ensure that response.completed() is called when your processing is done.
        response.completed()
    }
}

// This 'handler' function serves port 443.
func handler443(data: [String:Any]) throws -> RequestHandler {
    return {
        request, response in
        response.appendBody(string: "<html><title>Hello, world!</title><body>Hello, world! Port 443</body></html>")
        response.completed()
    }
}

let confData = [
    "servers": [
        // Serves Port 80
        [
            "name":"bushland.logicalbuilding.net",
            "port":80,
            "routes":[
                ["method":"get", "uri":"/", "handler":handler80],
                ["method":"get", "uri":"/**", "handler":PerfectHTTPServer.HTTPHandler.staticFiles,
                 "documentRoot":"./webroot",
                 "allowResponseFilters":true]
            ],
            "filters":[
                [
                    "type":"response",
                    "priority":"high",
                    "name":PerfectHTTPServer.HTTPFilter.contentCompression,
                    ]
            ]
        ],
        // Serves Port 443.
        [
            "name":"bushland.logicalbuilding.net",
            "port":443,
            "routes":[
                ["method":"get", "uri":"/", "handler":handler443],
                ["method":"get", "uri":"/**", "handler":PerfectHTTPServer.HTTPHandler.staticFiles,
                 "documentRoot":"./webroot",
                 "allowResponseFilters":true]
            ],
            "filters":[
                [
                    "type":"response",
                    "priority":"high",
                    "name":PerfectHTTPServer.HTTPFilter.contentCompression,
                    ]
            ],
            "tlsConfig":[
                "certPath": "/Users/Radagan/Development/Perfect/Certs/167af3a72faa08c9.crt",
                "verifyMode": "peer",
                "caCertPath": "/Users/Radagan/Development/Perfect/Certs/gd_bundle-g2-g1.crt"
            ]
        ]
    ]
]

do {
    // Launch the servers based on the configuration data.
    try HTTPServer.launch(configurationData: confData)
}
catch {
    fatalError("\(error)") // fatal error launching one of the servers
}

And the error:

Thread 1: Fatal error: LaunchFailure(message: "Server bushland.logicalbuilding.net:443 - networkError(0, \"Error setting clientCA : error:00000000:lib(0):func(0):reason(0)\")", configuration: PerfectHTTPServer.HTTPServer.Server(name: "bushland.logicalbuilding.net", port: 443, address: "0.0.0.0", routes: PerfectHTTP.Routes(routes: [PerfectHTTP.Route(methods: [GET], uri: "/", handler: (Function)), PerfectHTTP.Route(methods: [GET], uri: "/**", handler: (Function))], moreRoutes: [], baseUri: "", handler: nil), requestFi...

I've checked that DNS has the correct IP and that sort of thing. This appears to me to be an issue with the certificate being a wild card. Unfortunately, that's the cert I have to use. I really want to use Perfect and Swift for our test server, any Ideas?

Suggestions on doing a clean shutdown?

I have a handler for CTRL-C:

import Dispatch

signal(SIGINT, SIG_IGN) // prevent termination

var running = false
let sigintSrc = DispatchSource.makeSignalSource(signal: SIGINT, queue: .main)
sigintSrc.setEventHandler {
    if !running {
        print("Already shutting down or not yet started")
    } else {
        running = false
        print("Clean shutdown initiated")
        server.stop()
    }
}
sigintSrc.resume()

running = true
try server.start()

print("Server stopped")

I would like to wait on all currently pending handlers. I notice the handler queue (netHandleQueue) is public, but without some DispatchGrouping I'm not sure there's a good way to wait on all the handlers to complete.

Any suggestions? Thanks for your time.

Porting to Swift 5

PerfectLib is ported to Swift 5 but this one is not. I can compile with a bunch of warnings. Apparently 100% of the warnings are related to unsafe pointers. Do you guy have plans to make this?

Can't get post parameters by request.param(name: "xxxx")

Here is my code

static func signIn(request: HTTPRequest, resp: HTTPResponse) {

    var pwd = request.param(name: "pwd")
    var email = request.param(name: "email")
    
    defer {
        resp.completed()
    }

    guard pwd != nil && email != nil else {
        resp.appendBody(string: Response.JSON(.lackParameters))
        return
    }
}

Here is my request

POST /account/signIn HTTP/1.1
Host: 192.168.118.63:8181
Content-Type: application/json
Cookie: CSRF-TOKEN=BF6E8C61-8D4C-4501-BBD1-BFC223F997BF; PerfectSession=11279782-E82C-43BE-B986-71EEF1FB84E7
Accept: */*
User-Agent: GRedHeart5/1.0 (com.shabi.GRedHeart5; build:1; iOS 10.3.3) Alamofire/4.8.0
Accept-Language: zh-Hans-CN;q=1.0
Content-Length: 41
Accept-Encoding: gzip;q=1.0, compress;q=0.5
Connection: keep-alive

{"pwd":"666666","email":"[email protected]"}

Here is post parameters in request.postParams data structure

▿ 1 element
    ▿ 0 : 2 elements
- .0 : "{\"pwd\":\"666666\",\"email\":\"[email protected]\"}"
- .1 : ""

why I can't get post parameters by this method

public extension HTTPRequest {
    
    /// Returns the first GET or POST parameter with the given name.
    /// Returns the supplied default value if the parameter was not found.
    public func param(name: String, defaultValue: String? = nil) -> String? {
        for p in self.queryParams
            where p.0 == name {
                return p.1
        }
        for p in self.postParams
            where p.0 == name {
                return p.1
        }
        return defaultValue
    }
}

Maybe I prefer ask you why design like this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.