Mercurial > hg > orthanc
view Resources/Toolbox.lua @ 2248:69b0f4e8a49b
Escape multipart type parameter value in Content-Type header
## Summary
Multipart responses do not quote/escape the value of their type
parameter (the subtype) even though it always contains at least one
special character (the slash "/"), which confuses standard-compliant
HTTP clients.
## Details
The Content-Type header in HTTP is in RFC 7231, Section 3.1.1.5:
https://tools.ietf.org/html/rfc7231#section-3.1.1.5
The section defers to the media type section (3.1.1.1) for the syntax of
the media type:
https://tools.ietf.org/html/rfc7231#section-3.1.1.1
This states that a parameter value can be quoted:
parameter = token "=" ( token / quoted-string )
A parameter value that matches the token production can be transmitted
either as a token or within a quoted-string. The quoted and unquoted
values are equivalent.
Tokens are defined in RFC 7230, Section 3.2.6 (via RFC 7231, appendix
C):
https://tools.ietf.org/html/rfc7231#appendix-C
https://tools.ietf.org/html/rfc7230#section-3.2.6
Here we observe that tokens cannot contain a slash "/" character:
token = 1*tchar
tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
/ "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
/ DIGIT / ALPHA
; any VCHAR, except delimiters
Delimiters are chosen from the set of US-ASCII visual characters not
allowed in a token (DQUOTE and "(),/:;<=>?@[\]{}").
However, the current implementation does not quote/escape the value of
the type parameter:
multipart/related; type=application/dicom
Instead, it should be:
multipart/related; type="application/dicom"
All of this also seems to apply to the MIME Content-Type header
definition, even though it is a little different:
https://www.iana.org/assignments/message-headers
https://tools.ietf.org/html/rfc2045#section-5.1
https://tools.ietf.org/html/rfc2387
author | Thibault Nélis <tn@osimis.io> |
---|---|
date | Mon, 16 Jan 2017 13:07:11 +0100 |
parents | 6406f5493d92 |
children |
line wrap: on
line source
--[[ PrintRecursive(struct, [limit], [indent]) Recursively print arbitrary data. Set limit (default 100) to stanch infinite loops. Indents tables as [KEY] VALUE, nested tables as [KEY] [KEY]...[KEY] VALUE Set indent ("") to prefix each line: Mytable [KEY] [KEY]...[KEY] VALUE Source: https://gist.github.com/stuby/5445834#file-rprint-lua --]] function PrintRecursive(s, l, i) -- recursive Print (structure, limit, indent) l = (l) or 100; -- default item limit i = i or ""; -- indent string if (l<1) then print "ERROR: Item limit reached."; return l-1 end; local ts = type(s); if (ts ~= "table") then print (i,ts,s); return l-1 end print (i,ts); -- print "table" for k,v in pairs(s) do -- print "[KEY] VALUE" l = PrintRecursive(v, l, i.."\t["..tostring(k).."]"); if (l < 0) then break end end return l end function _InitializeJob() _job = {} end function _AccessJob() return _job end function SendToModality(resourceId, modality, localAet) if resourceId == nil then error('Cannot send a nonexistent resource') end table.insert(_job, { Operation = 'store-scu', Resource = resourceId, Modality = modality, LocalAet = localAet }) return resourceId end function SendToPeer(resourceId, peer) if resourceId == nil then error('Cannot send a nonexistent resource') end table.insert(_job, { Operation = 'store-peer', Resource = resourceId, Peer = peer }) return resourceId end function Delete(resourceId) if resourceId == nil then error('Cannot delete a nonexistent resource') end table.insert(_job, { Operation = 'delete', Resource = resourceId }) return nil -- Forbid chaining end function ModifyResource(resourceId, replacements, removals, removePrivateTags) if resourceId == nil then error('Cannot modify a nonexistent resource') end if resourceId == '' then error('Cannot modify twice an resource'); end table.insert(_job, { Operation = 'modify', Resource = resourceId, Replace = replacements, Remove = removals, RemovePrivateTags = removePrivateTags }) return '' -- Chain with another operation end function ModifyInstance(resourceId, replacements, removals, removePrivateTags) return ModifyResource(resourceId, replacements, removals, removePrivateTags) end -- This function is only applicable to individual instances function CallSystem(resourceId, command, args) if resourceId == nil then error('Cannot execute a system call on a nonexistent resource') end if command == nil then error('No command was specified for system call') end table.insert(_job, { Operation = 'call-system', Resource = resourceId, Command = command, Arguments = args }) return resourceId end print('Lua toolbox installed')