httpswift / swifter

Tiny http server engine written in Swift programming language.
BSD 3-Clause "New" or "Revised" License
3.9k stars 537 forks source link

signal SIGABRT when sending multiple requests #252

Open ghost opened 7 years ago

ghost commented 7 years ago

Overview

When sending multiple requests to a route findHandler sometimes results in a SIGABRT. This is most visible when spamming requests, as from a script.

Steps to Reproduce

  1. Create a iOS swift project
  2. Imports swifter
  3. Create a router with params (e.g. /a/:b/:c) which returns .ok(.text("Hello World"))
  4. Run a script which makes simultaneous requests to the above route

After some time, Swifter should crash at HttpRouter.swift#108 with a SGABRT and no further detail.

Files to reproduce are below.

Demo Files

(in an iOS application, installing Swifter through CocoaPods)

ViewController.swift

import UIKit
import Swifter

class ViewController: UIViewController {
    let server : HttpServer = HttpServer()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        server["/a/:b/:c"] = { request in
            return .ok(.text("Foo"))
        }

        try! server.start(12333)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

And then a python3 script for producing the error

import requests
import threading
import time

def do_request():
    url = "http://localhost:12333/a/b/c"
    response = requests.get(url)

def worker():
    # Make requests forever!
    while True:
        try:
            print("Requesting")
            do_request()
            print("Done")
        except e:
            time.sleep(0.1)

# Start a worker for each thread
num_threads = 12
for i in range(num_threads):
    t = threading.Thread(target=worker)
    t.start()

# Don't let the program exit
while True: time.sleep(0.1)

Note: the python script uses requests, so you'll need to install it if you don't already have it pip install requests

ghost commented 7 years ago

I've attached the project/script I used.

client.zip server.zip