Giter Site home page Giter Site logo

vapor / vapor Goto Github PK

View Code? Open in Web Editor NEW
23.7K 522.0 1.4K 16.35 MB

💧 A server-side Swift HTTP web framework.

Home Page: https://vapor.codes

License: MIT License

Swift 96.95% C 3.04% HTML 0.01%
vapor swift server-side-swift web-framework server framework http http2

vapor's Introduction

Vapor

Documentation Team Chat MIT License Continuous Integration Code Coverage Swift 5.7+ Mastodon


Vapor is an HTTP web framework for Swift. It provides a beautifully expressive and easy-to-use foundation for your next website, API, or cloud project.

Take a look at some of the awesome stuff created with Vapor.

💧 Community

Join the welcoming community of fellow Vapor developers on Discord.

🚀 Contributing

To contribute a feature or idea to Vapor, create an issue explaining your idea or bring it up on Discord.

If you find a bug, please create an issue.

If you find a security vulnerability, please contact [email protected] as soon as possible.

💛 Sponsors

Support Vapor's development by becoming a sponsor.

Broken Hands Emerge Tools Jari Donut Dane MacStadium

💚 Backers

Support Vapor's development by becoming a backer.

Moritz LangMaarten EngelsThomas KrajacicJesse TiptonSteve HumeMikkel UlstrupGeoffrey FosterPaul SchmiedmayerScott RobbinsSven A. SchmidtSpencer CurtisZach RausnitzTim „Timinator“ KretzschmarKlaasAndrew Edwards+Li, Inc.Stijn WillemsKyle NewsomeVia Aurelia SolutionsJakub KiermaszBrian DrellingMattes MohrJamieGalen RhodesLitmapsDavid RomanBrian StrobachKishikawa KatsumiAlex SherbakovSidetrackGreg KarpatiFrantišek MikšJeremy GreenwoodRay FixMićo MiloložaAlanJonas SannewaldTapEnvy.us, LLCJawadPARAIPAN SORINKalyn DavisYR ChenAarón Martínez Cuevas

vapor's People

Contributors

0xtim avatar adriencanterot avatar artkay avatar bennydebock avatar brettrtoomey avatar calebkleveter avatar casperhr avatar chinsyo avatar czechboy0 avatar gtranchedone avatar gwynne avatar joannis avatar ketzusaka avatar kgn avatar loganwright avatar mahdibm avatar maximbazarov avatar mrlotu avatar nathanflurry avatar rafaelguerreiro avatar rafiki270 avatar sarbogast avatar shnhrrsn avatar siemensikkema avatar skreutzberger avatar tanner0101 avatar technikyle avatar twof avatar vaporbot avatar vzsg 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  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

vapor's Issues

iOS app with a backend using Vapor

First of all, I just want to say that I think Vapor is a great library that I have enjoyed using.

One of the benefits, in my opinion, with the rising number of web frameworks written in Swift is that we as iOS developers are able to reuse code between the frontend and the backend. An obvious candidate for sharing is model objects.

I wanted to ask if anyone have any guidance or practical tips on how to manage a repository consisting both an iOS app and a backend using Vapor, with some classes being shared across the two. Tips on e.g. file structure, Xcode project setup and how to manage the deployment without uploading unneeded iOS specific files to the server is highly appreciated.

Routers accepting variadic handlers

Looking for more than one handler to handle against a route. It's a very powerful feature that I've used a lot with expressjs.

app.get('/example/b', function (req, res, next) {
  console.log('the response will be sent by the next function ...');
  next();
}, function (req, res) {
  res.send('Hello from B!');
});

source: http://expressjs.com/en/guide/routing.html

JSONSerializer not working with Array<String: Any>.

Hi,

When I tried to return an object with type is Array<[String: Any]> like this:

override func index(request: Request) -> ResponseConvertible {
    return generate()
}
func generate() -> Array<[String: Any]> {
    let firstObject: [String: Any] = ["id": 1, "title": "first"]
    let secondObject: [String: Any] = ["id": 2, "title": "second"] 
    return [firstObject, secondObject]
}

It doesn't work!

I looked into JSONSerializer class, I see the type casting to [Any] always fail.

else if let arr = object as? [Any] {

I think it's a bug of Swift. So, as work-around, I added some codes to make it work.

else if let arr = object as? Array<[String: Any]> {
// Do same things as [Any]
}

Your library is awesome, keep it up :)
Tuan.

Unable to build

I’m just getting started here so maybe it’s just my setup. Right now I get this error when I try to build vapor:

Cloning https://github.com/tannernelson/vapor.git
Using version 0.1.4 of package vapor
error: rename error: File exists (17): /var/www/vapor/Packages/vapor -> /var/www/vapor/Packages/vapor-0.1.4

This Ubuntu 14.04 with clang, git, libicu-dev installed. Swift 2.2 from January 11 is installed too.

Session class

Create a session class similar to PHP and Laravel's.

Session.get('name')

Session.put('name', 'Vapor')

Session.start(request)

create documentation wiki

Vapor, like Laravel, needs to have excellent documentation. The first step will be separating out the current single documentation README into multiple sections and pages. A GitHub wiki will be a good place to start with this as the Markdown format could be easily ported to a full website in the future.

Additionally, information such as a roadmap / contribution guideline will be included in this expanded documentation.

License violation

Improper JSON serialization leads to user-controlled JSON contents

The JSON serializer used does not properly validate key/value contents. One major issue is that " is not escaped, so users can create requests that craft extra keys in the serialized JSON. This can even be a security issue in certain web apps. I highly suggest using a JSON serialization library/framework for this task rather than writing a custom one. No reason to reinvent the (JSON) wheel :)

Example: http://qutheory.io/data/oops%22%7D,%22request.lol%22=%22hi?query=fail%22,extra=%22haxx

Hello world not working

The following app

import Vapor
let app = Application()
app.get("welcome") { request in
  return "Hello from Vapor"
}
app.start()

returns a 404 when requesting localhost/welcome.

Server output:

[2016-03-06 19:25:10 +0000] [INFO] Server has started on port 80
[2016-03-06 19:25:12 +0000] [VERBOSE] Received Get request for /welcome
[2016-03-06 19:25:12 +0000] [WARNING] Response had no 'Content-Type' header.

I'm running on Ubuntu 15.10 using the March 1 snapshot of Swift and Vapor 0.2.8.

"no such module 'Jay'" when running `swift build`

I just created a basic project through Xcode. It has two files:

Package.swift

import PackageDescription

let package = Package(
    name: "My App",
        dependencies: [
            .Package(url: "https://github.com/qutheory/vapor.git", majorVersion: 0),
    ]
)

main.swift

import Foundation

print("Hello, World!")

When I run swift build I get the following:

[I] ~/Dropbox/Projects/My App/My App (master *+%)           
↪  swift build                                                        0@12:30:47
Compiling Swift Module 'JayExample' (1 sources)
Compiling Swift Module 'Vapor' (37 sources)
/Users/me/Dropbox/Projects/My App/My App/Packages/Jay-0.3.5/Sources/JayExample/main.swift:1:8: error: no such module 'Jay'
import Jay
       ^
/Users/me/Dropbox/Projects/My App/My App/Packages/Vapor-0.2.7/Sources/Vapor/JSON/JSONSerializer.swift:2:8: error: no such module 'Jay'
import Jay
       ^
/Users/me/Dropbox/Projects/My App/My App/Packages/Vapor-0.2.7/Sources/Vapor/JSON/JSONSerializer.swift:2:8: error: no such module 'Jay'
import Jay
       ^
/Users/me/Dropbox/Projects/My App/My App/Packages/Vapor-0.2.7/Sources/Vapor/JSON/JSONSerializer.swift:2:8: error: no such module 'Jay'
import Jay
       ^
/Users/me/Dropbox/Projects/My App/My App/Packages/Vapor-0.2.7/Sources/Vapor/JSON/JSONSerializer.swift:2:8: error: no such module 'Jay'
import Jay
       ^
/Users/me/Dropbox/Projects/My App/My App/Packages/Vapor-0.2.7/Sources/Vapor/JSON/JSONSerializer.swift:2:8: error: no such module 'Jay'
import Jay
       ^
