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

Add documentation about request_body directive in Caddyfile #104

Merged
merged 5 commits into from
Nov 19, 2020

Conversation

pic
Copy link
Contributor

@pic pic commented Nov 18, 2020

No description provided.

Copy link
Member

@mholt mholt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, thank you! Just a few minor fixes first.

pic and others added 4 commits November 19, 2020 10:39
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
@pic pic requested a review from mholt November 19, 2020 09:41
@pic
Copy link
Contributor Author

pic commented Nov 19, 2020

@francislavoie @mholt thanks for the suggestions, I've applied all of them

Copy link
Member

@mholt mholt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It occurred to me that we should probably document what happens when more than the maximum body size is read by the server, just for convenience so people don't have to cross-reference the JSON docs. But this LGTM for now, thanks for the contribution!

@mholt mholt merged commit caefac9 into caddyserver:master Nov 19, 2020
@pic pic deleted the request_body branch November 24, 2020 16:42
@airblade
Copy link

It occurred to me that we should probably document what happens when more than the maximum body size is read by the server, just for convenience so people don't have to cross-reference the JSON docs.

Please could you tell me what happens?

I would expect a 413 Payload Too Large response but looking at the code it seems to silently drop any excess bytes and carry on as if nothing erroneous had happened.

BTW, I tried to "cross-reference the JSON docs" but I'm not sure what or where they are.

@mholt
Copy link
Member

mholt commented Jul 11, 2021

@airblade It should depend on the handler that's reading the body, it's the job of the terminating handler to handle errors in a way that is suitable for it.

BTW, I tried to "cross-reference the JSON docs" but I'm not sure what or where they are.

The "JSON Config Structure" in the docs: https://caddyserver.com/docs/json/ (or the list of config modules: https://caddyserver.com/docs/modules/http.handlers.request_body)

@airblade
Copy link

@mholt Thanks for the response, much appreciated.

I've been looking further at the docs and browsing the code but I'm still can't figure out what would happen when a request body exceeds the maximum allowed size. (In my scenario it would be the user uploading a file via an HTML form to Caddy, through to an upstream Puma app server running a Rails app.)

@mholt
Copy link
Member

mholt commented Jul 12, 2021

@airblade Like I said, it depends on the terminating handler and how it chooses to handle the error. Since you mentioned you have an upstream app, I'm going to assume you are using reverse_proxy, which uses a transport module to perform the round trip. The default HTTP transport is implemented by the Go standard library, which controls that part of the logic (reading the request body):

https://github.com/golang/go/blob/ab4085ce84f8378b4ec2dfdbbc44c98cb92debe5/src/net/http/transport.go#L503-L504

@francislavoie
Copy link
Member

francislavoie commented Jul 12, 2021

To clarify - r.Body = http.MaxBytesReader(w, r.Body, rb.MaxSize) wraps r.Body with a check if Caddy tries to read too many bytes that will emit an error.

The error will get triggered in whatever subsequent handler which tries to read the body (like Matt said, possibly in reverse_proxy) and will bubble up to server.go's ServeHTTP which is the entrypoint for the handlers.

From there, Caddy will try to invoke the error handler chain (see https://caddyserver.com/docs/caddyfile/directives/handle_errors) if any is defined. So you get to choose what happens if an error happens.

I think you can use an expression matcher like this maybe (i.e. the error message here https://github.com/golang/go/blob/ab4085ce84f8378b4ec2dfdbbc44c98cb92debe5/src/net/http/request.go#L1178):

handle_errors {
	@bodyTooLarge expression `{http.error.status_text} == "http: request body too large"`
	handle @bodyTooLarge {
		respond "Oops, you tried to send too much data" 413
	}
}

@mholt
Copy link
Member

mholt commented Jul 12, 2021

I hadn't thought of that, I suppose that might be possible. Haven't tried it though.

@francislavoie
Copy link
Member

Actually == comparison might not be precise enough here, might need to use a contains:

expression `{http.error.status_text}.contains("http: request body too large")`

YMMV. I haven't tried this. Just a hunch.

@airblade
Copy link

Thank you both for the explanations. I'm not too familiar with Go – sorry for being slow on the uptake.

Yes, I'm using reverse_proxy over a Unix socket to my upstream app server. Instead of trying to deduce from the code what would happen when uploading a too-large file, I just tried it. The upstream app server never saw the uploaded file, as I would expect. Caddy logged a 502 error (extract below):

{
  "level": "error",
  "logger": "http.log.error.log0",
  "msg": "http: request body too large",
  "request": {
    "proto": "HTTP/2.0",
    "method": "POST",
    "headers": {
      "Content-Length": [
        "150956774"
      ],
      "Content-Type": [
        "multipart/form-data; boundary=----WebKitFormBoundaryb8nKVz5ofss7vuyX"
      ]
    },
  },
  "duration": 5.752661917,
  "status": 502,
  "err_id": "ijuczeucu",
  "err_trace": "reverseproxy.statusError (reverseproxy.go:857)"
}

So to convert this into a 413 status code I would need to set up my own error handling, as above? I can certainly do that.

@mholt This is my first time using Caddy after years of Nginx. It is fantastic and I will not be going back :)

@francislavoie
Copy link
Member

Yeah, I think that's right. Try adding handle_errors and see if it changes what the response looks like.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants