borchero / Squid

Declarative and Reactive Networking for Swift.
https://squid.borchero.com
MIT License
71 stars 6 forks source link

Request is doing a GET when it's supposed to do a POST #22

Closed kevinrenskers closed 4 years ago

kevinrenskers commented 4 years ago

I have a very simple request:

struct LoginRequest: JsonRequest {
  typealias Result = LoginResponse

  let username: String
  let password: String

  let method: HttpMethod = .post
  let routes: HttpRoute = ["user", "login"]

  var body: HttpBody {
    HttpData.Json(["username": username, "password": password])
  }
}

LoginRequest(username: username, password: password)
        .schedule(with: apiService)

But I get this error:

[Squid] Scheduled request `LoginRequest` with identifier 3:
[Squid]     - Method:   POST
[Squid]     - Url:      https://example.com/api/user/login
[Squid]     - Headers:  * Content-Type => application/json
[Squid]     - Body:     {
[Squid]                   "username" : "s",
[Squid]                   "password" : "d"
[Squid]                 }
[Squid]  
[Squid @ 22:01:47.987] 
[Squid] Finished request `LoginRequest` with identifier 3:
[Squid]     - Status:   405
[Squid]     - Headers:  * Allow => POST, OPTIONS
[Squid]                 * Connection => keep-alive
[Squid]                 * Content-Length => 40
[Squid]                 * Content-Type => application/json
[Squid]                 * Date => Thu, 15 Oct 2020 20:01:47 GMT
[Squid]                 * Server => gunicorn/20.0.4
[Squid]                 * Strict-Transport-Security => max-age=60; includeSubDomains; preload
[Squid]                 * Via => 1.1 vegur
[Squid]                 * X-Content-Type-Options => nosniff
[Squid]                 * X-Frame-Options => DENY
[Squid]                 * X-Xss-Protection => 1; mode=block
[Squid]     - Body:     <40 bytes>
[Squid]                 {
[Squid]                   "detail" : "Method \"GET\" not allowed."
[Squid]                 }
[Squid]  

If I run it with the Charles proxy running, then yea it is actually doing a GET request. If I change LoginRequest.method to .put, the error I get back changes to "Method \"PUT\" not allowed.".

Why is .post not actually doing a POST but a GET? 🤔

kevinrenskers commented 4 years ago

Ah never mind.. the Django server itself has more info:

RuntimeError: You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to minotaur.local:8000/api/user/login/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings.

Turns out Django is doing a redirect itself to the URL with the trailing slash, and that is always turned into a GET request. Sigh :)

Is there an option in Squid to always append a trailing slash?

kevinrenskers commented 4 years ago

Well using let routes: HttpRoute = ["user", "login", "/"] solves it, so 🤷