elliottminns / blackfire Goto Github PK
View Code? Open in Web Editor NEWA minimal, fast and unopinionated web framework for Swift
License: Apache License 2.0
A minimal, fast and unopinionated web framework for Swift
License: Apache License 2.0
Hello,
How about create module for project ?
There is no examples, and another information... not about swift build, and not about Xcode project create for adding this module to own project...
Please expand documentation :)
Here is a template to help you improve your readme: iOS-readme-template
It's for iOS but you can draw inspiration from it ๐
For both Blackfish and Echo, the Xcode deployment target is set to 10.11, which is unnecessarily restrictive. They both build fine when set to 10.10 or 10.9.
I was hoping to use blackfish as a local server for unit testing. It works fine if I launch it separately, but if I try to get XCTest to launch it in setUp()
I get a deadlock, even though server.listen() gets called inside a dispatch_async. Any ideas?
running ab -r -n 10000 -c 100 http://localhost:8080/
once is fine, but only 4.2k average RPS, but if you run it a second time, it hangs at 6k requests and never crashes or dies. I suspect that it's not letting go of clients fast enough.
Hi,
Because of used names in framework there is problem when we have to deal with ambiguous names. In my case where I want to use SwiftHTTP and Blackfish where in both is class Response
.
But we can't use Blackfish.Response
because there is declared class in Blackfish framework called 'Blackfish' so swift is complain that: 'Response' is not a member type of 'Blackfish'
Express provides middleware for things such as request body parsing and other key features. It would be advantageous if Blackfish also provided this so that these can be changed by the user if need be.
Be able to add middleware that can intercept any handlers before passing it on to its next handler
See http://expressjs.com/en/guide/writing-middleware.html for example
As File I/O is a key part of organising data on a Server, I propose that an asynchronous File I/O library be created, powered by the Echo event loop.
As with Node.js, files can be read and written to asynchronously to prevent Web Servers from blocking during these, sometimes long running, operations.
My proposal is to create a new package that blackfish will use, in order to create asynchronous file I/O operations.
I propose .NoContent (204) be added to the Status enum. 204 No Content should be used in place of 200 OK when nothing is returned (which is usually the case for PUT or DELETE requests).
With this method controller
https://github.com/nonameplum/blackfish-github-badges/blob/master/Sources/IndexController.swift#L16
I'm getting SIGABRT
for response.request
in line https://github.com/elliottminns/blackfish/blob/master/Sources/SocketServer.swift#L114
I forked you repo and changed unowned let
to weak var
to resolve my problem but I didn't fully catch why this happen.
I'm unclear on how to extract data from a post or put using this library; I seem to only find empty dictionaries. Could you add an example?
Thanks!
I have the following controller set up:
class StudentController: Controller {
private var students: [Student]
init(students: [Student]) {
self.students = students
}
func routes(router: Router) {
router.get("/", handler: list)
}
private func list(request: Request, response: Response) {
response.send(json: students.map { $0.toJSON() })
}
}
Method toJSON in class Student is as follows:
func toJSON() -> [String: Any] {
var json: [String: Any] = [:]
json["id"] = id // Int
json["name"] = name // String
json["enrollments"] = enrollments.map { $0.id } // [Int]
return json
}
Trying to GET this resource returns an empty string.
In the console, Blackfish outputs the following:
BlackFishTest listening on port 3000
[["id": 1, "name": "Steven", "enrollments": []], ["id": 2, "name": "Ray", "enrollments": []]]
Mirror for Array<Dictionary<String, protocol<>>>
What's wrong here?
I'm running the February 8 build on Ubuntu.
Handling multipart/form-data encoding is not currently supported for forms automatically, and must be called via a request.parseMultiPartFormData().
It would be interesting to have a form of Middleware that would allow the user to specify what they would like done with any automatic multipart form data that is uploaded, such as stored to the temporary folder etc
Request.body only contains a substring of the actually body. Perhaps this has to do with the way Content-Length is set?
What would we need to do to incorporate support for HTTPS?
It would help if you could document which specific Swift Dev-Snapshot you are using to test this as of right now.
Express uses events at significant parts to allow messages to return.
One of the key ones is an on-finished
event that is fired when a request is sent. Which is useful for giving the duration and status code of a response for logging purposes.
I propose to include app events and hooks that can add handlers to listen to these events.
The current events that I am initially planning to support are:
onFinish
onStart
Hi, I just found your project and it's interesting me. I'm expecting Swift will be used beyond iOS/OSX dev.
I read README.md first and got a little bit strange part.
In Controller section,
You define MyController
and in main.swift you added controller this
app.use(path: "/test", controller: Test())
I can't test your example since I'm having a problem to install Swift 2.2, but in my programming sense it's supposed to be
app.use(path: "/test", controller: MyController())
rather Test()
I think?
Could you check it out and if my guess is right I would be happy to make change.
Thanks,
Most modern API's required the ability to send out HTTP requests to other services.
Currently there aren't any other HTTP servers providing this, and for Blackfish to be a number one Web Server, it should have this functionality.
My proposal is that seeming though Echo is what is powering the Event Loop behind Blackfish, and given it's asynchronous nature, the Request library should also be powered by Echo and it's own repository. This means that it'll be reusable across other packages and will also be non-blocking.
My thought process is to use libcurl as the main driver and implement a wrapper in swift to open up this process. The best JSON parsing library I have currently found is Swift-PureJsonSerializer and I think would add a nice addition to the Requesting Library.
It would appear Public isn't being listened too, or able to view files in the Public folder
for example, https://github.com/Keloran/Blackfish-Site
import Blackfire
let app = Flame(type: .concurrent)
app.get("/data") { (request, response) in
print("query: \(request.query) ")
print("params: \(request.params) ")
print("path: \(request.path) ")
print("body: \(request.body) ")
response.send(html: "SOME")
}
app.start(port: 3000) { (result) in
switch result {
case .success:
print("Server started on port 3000")
case .failure(let error):
print("Server failed with error: \(error)")
}
}
http://localhost:3000/data?param=res
=>
query: [:]
params: [:]
path: /data
body:
query: [:]
params: [:]
path: /data
body:
http://localhost:3000/data/param=res
=>
query: [:]
params: [:]
path: /data/param=res
body:
http://localhost:3000/data/?param=res
=>
query: [:]
params: [:]
path: /data/
body:
How I can pass params ?)
Currently Unix is not using a single threaded approach because of the lack of GCD and dispatch_main_queue()
.
The proposal is to use override dispatch_main_queue()
to add any blocks associated on to a queue that is then processed by the main event loop.
It is unclear to me whether Blackfish supports JSON input or not.
I've tried sending a POST request with JSON in the body, but cannot find any properties on request
to read it. There is a body
property, but that's internal and simply a byte array.
In RequestHandler.swift, the code that sets the params property of the Request object is commented out.
Hey cool project! I took a quick look at the source code and I see that you are using recv
to read data from the socket. As far as I know that function blocks if there is no data to be read. Did I get this right? Are you planning to add non-blocking IO in the near feature?
Hi, I really like your work because I'm a fan of Express.js and I think swift would be very interesting switch.
I think it would be very interesting to add some DB connectors (eg. MySQL/MariaDB and MongoDB) as default one in order to provide more appeal to blackfish project. What do you think?
My app is set up as follows:
let app = Blackfish()
let model = Model()
app.use(renderer: StencilRenderer(), ext: ".stencil")
app.get("/") { request, response in
response.render("index.stencil")
}
app.get("/students.html") { request, response in
response.render("students.stencil", data: ["students": model.students])
}
app.use(path: "/api/students", controller: StudentController(model: model))
app.use(path: "/api/courses", controller: CourseController(model: model))
app.listen(port: 3000) { error in
print(error ?? "BlackFishTest listening on port 3000")
}
The error is related to the paths /
and /students.html
. The paths starting with api
still work as before. Files index.stencil
and students.stencil
are in the Resources
folder. What's wrong here?
I'm using the February 8 build on Ubuntu.
When i have clicked on "Deploy to Heroku", it end up with this error message.
-----> Fetching set buildpack https://github.com/kylef/heroku-buildpack-swift... done
-----> Swift app detected
Cloning into 'swiftenv'...
-----> Installing DEVELOPMENT-SNAPSHOT-2016-02-08-a
Downloading https://swift.org/builds/development/ubuntu1404/swift-DEVELOPMENT-SNAPSHOT-2016-02-08-a/swift-DEVELOPMENT-SNAPSHOT-2016-02-08-a-ubuntu14.04.tar.gz
DEVELOPMENT-SNAPSHOT-2016-02-08-a has been installed.
-----> Installing clang-3.7.0
-----> Building Package
Cloning https://github.com/elliottminns/blackfish.git
Using version 0.4.2 of package blackfish
Cloning https://github.com/elliottminns/echo.git
Using version 0.5.1 of package echo
Cloning https://github.com/elliottminns/uv-module.git
Using version 0.1.0 of package uv-module
Cloning https://github.com/elliottminns/blackfish-stencil.git
Using version 0.1.1 of package blackfish-stencil
Cloning https://github.com/kylef/Stencil.git
Using version 0.5.3 of package Stencil
Cloning https://github.com/kylef/PathKit.git
Using version 0.6.1 of package PathKit
Compiling Swift Module 'Echo' (9 sources)
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
func runBlock(block: () -> (), onThread thread: inout pthread_t) {
^~~~~~
inout
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
header "/usr/local/include/uv.h"
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
import CUV
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
func runBlock(block: () -> (), onThread thread: inout pthread_t) {
^~~~~~
inout
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
header "/usr/local/include/uv.h"
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
import CUV
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
func runBlock(block: () -> (), onThread thread: inout pthread_t) {
^~~~~~
inout
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
header "/usr/local/include/uv.h"
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
import CUV
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
func runBlock(block: () -> (), onThread thread: inout pthread_t) {
^~~~~~
inout
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
header "/usr/local/include/uv.h"
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
import CUV
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
func runBlock(block: () -> (), onThread thread: inout pthread_t) {
^~~~~~
inout
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
header "/usr/local/include/uv.h"
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
import CUV
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
func runBlock(block: () -> (), onThread thread: inout pthread_t) {
^~~~~~
inout
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
header "/usr/local/include/uv.h"
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
import CUV
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
func runBlock(block: () -> (), onThread thread: inout pthread_t) {
^~~~~~
inout
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
header "/usr/local/include/uv.h"
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
import CUV
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
func runBlock(block: () -> (), onThread thread: inout pthread_t) {
^~~~~~
inout
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
header "/usr/local/include/uv.h"
^
/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
import CUV
^
<unknown>:0: error: build had 1 command failures
swift-build: error: exit(1): ["/app/tmp/cache/swiftenv/versions/DEVELOPMENT-SNAPSHOT-2016-02-08-a/usr/bin/swift-build-tool", "-f", "/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/.build/release/Echo.o/llbuild.yaml"]
! Push rejected, failed to compile Swift app
Hi,
Stupid question and not especially relative to blackfish but this is with your library I'm testing packages ...
Inside my project folder I created a Package.swift :
import PackageDescription
let package = Package (
name: "Blackfish",
dependencies: [
.Package(url: "https://github.com/elliottminns/blackfish", majorVersion: 0),
]
)
When I run swift build
I have this output error : error: no targets found for this file layout
I'm sure I'm doing something very wrong but can't find what ...
Any help please ? ๐
A default render engine to allow better view loading, current suggestion is Stencil
Upload parsing is currently performed when a file is uploaded. This should probably be dictated by the response handler as it's currently a slow process for the user to upload a file to an endpoint.
Now that the Swift Package Manager has support for tests, Blackfish needs a solid coverage of tests against various cases to ensure it's scalability as the project grows.
Swift:
Apple Swift version 3.0.2 (swift-3.0.2-RELEASE)
Target: x86_64-apple-macosx10.9
Xcode:
Xcode 8.2.1 (8C1002)
OS:
macOS 10.12.2
Function:
public func send(json: Any) {
self.headers["Content-Type"] = "application/json"
do {
let data = try JSONSerialization.data(withJSONObject: json, options: [])
self.body = Buffer(data: data)
} catch {
self.status = 500
}
send()
}
P.s:
JSONSerialization.isValidJSONObject(json) => false
Result:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write'
*** First throw call stack:
(
0 CoreFoundation 0x00007fffc73c1e7b exceptionPreprocess + 171
1 libobjc.A.dylib 0x00007fffdbfaccad objc_exception_throw + 48
2 CoreFoundation 0x00007fffc744099d +[NSException raise:format:] + 205
3 Foundation 0x00007fffc8d5dd5c +[NSJSONSerialization dataWithJSONObject:options:error:] + 249
4 Blackfire 0x000000010068ebbe TFC9Blackfire12HTTPResponse4sendfT4jsonP__T + 702
5 OwnServer 0x00000001000024c0 TF9OwnServerU2_FTC9Blackfire7RequestCS0_12HTTPResponse_T + 224
6 Blackfire 0x00000001006934d3 TTRXFo_oC9Blackfire7RequestoCS_12HTTPResponse__XFo_iTS0_S1___iT + 35
7 Blackfire 0x0000000100693571 TPA__TTRXFo_oC9Blackfire7RequestoCS_12HTTPResponse__XFo_iTS0_S1___iT + 81
8 Blackfire 0x0000000100697507 TTRXFo_iTC9Blackfire7RequestCS_12HTTPResponse__iT__XFo_oS0_oS1__ + 39
9 Blackfire 0x000000010069726a TFFV9Blackfire14RequestHandler6handleFT7requestCS_11HTTPRequest8responseCS_12HTTPResponse_T_U_FFTCS_7RequestS2__T_T + 90
10 Blackfire 0x00000001006973be TTRXFo_oXFo_oC9Blackfire7RequestoCS_12HTTPResponse___zoPs5Error__XFo_iXFo_iTS0_S1___iT___zoPS2__ + 126
11 libswiftCore.dylib 0x0000000100775dd5 TFEsPs8Sequence7forEachfzFzWx8Iterator7Element_T_T + 389
12 Blackfire 0x0000000100697084 TFV9Blackfire14RequestHandler6handlefT7requestCS_11HTTPRequest8responseCS_12HTTPResponse_T + 1076
13 Blackfire 0x00000001006839e1 TFC9Blackfire5Flame6serverfTCS_10HTTPServer10didReceiveCS_11HTTPRequest8responseCS_12HTTPResponse_T + 161
14 Blackfire 0x0000000100683a53 TTWC9Blackfire5FlameS_18HTTPServerDelegateS_FS1_6serverfTCS_10HTTPServer10didReceiveCS_11HTTPRequest8responseCS_12HTTPResponse_T + 67
15 Blackfire 0x0000000100690f80 TFFC9Blackfire10HTTPServer6serverFTCS_6Server19didCreateConnectionPS_10Connection__T_U_FTCS_6BufferSi_T + 800
16 Blackfire 0x00000001006856d5 TFFC9Blackfire16SocketConnection4readFT8callbackFTCS_6BufferSi_T__T_U_FT_T + 453
17 Blackfire 0x00000001006857f7 TTRXFo___XFdCb__ + 39
18 libdispatch.dylib 0x00000001006e5f5c _dispatch_client_callout + 8
19 libdispatch.dylib 0x00000001006fcb15 _dispatch_continuation_pop + 1025
20 libdispatch.dylib 0x00000001006f2658 _dispatch_source_latch_and_call + 195
21 libdispatch.dylib 0x00000001006e8da5 _dispatch_source_invoke + 1106
22 libdispatch.dylib 0x00000001006feca7 _dispatch_root_queue_drain_deferred_item + 704
23 libdispatch.dylib 0x00000001007038f0 _dispatch_kevent_worker_thread + 983
24 libsystem_pthread.dylib 0x000000010075d773 _pthread_wqthread + 1004
25 libsystem_pthread.dylib 0x000000010075d375 start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException
The following
response.send(json: ["message": "Hello World"])
does not compile, with the following error:
contextual type AnyObject cannot be used with dictionary literal
.
This is using the February 8 build on Ubuntu.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.