Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Downloading a file generates a second GET request [without headers] #489

Closed
giuseppegreco opened this issue Jul 10, 2014 · 21 comments · May be fixed by bumplzz69/swagger-ui#20, checkoss/swagger-ui#16 or qsays/swagger-ui#24
Milestone

Comments

@giuseppegreco
Copy link

In the following Controller, method getAvatar returns the image of the user's avatar:

object Users extends Controller {

  ...

  def getAvatar(imageId: String) = SecuredAction.async { implicit request =>
    daoService.findImage(imageId).flatMap {
      case Some(image) =>
        val contentDisposition = request.getQueryString("inline") match {
          case Some("true") => ContentDisposition.Inline
          case _ => ContentDisposition.Attachment
        }
        serveFile(image, contentDisposition)
      case _ => Future.successful(NotFound)
  }.recover { e => e match {
    ...
  }

  def serveFile(file: MetaFile, contentDisposition: ContentDisposition)( 
    implicit fsService: FsServiceComponent#FsService
  ) = Future {
    val filename = file.filename
    SimpleResult(
      header = ResponseHeader(OK, Map(
        CONTENT_LENGTH -> (s"${file.length}"),
        CONTENT_DISPOSITION -> (s"""$contentDisposition; filename="$filename"; filename*=UTF-8''"""
        + java.net.URLEncoder.encode(filename, "UTF-8").replace("+", "%20")),
        CONTENT_TYPE -> file.contentType.getOrElse("application/octet-stream")
      )),
      body = fsService.enumerate(file)
    )
  }
}

The code above forks fine as long as I ignore security. For instance, SecuredAction is a custom Action that manages authorization using Jwt (Json Web Token). Each request needs to have a valid JWT in the AUTHORIZATION header to get authorized... and also this mechanism works fine. The problem is that in case of file download, the method (in this case getAvatar) get invoked twice: the first GET request contains the token, while the second GET request doesn't.

I've tried my REST API with curl: it works fine and DOESN'T generate a second GET as Swagger does.

@fehguy
Copy link
Contributor

fehguy commented Jul 11, 2014

Hi, are you sure the second request is a GET? Maybe it's an options?

I need some more info for this. Can you share your JSON description?

@giuseppegreco
Copy link
Author

Hi Tony,

Yes, I get two GET requests. Here is what I get when invoking my REST api via Swagger:

[debug] application - request /auth/users/5392238c1e04001e04b384b4/avatar authorized for user 5392238c1e04001e04b384b4
AnyContentAsEmpty
GET /auth/users/5392238c1e04001e04b384b4/avatar
[debug] application - request /auth/users/5392238c1e04001e04b384b4/avatar authorized for anonymous user
AnyContentAsEmpty
GET /auth/users/5392238c1e04001e04b384b4/avatar

... and here is what I get when invoking my REST api via curl:

[debug] application - request /auth/users/5392238c1e04001e04b384b4/avatar authorized for user 5392238c1e04001e04b384b4
AnyContentAsEmpty
GET /auth/users/5392238c1e04001e04b384b4/avatar

As you can see, curl invokes the API only once with the correct authorization token and everything works fine. Instead, Swagger invokes the API twice: the first GET request is correct and contains the right authorization token, while in the second GET request the token is gone and as a result the file is not downloaded.

I hope that helps,
j3d

@fehguy
Copy link
Contributor

fehguy commented Jul 11, 2014

OK--if you can send the JSON for that API I can help sort it out. If you don't want to post it here, you can email it to me.

@giuseppegreco
Copy link
Author

OK, just emailed more info. Tx.

@fehguy
Copy link
Contributor

fehguy commented Aug 2, 2014

try again. Just did an update of swagger-ui

@giuseppegreco
Copy link
Author

Hi Tony,

Replacing swagger.js produces the following error when sending a POST
(Bad request):

For request 'POST /auth/users/credentials' [Expecting text/json or
application/json body]
I've just rolled back to the previous version. Let me know if you need
any further info ;-)

Talk 2 u soon,
j3d

On 02.08.2014 02:28, Tony Tam wrote:

try again. Just did an update of swagger-ui


Reply to this email directly or view it on GitHub
#489 (comment).

Giuseppe Greco_|_Founder
*Gok!llo GmbH
*8001 Zurich – Switzerland
Email [email protected] • Phone +41 91 234 51 09 • Mobile +41
79 590 33 06
gokillo.com http://gokillo.com/

@fehguy
Copy link
Contributor

fehguy commented Aug 2, 2014

Hi j3d, I messed it up yesterday and pushed a fix just a few minutes ago. Can you please update to swagger-ui 2.0.21 and swagger-js 2.0.36?

@giuseppegreco
Copy link
Author

Hi Tony,

I've just updated my Swagger UI distro... but it doesn't work. GET
requests work, while POST requests never return and the UI just blocks.

Since no error message is generated I'm unable to provide you with more
info.

Talk 2 u soon,
j3d

On 03.08.2014 00:59, Tony Tam wrote:

Hi j3d, I messed it up yesterday and pushed a fix just a few minutes
ago. Can you please update to swagger-ui 2.0.21 and swagger-js 2.0.36?


Reply to this email directly or view it on GitHub
#489 (comment).

@giuseppegreco
Copy link
Author

Just to let you know I tested the latest version... and the problem is still here (it works with CURL). Let me know if I could help somehow ;-)