/Users/me/Dropbox/Projects/My App/My App/Packages/Vapor-0.2.7/Sources/Vapor/JSON/JSONSerializer.swift:2:8: error: no such module 'Jay'
import Jay
       ^
/Users/me/Dropbox/Projects/My App/My App/Packages/Vapor-0.2.7/Sources/Vapor/JSON/JSONSerializer.swift:2:8: error: no such module 'Jay'
import Jay
       ^
/Users/me/Dropbox/Projects/My App/My App/Packages/Vapor-0.2.7/Sources/Vapor/JSON/JSONSerializer.swift:2:8: error: no such module 'Jay'
import Jay
       ^
<unknown>:0: error: build had 2 command failures
error: exit(1): /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2016-02-25-a.xctoolchain/usr/bin/swift-build-tool -f /Users/me/Dropbox/Projects/AMC\ Podcast\ Feed/AMC\ Podcast\ Feed/.build/debug.yaml default

I'm new to all of this and likely doing something wrong.

Unable to build on OS X 10.11, Xcode 7.3 Beta

I performed a clean install of Swift and Xcode 7.3 beta and then configured a blank project using the Getting Started guide, however I get the below console output when building it.

$ swift build
Cloning https://github.com/qutheory/vapor.git
Resolved version: 0.2.6
Cloning https://github.com/czechboy0/Jay.git
Resolved version: 0.3.5
Compiling Swift Module 'Jay' (19 sources)
Linking libJay.dylib
Compiling Swift Module 'JayExample' (1 sources)
Compiling Swift Module 'Vapor' (36 sources)
Linking JayExample
Linking libVapor.dylib
Compiling Swift Module 'Vaportest' (6 sources)
Compiling Swift Module 'VaporDev' (2 sources)
Compiling Swift Module 'TestProject' (1 sources)
Linking VaporDev
Linking TestProject
ld: framework not found XCTest for architecture x86_64
<unknown>:0: error: build had 1 command failures
error: exit(1): /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2016-02-25-a.xctoolchain/usr/bin/swift-build-tool -f /Users/jamie/Development/TestProject/.build/debug.yaml default

Swift version:

$ swift --version
Apple Swift version 3.0-dev (LLVM b361b0fc05, Clang 11493b0f62, Swift fc261045a5)
Target: x86_64-apple-macosx10.9

Can't deploy to heroku -> Vapor was not compiled for testing

While deploying to heroku via the heroku buildpack by kyef, I am getting various errors, which are saying, that vapor was not compiled for testing.

Logs:

remote: /tmp/build_983b446567fa58ccabf08a27e651813d/Packages/Vapor-0.2.8/Tests/Vapor/ControllerTests.swift:10:18: error: module 'Vapor' was not compiled for testing
remote: @testable import Vapor
remote:                  ^
remote: /tmp/build_983b446567fa58ccabf08a27e651813d/Packages/Vapor-0.2.8/Tests/Vapor/ProcessTests.swift:10:18: error: module 'Vapor' was not compiled for testing
remote: @testable import Vapor
remote:                  ^
remote: /tmp/build_983b446567fa58ccabf08a27e651813d/Packages/Vapor-0.2.8/Tests/Vapor/HashTests.swift:11:18: error: module 'Vapor' was not compiled for testing
remote: @testable import Vapor
remote:                  ^
remote: /tmp/build_983b446567fa58ccabf08a27e651813d/Packages/Vapor-0.2.8/Tests/Vapor/ResponseTests.swift:10:18: error: module 'Vapor' was not compiled for testing
remote: @testable import Vapor
remote:                  ^
remote: /tmp/build_983b446567fa58ccabf08a27e651813d/Packages/Vapor-0.2.8/Tests/Vapor/LogTests.swift:10:18: error: module 'Vapor' was not compiled for testing
remote: @testable import Vapor
remote:                  ^
remote: /tmp/build_983b446567fa58ccabf08a27e651813d/Packages/Vapor-0.2.8/Tests/Vapor/RouteTests.swift:10:18: error: module 'Vapor' was not compiled for testing
remote: @testable import Vapor
remote:                  ^
remote: /tmp/build_983b446567fa58ccabf08a27e651813d/Packages/Vapor-0.2.8/Tests/Vapor/QueryParametersTests.swift:11:18: error: module 'Vapor' was not compiled for testing
remote: @testable import Vapor
remote:                  ^
remote: /tmp/build_983b446567fa58ccabf08a27e651813d/Packages/Vapor-0.2.8/Tests/Vapor/EnvironmentTests.swift:10:18: error: module 'Vapor' was not compiled for testing
remote: @testable import Vapor
remote:                  ^
remote: /tmp/build_983b446567fa58ccabf08a27e651813d/Packages/Vapor-0.2.8/Tests/Vapor/RouterTests.swift:11:18: error: module 'Vapor' was not compiled for testing
remote: @testable import Vapor
remote:                  ^
remote: <unknown>:0: error: build had 1 command failures
remote: swift-build: error: exit(1): /app/tmp/cache/swiftenv/versions/DEVELOPMENT-SNAPSHOT-2016-02-25-a/usr/bin/swift-build-tool -f /tmp/build_983b446567fa58ccabf08a27e651813d/.build/release.yaml default
remote: 
remote:  !     Push rejected, failed to compile Swift app
remote: 
remote: Verifying deploy...
remote: 
remote: !   Push rejected to swiftserver-test.

What did I do wrong?

Thanks in advance.

Controller Refactor Proposal

Hello,

I wanted to make a proposal towards refactoring how Controllers work within Vapor. I've been working on a project that has some similarities to Vapor, and I wanted to see how my vision fit within it.

Under my system, I have calls into the router like so:

router.registerRouteWithPath("/channels/:channel", usingAction: ChannelDashboard.index)

ChannelDashboard conforms to Controller:

protocol Controller: class {
    var request: Request { get }
    init(request: Request) throws
}

It also implements the method index, which handles the actual request.

The key difference here and between what exists in Vapor today is that the request is passed into an initializer vs each request method. This would allow people to configure a variety of things at class initialization (which the router handles via currying, and I'll get into that soon). The way I'm using it is connecting to a DB, opening other sockets, and reading some extra data that all request methods would be interested in.

I feel like this would be useful because under the current Controller implementation you wouldn't be able to do what Rails calls a before_filter that would be able to look at request data; it'd have to wait until after the instantiation from the router closure.

In terms of implementation with currying, after the Request object is instantiated we can attempt try to instantiate the controller. This is what I'm doing under my system, which takes a generic type + the protocol, and records the instantiation call into a closure attached with a path:

func registerRouteWithPath<ControllerType: Controller>(path: String, usingAction action: (Controller) -> () throws -> ResponseType) {
        let actionCaller = { (request: Request) throws -> ResponseType in
            try action(try ControllerType(request: request))()
        }

        let route = Route(path: path, actionCaller: actionCaller)
        routes.append((path, route))
    }

This is possible because Swift creates a class method for each instance method that takes an instance of the class, i.e:

ChannelDashboard.index(ChannelDashboard) -> () -> ResponseType

That's a bit confusing, but it makes for a very simple registration API, and its something that's worked well in my use case where I don't need to worry about processing request information after the fact.

In addition, Vapor or its users could extend Controller to look at request and provide convenience methods to the contents of the Request object. I've done this with parameter values, and also added some methods for working with environment variables.

What are your thoughts on this? I'd be happy to implement them myself if there's interest.

Thanks!
~James

Response status No Content

204 No Content is the intended response for requests that succeeded but don't return anything. It is often used for updates and deletions and should be included in the Status enum for ease of use.

Build Errors when building with Vapor 0.3.5

screen shot 2016-03-27 at 1 39 32 pm

When building an app that has Vapor as a package. I am getting a build error about JayExample not finding a module. I think JayExample needs to be excluded within its projects.

Not sure If should post this here or on the Jay git. But error began when I added Vapor as a package.

Problem with swiftpm

I got an error NoSources when swift building on Ubuntu 15 server (swift dev-snapshot from Feb 25).

To make it work I had to:

cd Packages/Vapor-0.2.6/Vapor
mv */* .
rmdir * # for good measure

Compile failure on OSX 10.10.5 , Xcode 7.1

/Library/Developer/Xcode/DerivedData/Vapor-hcyxlaippuixaudjkrczccpcvdiu/Build/Intermediates/Vapor.build/Debug/Vapor.build/Script-3AEEF4211C7F6D9F0099CBAE.sh: line 2: /Library/Developer/Toolchains/swift-latest.xctoolchain/usr/bin/swift: No such file or directory

Unable to properly infer complex Json

If I have the following command:

Route.get("complex") { request in
    let json = [
        "root" : [
            ["hello" : "world"],
            ["hello" : "mars"]
        ]
    ]
    return try Response(status: .OK, json: json)
}

It will work locally, but on Heroku, it will hit Mirror in the JsonSerializer and return ""

If, I add let json: [String : Any] = ... then it will return { "root" : "" } because it fails in parsing the nesting.

This can be reproduced locally, but requires a bit trickier response:

Route.get("thing") { _ in
    let thing: [String : [String : Any]] = [
        "one" : [
            "hi" : "there"
        ],
        "two" : [
            "hi" : "again",
            "bye" : "sup"
        ]
    ]

    return thing
}

Then my only response is: `

Benchmark require

Wish some day you can comparing PHP 7.x/HHVM 3.5 on Laravel 5.x and Lumen benchmark.

Vapor installer

Not an issue as such, more of an FYI...

I've built a quick installer here https://github.com/mpclarkson/vapor-installer which allows you to create a new vapor project at the command line:

vapor new ProjectName

This basically:

  1. Checks if a folder with the specified name exists already
  2. Clones your vapor-example repository (master) into a folder with the ProjectName
  3. Updates the Package.swift and other files by replacing VaporApp with ProjectName

Future enhancements:

  1. Specify a tag / release
  2. Self-update etc

Note, I had to build this with swiftc rather than swift build as I'm having all sorts of issues with the package manager on OSX- no issues on Ubuntu.

Let me know if you'd be happy for me to update the readme with a link to the installer.

Are you on twitter?

Erro on link libStrand.so

On build exemple show the erro:

Linking .build/debug/libStrand.so
/usr/bin/ld: /tmp/vapor-example/.build/debug/Strand.build/Strand.swift.o: relocation R_X86_64_PC32 against protected symbol `TWPO6Strand11StrandErrors13ErrorProtocolS' can not be used when making a shared object
/usr/bin/ld: final link failed: Bad value
clang-3.7: error: linker command failed with exit code 1 (use -v to see invocation)
:0: error: link command failed with exit code 1 (use -v to see invocation)
:0: error: build had 1 command failures
error: exit(1): /usr/bin/swift-build-tool -f /tmp/vapor-example/.build/debug.yaml default

Placement of `inout`

The placement of inout has changed because of SE-30. Can this be adopted in the code?
Currently, my error messages get lost in a long list of deprecation warnings because of this.

Server Side Requirements

Hello,
this may look as a dumb question, but has a PHP developer I never faced any problems with shared hosting because every hosting has PHP.

I understand that to use Swift and Vapor on the web it may require some special configurations or instalations.
So, what are those requirements? Is there a guide or something to test in heroku.com?

Xcode project missing files that have been added to .gitignore

Forked the repo to hopefully help contribute but not sure how you would like this to occur. The Xcode project seems pretty broken right now due to many missing files that are added in the .gitignore. I am not able to run the current tests and not sure how you would like newly added tests to be added to the project.

Json cannot be initialized using Int

The following code (where id is of type Int)

var data: [String: Json] = [:]
data["id"] = Json(id)

does not compile with the error call can throw, but it is not marked with 'try' and the error is not handled (referring to the Json initializer).

Should this be possible? I can wrap id in a Double as a workaround, but the error was pretty confusing so I wonder if this is a bug.

This is using Vapor 0.2.8 on Ubuntu 15.10 with Swift snapshot of March 1.

DDoS risk

In function handleConnection(socket:) [File : SocketServer.swift]:
while let request = try? parser.readHttpRequest(socket) { ... }
Isn't it a chance for server to be attacked by DDOS? since parser.readHttpRequest() is blocked on socket reading.

Cryptography best practices

I've only taken a quick look at the code, but I see a few theoretical security issues:

  • You're using SHA-1 for various purposes; due to recent cryptanalytic breakthroughs on it, it's highly recommended to avoid SHA-1 in favor of SHA-2 or another hash ("SHA-1 is no longer considered secure against well-funded opponents"). If you were using the HMAC construction with applicationKey, this would be only a theoretical issue, as the only attack likely to be practical on SHA-1 anytime soon is a collision attack, and HMAC does not depend on collision resistance (and your other use of SHA-1, generating random session IDs, does not benefit from reverse engineering the hash), but...
  • ...you're hashing the string "\(string)\(applicationKey)". Since the data is first and the hash is (essentially) iterative, finding a collision between two legal data strings (which can be done offline) would also cause the concatenated string to collide. Reversing the order would fix that but open up length extension attacks. Instead, use HMAC, that's what it's for.
  • On Linux, you're generating random numbers using libc's random, which is very much not cryptographically secure. Easiest to just read from /dev/urandom instead. (On OS X, arc4random is okay but theoretically vulnerable to issues with bias, with the same solution.)
  • While this is unlikely to ever be an issue in practice, the random session generator uses an unnecessarily low amount of entropy, with "only" 100 million possibilities (26 bits) from the two Int.random calls. 100 million is high for an online attack and unless the clock is somehow compromised, the precision of timeIntervalSinceNow bumps that up by many more orders of magnitude - but avoiding this tiny risk is just a matter of adding a few more zeroes, so it'd be best to do so. Better yet, just get 16 random bytes from a suitable generator without going through the SHA hashing.

post request body

When receiving a JSON request, I expected the request.data to include the keys and values, but instead it's a json string key and value that are identical, ie:

["{\"hello\":\"world\"}" : "{\"hello\":\"world\"}"]

Logger wip

I've written a basic logger which you can see here and would appreciate any input before taking it any further.

The relevant files are:

LogDriver.swift
This includes the LoggerDriver protocol and an example ConsoleLoggerDriver which simply prints logs to the console.

The intention here is that you can implement any kind of logger (e.g. file, database etc) so long as it implements this protocol.

Logger.swift
This is a singleton... not sure what your position is on singletons but they are certainly widely used for loggers. Happy to change the implementation if you prefer otherwise.

Currently the logger uses the ConsoleLoggerDriver, which is (current) injected in the private init for the example, but this would be better handled by registering a service provider (as discussed in #39 )

Log.swift
This contains the Level enum, a Loggable protocol and a Log struct which implements this protocol. Currently, only date, level and message are required by the protocol but this could also include the file, function, line etc.

I have created an example log in Request.init as follows:

   //Testing logs
   let message = "Received \(method.rawValue) request for \(path)"
   let log = Log(level: .Info, message: message)
   Logger.sharedInstance.log(log)

Which prints the following to the console for every request:

[2016-02-21 05:08:38 +0000] Info: Received GET request for /

compile fail, ubuntu 14.04

swift build
Compiling Swift Module 'Vapor' (18 sources)
/home/mac/swiftdev/vapor/Sources/Parser.swift:36:42: error: value of type 'String' has no member 'stringByReplacingOccurrencesOfString'
let key = cookieArray[0].stringByReplacingOccurrencesOfString(" ", withString: "")
~~~~~~~~~~~^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Decode URL-encoded parameters in request.parameters

It would be nice if parameters were automatically decoded — almost every web framework does this automatically. I would make a PR but the repo seems to be missing main.swift and several other other items — is that on purpose?

Dangerous `rm -rf` in CLI

Was just browsing around and noticed this:

            let _ = try? run("rm -rf \(name)/.git")

Thought I should say something since (it looks like) running vapor new / would run rm -rf / /.git, or other similar bad things.

Thanks!

Asynchronous

I would like to propose an improvement that would allow for asynchronous request handling.

My proposal would be that instead of returning a ResponseConvertible object in the Router, a Response object is added to the parameters, and is handled when a send() method is called on the response. For example:

Route.get("/") { request, response in
      response.status = .OK
      response.body = View(path: "Views/index.html")
      response.send()
}

This would allow for any asynchronous long running tasks to be handled, whilst giving the ability to return to the user in a timely manner. This would allow for much more responsive websites. For example:

Route.post("/BuildRome") { request, response in

    if builder.validateData(request.data) {

        response.status = .OK

        builder.buildRomeFromData(request.data) { rome in

             // Tell the world we've built rome. 
             response.body = ["rome": rome]
             response.send()
        }

    } else {
        response.status = . BadRequest
        response.send()
    }
}

Please let me know your thoughts.

Injecting dependencies into ResourceControllers

How am I supposed to do this? Vapor requires me to register a type as a controller, not an object. The Controller protocol dictates this type should have a default initializer. Vapor then uses this initializer to create an object right before it calls one of the index, store, ... methods on it. This means I can't inject anything into the object because I can't initialize it.

Wouldn't it be better to register an object as a controller, instead of a type? That's the way Blackfish does it, meaning I can inject my dependencies (model) via the initializer as follows (Blackfish code):

app.use(path: "/api/students", controller: StudentsApiController(model: model))

Use of `self`

I noticed Application+Route uses self unnecessarily:

public final func get(path: String, handler: Route.Handler) {
    self.add(.Get, path: path, handler: handler)
}

These usages should probably be removed as the consensus is to only use self when required (see the rejection of SE-9).

Error while deploying to Heroku

First of all, good job on making this!

This issue might be out of scope for this repo, but here goes. I wanted to try and deploy this to Heroku. Using kylef's buildpack (https://github.com/kylef/heroku-buildpack-swift) I receive the following error:

remote: -----> Fetching set buildpack https://github.com/kylef/heroku-buildpack-swift.git... done
remote: -----> Swift app detected
remote: -----> Installing 2.2-SNAPSHOT-2016-01-11-a
remote: -----> Installing clang-3.7.0
remote: -----> Building Package
remote: Cloning https://github.com/tannernelson/vapor.git
remote: Using version 0.1.6 of package vapor
remote: Compiling Swift Module 'Vapor' (21 sources)
remote: /tmp/build_40ef44289550a82b4ac7bc7f6206a753/Packages/vapor-0.1.6/Sources/Server.swift:85:17: error: use of unresolved identifier 'sleep'
remote:                 sleep(1)
remote:                 ^~~~~
remote: Attributes 'readnone and readonly' are incompatible!
remote: i16 (i16)* @htons
remote: LLVM ERROR: Broken module found, compilation aborted!
remote: <unknown>:0: error: build had 1 command failures
remote: swift-build: error: exit(1): ["/tmp/build_40ef44289550a82b4ac7bc7f6206a753/.swift/swift-2.2-SNAPSHOT-2016-01-11-a/swift-2.2-SNAPSHOT-2016-01-11-a-ubuntu14.04/usr/bin/swift-build-tool", "-f", "/tmp/build_40ef44289550a82b4ac7bc7f6206a753/.build/release/Vapor.o/llbuild.yaml"]
remote:
remote:
remote:  !     Push rejected, failed to compile Swift app

Do you know why this is happening?

Default response text

Should Response not have a convenience initializer that takes only a status? I find myself doing a lot of this:

Response(status: .Created, text: Response.Status.Created.reasonPhrase)

Query data is being handled improperly

Within Request.swift is a method called parseQueryData that is mishandling how question marks are meant to be processed. The issue is here:

return self.parseData(urlParts[1])

urlParts is created like so:

var urlParts = string.split("?")

A '?' is only significant for at the first occurrence. For example, with a path of /foo/bar?baz=derp?derp should evaluate to a key of baz containing a value of 'derp?derp'. However, under the existing way the parts are split up, the value would be 'derp' as the rest of the value information (except the ?) would live in urlParts[2].

Some reference on the topic:

http://stackoverflow.com/questions/2924160/is-it-valid-to-have-more-than-one-question-mark-in-a-url

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.