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

File upload through API returns Internal server error #1531

Closed
oniskanen opened this issue Oct 4, 2016 · 4 comments
Closed

File upload through API returns Internal server error #1531

oniskanen opened this issue Oct 4, 2016 · 4 comments
Labels
bug Issue describes a bug done Done but not yet released
Milestone

Comments

@oniskanen
Copy link

What were you doing?

I'm trying to use the OctoPrint API to upload files to the local folder on the RaspberryPi running OctoPrint. Here's an example request: http://pastebin.com/iLGHQSSu

Here's the GCODE: https://drive.google.com/file/d/0BybDJjp-fX5wX0ZjWnJtckhiLUE/view?usp=sharing

What did you expect to happen?

The file to be uploaded to RaspberryPi.

What happened instead?

The request returns HTTP 500, Internal server error. According to web UI, file upload wasn't successful. The error from octoprint.log:

2016-10-04 17:22:29,805 - octoprint - ERROR - Exception on /api/files/local [POST]
Traceback (most recent call last):
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Flask-0.10.1-py2.7.egg/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Flask-0.10.1-py2.7.egg/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Flask-0.10.1-py2.7.egg/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Flask-0.10.1-py2.7.egg/flask/app.py", line 1473, in full_dispatch_request
    rv = self.preprocess_request()
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Flask-0.10.1-py2.7.egg/flask/app.py", line 1666, in preprocess_request
    rv = func()
  File "/home/pi/oprint/local/lib/python2.7/site-packages/OctoPrint-1.2.16-py2.7.egg/octoprint/server/__init__.py", line 675, in before_request
    g.locale = self._get_locale()
  File "/home/pi/oprint/local/lib/python2.7/site-packages/OctoPrint-1.2.16-py2.7.egg/octoprint/server/__init__.py", line 543, in _get_locale
    if "l10n" in request.values:
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Werkzeug-0.8.3-py2.7.egg/werkzeug/local.py", line 336, in __getattr__
    return getattr(self._get_current_object(), name)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Werkzeug-0.8.3-py2.7.egg/werkzeug/utils.py", line 77, in __get__
    value = self.func(obj)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Werkzeug-0.8.3-py2.7.egg/werkzeug/wrappers.py", line 390, in values
    for d in self.args, self.form:
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Werkzeug-0.8.3-py2.7.egg/werkzeug/utils.py", line 77, in __get__
    value = self.func(obj)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Werkzeug-0.8.3-py2.7.egg/werkzeug/wrappers.py", line 383, in form
    self._load_form_data()
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Flask-0.10.1-py2.7.egg/flask/wrappers.py", line 165, in _load_form_data
    RequestBase._load_form_data(self)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Werkzeug-0.8.3-py2.7.egg/werkzeug/wrappers.py", line 318, in _load_form_data
    data = parser.parse_from_environ(self.environ)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Werkzeug-0.8.3-py2.7.egg/werkzeug/formparser.py", line 164, in parse_from_environ
    return self.parse(stream, mimetype, content_length, options)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Werkzeug-0.8.3-py2.7.egg/werkzeug/formparser.py", line 182, in parse
    input_stream = LimitedStream(stream, content_length)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/Werkzeug-0.8.3-py2.7.egg/werkzeug/wsgi.py", line 736, in __init__
    self._read = stream.read
AttributeError: 'unicode' object has no attribute 'read'
2016-10-04 17:34:06,720 - octoprint.server.util.sockjs - INFO - Client connection closed: 172.20.10.3

Branch & Commit or Version of OctoPrint

Version: 1.2.16 (master branch)

Link to octoprint.log

http://pastebin.com/vRwEFHD3

I have read the FAQ.

@foosel
Copy link
Member

foosel commented Oct 5, 2016

Huh. It appears to be caused by the Content-Type line for your print parameter. I can reproduce the same error with a minimal example:

