Flesh out content repo; modify templating to support headers

Edit content-repo.yaml to include examples and headers.
Restructure content module to conform to the module template.
Adjust the HTTP API template to give 1 more char to the response
param to fit "Content-Disposition" correctly.
Edit the templating system to support displaying enums for
swagger APIs (before it was just JSON schema). Also add support
for introspecting headers from swagger. Finally, replace - with
_ when forming the {{ template_var }} else things whine.
pull/977/head
Kegan Dougal 9 years ago
parent 4a7a682c0f
commit 87b6dd845e

@ -15,16 +15,22 @@ paths:
summary: Upload some content to the content repository.
produces: ["application/json"]
parameters:
- in: header
name: Content-Type
type: string
description: The content type of the file being uploaded
x-example: "Content-Type: audio/mpeg"
- in: body
name: content
name: "<content>"
description: The content to be uploaded.
required: true
schema:
type: string
example: "<bytes>"
format: byte
responses:
200:
description: Information about the uploaded content.
description: The MXC URI for the uploaded content.
schema:
type: object
required: ["content_uri"]
@ -32,6 +38,11 @@ paths:
content_uri:
type: string
description: "The MXC URI to the uploaded content."
examples:
"application/json": |-
{
"content_uri": "mxc://example.com/AQwafuaFswefuhsfAFAgsw"
}
"/download/{serverName}/{mediaId}":
get:
summary: "Download content from the content repository."
@ -40,20 +51,32 @@ paths:
- in: path
type: string
name: serverName
x-example: matrix.org
required: true
description: |
The server name from the ``mxc://`` URI (the authoritory component)
- in: path
type: string
name: mediaId
x-example: ascERGshawAWawugaAcauga
required: true
description: |
The media ID from the ``mxc://`` URI (the path component)
responses:
200:
description: "The content downloaded."
description: "The content that was previously uploaded."
headers:
Content-Type:
description: "The content type of the file that was previously uploaded."
x-example: "audio/mpeg"
type: "string"
Content-Disposition:
description: "The name of the file that was previously uploaded, if set."
x-example: "attachment;filename=03-cool.mp3"
type: "string"
schema:
type: file
name: "<file>"
"/thumbnail/{serverName}/{mediaId}":
get:
summary: "Download a thumbnail of the content from the content repository."
@ -63,31 +86,47 @@ paths:
type: string
name: serverName
required: true
x-example: matrix.org
description: |
The server name from the ``mxc://`` URI (the authoritory component)
- in: path
type: string
name: mediaId
x-example: ascERGshawAWawugaAcauga
required: true
description: |
The media ID from the ``mxc://`` URI (the path component)
- in: query
type: integer
x-example: 64
name: width
description: The desired width of the thumbnail.
description: |-
The *desired* width of the thumbnail. The actual thumbnail may not
match the size specified.
- in: query
type: integer
x-example: 64
name: height
description: The desired height of the thumbnail.
description: |-
The *desired* height of the thumbnail. The actual thumbnail may not
match the size specified.
- in: query
type: string
enum: ["crop", "scale"]
name: method
x-example: "scale"
description: The desired resizing method.
responses:
200:
description: "A thumbnail of the requested content."
headers:
Content-Type:
description: "The content type of the thumbnail."
x-example: "image/jpeg"
type: "string"
enum: ["image/jpeg", "image/png"]
schema:
type: file
name: "<file>"

@ -3,8 +3,23 @@ Content repository
.. _module:content:
HTTP API
--------
This module allows users to upload content to their homeserver which is
retrievable from other homeservers. Its' purpose is to allow users to share
attachments in a room. Content locations are represented as Matrix Content (MXC)
URIs. They look like::
mxc://<server-name>/<media-id>
<server-name> : The name of the homeserver where this content can be found, e.g. matrix.org
<media-id> : An opaque ID which identifies the content.
Client behaviour
----------------
Clients can upload and download content using the following HTTP APIs.
{{content_repo_http_api}}
Uploads are POSTed to a resource which returns a token which is used to GET
the download. Uploads are POSTed to the sender's local homeserver, but are
@ -49,6 +64,9 @@ width and height are close to the requested size and the aspect matches
the requested size. The client should scale the image if it needs to fit
within a given rectangle.
Server behaviour
----------------
Homeservers may generate thumbnails for content uploaded to remote
homeservers themselves or may rely on the remote homeserver to thumbnail
the content. Homeservers may return thumbnails of a different size to that
@ -58,13 +76,19 @@ Homeservers must never upscale images.
Security considerations
-----------------------
The HTTP GET endpoint does not require any authentication. Knowing the URL of
the content is sufficient to retrieve the content, even if the entity isn't in
the room.
Homeservers have additional concerns:
- Clients may try to upload very large files. Homeservers should not store files
that are too large and should not serve them to clients.
- Clients may try to upload very large images. Homeservers should not attempt to
generate thumbnails for images that are too large.
- Remote homeservers may host very large files or images. Homeserver should not
- Remote homeservers may host very large files or images. Homeservers should not
proxy or thumbnail large files or images from remote homeservers.
- Clients may try to upload a large number of files. Homeservers should limit the

@ -31,18 +31,18 @@ Response format:
{% for table in endpoint.res_tables -%}
{{"``"+table.title+"``" if table.title else "" }}
================== ================= ===========================================
=================== ================= ==========================================
Param Type Description
================== ================= ===========================================
=================== ================= ==========================================
{% for row in table.rows -%}
{# -#}
{# Row type needs to prepend spaces to line up with the type column (19 ch) -#}
{# Row type needs to prepend spaces to line up with the type column (20 ch) -#}
{# Desc needs to prepend the required text (maybe) and prepend spaces too -#}
{# It also needs to then wrap inside the desc col (43 ch width) -#}
{# It also needs to then wrap inside the desc col (42 ch width) -#}
{# -#}
{{row.key}}{{row.type|indent(19-row.key|length)}}{{row.desc|wrap(43,row.req_str | indent(18 - (row.type|length))) |indent_block(37)}}
{{row.key}}{{row.type|indent(20-row.key|length)}}{{row.desc|wrap(42,row.req_str | indent(18 - (row.type|length))) |indent_block(38)}}
{% endfor -%}
================== ================= ===========================================
=================== ================= ==========================================
{% endfor %}
{% endif -%}

@ -151,6 +151,13 @@ class MatrixUnits(Units):
# assign value expected for this param
val_type = param.get("type") # integer/string
if param.get("enum"):
val_type = "enum"
desc += (
" One of: %s" % json.dumps(param.get("enum"))
)
refType = Units.prop(param, "schema/$ref/") # Error,Event
schemaFmt = Units.prop(param, "schema/format") # bytes e.g. uploads
if not val_type and refType:
@ -255,7 +262,7 @@ class MatrixUnits(Units):
res_type = Units.prop(good_response, "schema/type")
if res_type and res_type not in ["object", "array"]:
# response is a raw string or something like that
endpoint["res_tables"].append({
good_table = {
"title": None,
"rows": [{
"key": good_response["schema"].get("name", ""),
@ -263,7 +270,16 @@ class MatrixUnits(Units):
"desc": res.get("description", ""),
"req_str": ""
}]
})
}
if good_response.get("headers"):
for (header_name, header) in good_response.get("headers").iteritems():
good_table["rows"].append({
"key": header_name,
"type": "Header<" + header["type"] + ">",
"desc": header["description"],
"req_str": ""
})
endpoint["res_tables"].append(good_table)
elif res_type and Units.prop(good_response, "schema/properties"):
# response is an object:
schema = good_response["schema"]
@ -328,7 +344,7 @@ class MatrixUnits(Units):
self.log("Reading swagger API: %s" % filename)
with open(os.path.join(path, filename), "r") as f:
# strip .yaml
group_name = filename[:-5]
group_name = filename[:-5].replace("-", "_")
api = yaml.load(f.read())
api["__meta"] = self._load_swagger_meta(api, group_name)
apis[group_name] = api

Loading…
Cancel
Save