Form upload

Last Updated: May 16, 2017

Form upload is when an object is uploaded using the Post Object request in the OSS API. Form upload bypasses objects being forwarded to the server, and instead uploads objects directly from the client to OSS, reducing bottlenecks at the server end due to object resizing.

Applicable scenarios

The following example scenarios demonstrate the application of the form upload process in a career search website environment:

Without using form upload

  1. A website user uploads their object (a resume).
  2. The website server responds to the upload page.
  3. The resume is uploaded to the server.
  4. The server uploads the resume to OSS.

Using form upload

  1. A website user uploads their resume.
  2. The website server responds to the upload page.
  3. The resume is uploaded to OSS.

Upload restrictions

  • The maximum object size permitted for each form upload is 5 GB.
  • Naming restrictions:
    • The name must be UTF-8 encoded.
    • The length must be between 1-1,023 bytes
    • The name cannot start with a backslash “/“ or forward slash “\”.

Upload security and authorization

To prevent unauthorized third parties from uploading objects to the developer’s bucket, OSS provides bucket- and object-level access permission control. For details, refer to Access Control.

In addition to bucket-level and object-level access permissions, OSS also provides account-level authorization to authorize third-party uploads. For details, refer to Post Object.

Basic process

  1. Construct a post policy. For more details, refer to Post Policy.
    In this policy example:
    • The expiration time for site user uploads is 2115-01-27T10:56:19Z (in actual usage this setting is determined based on site requirements).
    • The maximum upload file size is 104,857,600 bytes.
    • Python code is used.
    • The policy is a string in JSON format: policy="{\"expiration\":\"2115-01-27T10:56:19Z\",\"conditions\":[[\"content-length-range\", 0, 104857600]]}".
  2. Encode the policy string using base64 encoding.
  3. Use the OSS AccessKeySecret to sign the base64 encoded policy.
  4. Construct an HTML page for uploads.
  5. Open the HTML page and select the file to upload. The following is an example output:

    1. #coding=utf8
    2. import md5
    3. import hashlib
    4. import base64
    5. import hmac
    6. from optparse import OptionParser
    7. def convert_base64(input):
    8. return base64.b64encode(input)
    9. def get_sign_policy(key, policy):
    10. return base64.b64encode(hmac.new(key, policy, hashlib.sha1).digest())
    11. def get_form(bucket, endpoint, access_key_id, access_key_secret, out):
    12. #1 Construct a Post Policy
    13. policy="{\"expiration\":\"2115-01-27T10:56:19Z\",\"conditions\":[[\"content-length-range\", 0, 1048576]]}"
    14. print("policy: %s" % policy)
    15. #2 Encode the policy string using base64 encoding
    16. base64policy = convert_base64(policy)
    17. print("base64_encode_policy: %s" % base64policy)
    18. #3 Use the OSS AccessKeySecret to sign the base64 encoded policy
    19. signature = get_sign_policy(access_key_secret, base64policy)
    20. #4 Construct an HTML page for uploads
    21. form = '''
    22. <html>
    23. <meta http-equiv=content-type content="text/html; charset=UTF-8">
    24. <head><title>OSS form upload (PostObject)</title></head>
    25. <body>
    26. <form action="http://%s.%s" method="post" enctype="multipart/form-data">
    27. <input type="text" name="OSSAccessKeyId" value="%s">
    28. <input type="text" name="policy" value="%s">
    29. <input type="text" name="Signature" value="%s">
    30. <input type="text" name="key" value="upload/${filename}">
    31. <input type="text" name="success_action_redirect" value="http://oss.aliyun.com">
    32. <input type="text" name="success_action_status" value="201">
    33. <input name="file" type="file" id="file">
    34. <input name="submit" value="Upload" type="submit">
    35. </form>
    36. </body>
    37. </html>
    38. ''' % (bucket, endpoint, access_key_id, base64policy, signature)
    39. f = open(out, "wb")
    40. f.write(form)
    41. f.close()
    42. print("form is saved into %s" % out)
    43. if __name__ == '__main__':
    44. parser = OptionParser()
    45. parser.add_option("", "--bucket", dest="bucket", help="specify ")
    46. parser.add_option("", "--endpoint", dest="endpoint", help="specify")
    47. parser.add_option("", "--id", dest="id", help="access_key_id")
    48. parser.add_option("", "--key", dest="key", help="access_key_secret")
    49. parser.add_option("", "--out", dest="out", help="out put form")
    50. (opts, args) = parser.parse_args()
    51. if opts.bucket and opts.endpoint and opts.id and opts.key and opts.out:
    52. get_form(opts.bucket, opts.endpoint, opts.id, opts.key, opts.out)
    53. else:
    54. print "python %s --bucket=your-bucket --endpoint=oss-cn-hangzhou.aliyuncs.com --id=your-access-key-id --key=your-access-key-secret --out=out-put-form-name" % __file__

    Save this code segment as post_object.py and use Python to run it.

    1. Usage:
    2. python post_object.py --bucket=Your bucket --endpoint=The bucket's OSS domain name --id=Your AccessKeyId --key=Your AccessKeySecret --out=Output file name
    3. Example:
    4. python post_object.py --bucket=oss-sample --endpoint=oss-cn-hangzhou.aliyuncs.com --id=tphpxp --key=ZQNJzf4QJRkrH4 --out=post.html

Note:

  • "success_action_redirect" value="http://oss.aliyun.com" indicates the page to navigate to after a successful upload. This can be replaced as needed.
  • "success_action_status" value="201" indicates that Status Code 201 is returned after a successful upload. This can be replaced according to site requirements.
  • If the generated HTML file is post.html, open post.html and select the file to upload. In this example, the client navigates to the OSS homepage after a successful upload.

Reference

Best practices

Thank you! We've received your feedback.