POST /api/files/local HTTP/1.1
Host: localhost:5000
User-Agent: UnityPlayer/5.4.1f1 (http://unity3d.com)
Accept: */*
Accept-Encoding: identity
Content-Length: 354
Content-Type: multipart/form-data; boundary="sd4ibZFCpcreuTHRApjktFt7IKoRYB9jI33dPfSD"
X-Api-Key: test1234
X-Unity-Version: 5.4.1f1

--sd4ibZFCpcreuTHRApjktFt7IKoRYB9jI33dPfSD
Content-Type: application/octet-stream
Content-disposition: form-data; name="file"; filename="model.gcode"

M117 Test
--sd4ibZFCpcreuTHRApjktFt7IKoRYB9jI33dPfSD
Content-Type: text/plain; charset="utf-8"
Content-disposition: form-data; name="print"

false
--sd4ibZFCpcreuTHRApjktFt7IKoRYB9jI33dPfSD--

With the Content-Type line, error:

$ cat upload_1531.txt | nc localhost 5000
HTTP/1.1 500 Internal Server Error
Date: Wed, 05 Oct 2016 09:39:30 GMT
Content-Length: 93
Content-Type: text/html; charset=UTF-8
Server: TornadoServer/4.0.2

<html><title>500: Internal Server Error</title><body>500: Internal Server Error</body></html>

without it, no error:

$ cat upload_1531.txt | nc localhost 5000
HTTP/1.1 201 CREATED
Content-Type: application/json
Content-Length: 320
Location: http://localhost:5000/api/files/local/model.gcode
Cache-Control: pre-check=0, no-cache, no-store, must-revalidate, post-check=0, max-age=0
Pragma: no-cache
Expires: -1
X-Clacks-Overhead: GNU Terry Pratchett
Set-Cookie: session_P5000=.eJyrVopPK0otzlCyKikqTdVRis9MUbKqVlJIUrJS8g0JNfV1Sa-MyvWs8s3yNY3MDTSOCsnIiHIPyowK8TT1dXc19A2PrIwKcbVVqtVRykxJzSvJLKnUSywtyYgvqSxIVbLKK83JQZJBMj3CyK08MdAWrLO0OLUoHqtcLQCjSjPx.CtZb-Q.BKcnsCBalj92wd34KUrOfcEaFSI; Path=/; HttpOnly
Server: TornadoServer/4.0.2

{
  "done": true,
  "files": {
    "local": {
      "name": "model.gcode",
      "origin": "local",
      "path": "model.gcode",
      "refs": {
        "download": "http://localhost:5000/downloads/files/local/model.gcode",
        "resource": "http://localhost:5000/api/files/local/model.gcode"
      }
    }
  }
}

Stack trace in octoprint.log is the same as your's. It crashes not within OctoPrint, but within the underlying Flask, when attempting to read potential request query parameters. That's not going to be a lot of fun I fear.

@foosel foosel added the bug Issue describes a bug label Oct 5, 2016
foosel added a commit that referenced this issue Oct 5, 2016
…sues

If a content type header was present on a multipart form data part it would turn
the rewritten body into a unicode instead of a byte array, causing a later conversion
to a byte stream to not capture.

Fixed both the fact that the rewritten body would turn into unicode by making
sure the content type header was provided as byte array and fixed the byte stream
conversion to also trigger on unicode instances.

Solves #1531
@foosel foosel added the done Done but not yet released label Oct 5, 2016
@foosel
Copy link
Member

foosel commented Oct 5, 2016

Fixed on maintenance and devel branches, will be part of the next release.

@foosel foosel added this to the 1.2.17 milestone Oct 5, 2016
@oniskanen
Copy link
Author

Wow, that was quick! Thanks for the effort 👍

@foosel
Copy link
Member

foosel commented Nov 25, 2016

Forgot to close this when 1.2.17 was released

@foosel foosel closed this as completed Nov 25, 2016
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 29, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue describes a bug done Done but not yet released
Projects
None yet
Development

No branches or pull requests

2 participants