@giuseppegreco
Copy link
Author

Did some additional tests... and the last version ALWAYS generates two requests, regardless of the request type (GET, PATCH, ...).

@fehguy
Copy link
Contributor

fehguy commented Aug 28, 2014

I don't see this. Try from here:

http://petstore.swagger.wordnik.com/

Do you see multiple requrests? You sure you're not seeing the OPTIONS request first?

@giuseppegreco
Copy link
Author

Hi Tony,

Sorry for my delay... but I wanted to be sure and so I did some more
tests. Here below is what I've found so far with the latest version of
swagger-ui:

  1. PATCH requests with empty body don't work and always return the
    "Invalid JSON" message
  2. Normal GET, PATCH, POST requests DO NOT generate a second HTTP
    request... but GET requests to download files DO generate a second GET
    request identical to the previous one

So when I said that GET, PATCH, ... ALWAYS generate a second HTTP
request was not correct - I'm sorry for that :-(

Talk 2 u soon,
j3d

On 28.08.2014 07:40, Tony Tam wrote:

I don't see this. Try from here:

http://petstore.swagger.wordnik.com/

Do you see multiple requrests? You sure you're not seeing the OPTIONS
request first?


Reply to this email directly or view it on GitHub
#489 (comment).

Giuseppe Greco_|_Founder
*Gok!llo GmbH
*8001 Zurich – Switzerland
Email [email protected] • Phone +41 91 234 51 09 • Mobile +41
79 590 33 06
gokillo.com http://gokillo.com/

@fehguy
Copy link
Contributor

fehguy commented Sep 2, 2014

OK, it is true that swagger is not sending an empty JSON for any requests automatically. So if you issue a PATCH without any content, it is not putting {} in the body and therefore you get a parse error on your server.

@giuseppegreco
Copy link
Author

I just did a small change in the swagger-ui source so that I no longer the the "invalid JSON" error:

if (obj.body == null && obj.method != "GET") obj.body = "{}";

This works for me ;-)

What is still not working are GET requests to download files... they always generate two GET
requests (no OPTIONS or whatever else). If I sent a GET request to download a file with swagger-ui, then my backend receives two distinct requests... and the problem is that the second request no longer contains the authorization header and therefore the request get refused. If a send the same GET request with curl, then everything works correctly.

@fehguy
Copy link
Contributor

fehguy commented Sep 6, 2014

I think this is a valid solution, it belongs in swagger-js. I still cannot reproduce the double download request. If you have a service up, a sample, or anything like that, would be happy to help sort this out.

@giuseppegreco
Copy link
Author

Give me 5 minutes... if you provide me with your private email I'll
setup an instance of my backend so that you cant try it.

j3d

On 06.09.2014 17:57, Tony Tam wrote:

I think this is a valid solution, it belongs in swagger-js. I still
cannot reproduce the double download request. If you have a service
up, a sample, or anything like that, would be happy to help sort this out.


Reply to this email directly or view it on GitHub
#489 (comment).

Giuseppe Greco_|_Founder
*Gok!llo GmbH
*8001 Zurich – Switzerland
Email [email protected] • Phone +41 91 234 51 09 • Mobile +41
79 590 33 06
gokillo.com http://gokillo.com/

@fehguy
Copy link
Contributor

fehguy commented Sep 6, 2014

sure--i'm stepping away from the computer for about 2 hours but can help when back. [email protected]

@fehguy fehguy modified the milestone: v2.1.0-M1 Jan 28, 2015
@fehguy
Copy link
Contributor

fehguy commented Feb 1, 2015

I'm unable to reproduce this. If you can re-test with M1, let's reopen this.

@fehguy fehguy closed this as completed Feb 1, 2015
@giuseppegreco
Copy link
Author

Just tried... and I still get two GET requests (as I already told you,
it works with curl).
j3d

On 01.02.2015 05:51, Tony Tam wrote:

I'm unable to reproduce this. If you can re-test with M1, let's reopen
this.


Reply to this email directly or view it on GitHub
#489 (comment).

@webron
Copy link
Contributor

webron commented Feb 1, 2015

Is your spec publicly available? If you want to share it in private, feel free to send an email with the details (mail available on profile).

@jamesearlywine
Copy link

I'm having similar issue.

In Chrome browser:
http://hssticker.indystardev.com/swagger/explore_cache/#!/Sports_Ticker_Cache/get_imageCache_folder_filename
If you use the filename: qfEEqs.png

You'll see that SwaggerUI indicated there is no response from the server.

..but then it works if you open your web/javascript console.

..and then when I try it in Firefox, it works fine.

I notice two requests are being sent to s3 for the image.

Does anyone know why this would be happening?

--jle

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment