roadrunner icon indicating copy to clipboard operation
roadrunner copied to clipboard

[🐛 BUG]: Unable to upload file when raw_body enabled

Open m157y opened this issue 1 year ago • 5 comments

No duplicates 🥲.

  • [X] I have searched for a similar issue in our bug tracker and didn't find any solutions.

What happened?

I'm trying to upload file, but RR server is failing.

Issue looks pretty similar to https://github.com/roadrunner-server/roadrunner/issues/1765, but it's already fixed and released, but my problem is still here.

Version (rr --version)

2023.3.8 (build time: 2023-12-14T16:05:31+0000, go1.21.5), OS: darwin, arch: arm64

How to reproduce the issue?

On file upload with raw_body: true will RR fail.

Of course, firstly I was thought that there is some issue with app code, so I've simplified worker as much as possible and if you'll try to upload file to worker like attached below it will fail anyway.

<?php

declare(strict_types=1);

require __DIR__ . '/../vendor/autoload.php';

$worker = new \Spiral\RoadRunner\Http\PSR7Worker(
    \Spiral\RoadRunner\Worker::create(),
    new \Nyholm\Psr7\Factory\Psr17Factory(),
    new \Nyholm\Psr7\Factory\Psr17Factory(),
    new \Nyholm\Psr7\Factory\Psr17Factory(),
);

while ($request = $worker->waitRequest()) {
    try {
        $worker->respond(new \Nyholm\Psr7\Response());
    } catch (Throwable $e) {
        $worker->getWorker()->error((string) $e);
    }
}

.rr.yaml which will reproduce this error

version: '3'

rpc:
  listen: tcp://127.0.0.1:6001

server:
  command: "php src/worker.php"
  relay: pipes

logs:
  mode: development
  level: debug
  encoding: console
  output: stderr
  err_output: stderr

http:
  address: 127.0.0.1:8080
  internal_error_code: 505
  access_logs: false
  raw_body: true
  middleware: [ "static" ]
  uploads:
    dir: "/tmp"
  static:
    dir: "public/"
    forbid: [ "index.php" ]

But if you'll change raw_body: false it'll work flawless

Relevant log output

2023-12-16T13:44:54+0000	ERROR	http        	internal server error	{"message": "http_plugin: 2023/12/16 13:44:54 http: panic serving 127.0.0.1:53182: interface conversion: interface {} is handler.dataTree, not []uint8\ngoroutine 210 [running]:\nnet/http.(*conn).serve.func1()\n\tnet/http/server.go:1868 +0xb0\npanic({0x103d47920?, 0x1400011c7e0?})\n\truntime/panic.go:920 +0x26c\ngithub.com/roadrunner-server/http/v4/handler.(*Request).Payload(...)\n\tgithub.com/roadrunner-server/http/[email protected]/handler/request.go:172\ngithub.com/roadrunner-server/http/v4/handler.(*Handler).ServeHTTP(0x1400086c000, {0x1040671e0, 0x140000a64e0}, 0x1022e97b0?)\n\tgithub.com/roadrunner-server/http/[email protected]/handler/handler.go:139 +0x1764\ngithub.com/roadrunner-server/http/v4.(*Plugin).ServeHTTP(0x1400088df40, {0x1040671e0, 0x140000a64e0}, 0x14000c32100)\n\tgithub.com/roadrunner-server/http/[email protected]/plugin.go:205 +0x3f0\ngithub.com/roadrunner-server/http/v4.(*Plugin).applyBundledMiddleware.MaxRequestSize.func1({0x1040671e0, 0x140000a64e0}, 0x3?)\n\tgithub.com/roadrunner-server/http/[email protected]/middleware/maxRequest.go:15 +0xb0\nnet/http.HandlerFunc.ServeHTTP(0x14001006200?, {0x1040671e0?, 0x140000a64e0?}, 0x103558d38?)\n\tnet/http/server.go:2136 +0x38\ngithub.com/roadrunner-server/http/v4.(*Plugin).applyBundledMiddleware.NewLogMiddleware.(*lm).Log.func5({0x1040672d0, 0x1400099a078}, 0x0?)\n\tgithub.com/roadrunner-server/http/[email protected]/middleware/log.go:125 +0x140\nnet/http.HandlerFunc.ServeHTTP(0x0?, {0x1040672d0?, 0x1400099a078?}, 0x1?)\n\tnet/http/server.go:2136 +0x38\ngithub.com/roadrunner-server/static/v4.(*Plugin).Middleware.func1({0x1040672d0, 0x1400099a078}, 0x14001006200)\n\tgithub.com/roadrunner-server/static/[email protected]/plugin.go:149 +0x4e8\nnet/http.HandlerFunc.ServeHTTP(0x1400092c050?, {0x1040672d0?, 0x1400099a078?}, 0xc1578855a02b0028?)\n\tnet/http/server.go:2136 +0x38\ngithub.com/roadrunner-server/prometheus/v4.(*Plugin).Middleware.func1({0x1040660c8, 0x140009b6460}, 0x14001006200)\n\tgithub.com/roadrunner-server/prometheus/[email protected]/plugin.go:131 +0x464\nnet/http.HandlerFunc.ServeHTTP(0x10405f070?, {0x1040660c8?, 0x140009b6460?}, 0x6?)\n\tnet/http/server.go:2136 +0x38\nnet/http.serverHandler.ServeHTTP(...)\n\tnet/http/server.go:2938\nnet/http.(*conn).serve(0x14000c621b0, {0x10406e968, 0x14000bd01b0})\n\tnet/http/server.go:2009 +0x5b0\ncreated by net/http.(*Server).Serve in goroutine 110\n\tnet/http/server.go:3086 +0x4cc\n"}

m157y avatar Dec 16 '23 13:12 m157y

Hey @m157y 👋 Please attach at least a cURL sample request to reproduce your behavior.

rustatian avatar Dec 16 '23 14:12 rustatian

Sure

curl 'http://localhost:8080/' \
  -H 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryCeAZDfHPsreuikmt' \
  --data-raw $'------WebKitFormBoundaryCeAZDfHPsreuikmt\r\nContent-Disposition: form-data; name="newsItem[url]"\r\n\r\ntest\r\n------WebKitFormBoundaryCeAZDfHPsreuikmt\r\nContent-Disposition: form-data; name="newsItem[title]"\r\n\r\nTest\r\n------WebKitFormBoundaryCeAZDfHPsreuikmt\r\nContent-Disposition: form-data; name="newsItem[preview]"\r\n\r\nTest news\r\n------WebKitFormBoundaryCeAZDfHPsreuikmt\r\nContent-Disposition: form-data; name="newsItem[text]"\r\n\r\nTest\r\n------WebKitFormBoundaryCeAZDfHPsreuikmt\r\nContent-Disposition: form-data; name="newsItem[imageUrl]"; filename="600x600.jpeg"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundaryCeAZDfHPsreuikmt\r\nContent-Disposition: form-data; name="newsItem[isActive]"\r\n\r\n0\r\n------WebKitFormBoundaryCeAZDfHPsreuikmt--\r\n'

m157y avatar Dec 16 '23 14:12 m157y

Cool, thanks. I'm currently working on updating and removing this raw_body option at all.

rustatian avatar Dec 16 '23 16:12 rustatian

I double-checked this case and I guess I should improve the docs, because multipart data comes to the worker already parsed (kind of raw format). So, this is completely ok to not use raw_body with multipart (most use-cases for this flag is for the url-encoded data). btw, we're moving to the protobuf data format between the worker and RR (instead of JSON), and soon this option would be deprecated and all will be in a kind of raw format.

rustatian avatar Dec 16 '23 23:12 rustatian

ref: #1696

rustatian avatar Dec 17 '23 12:12 rustatian