@@ -2092,6 +2092,24 @@ def dispatch(self, method, uri, input):
20922092 msg = _ ("Api rate limits exceeded. Please wait: %s seconds." ) % retry_after
20932093 output = self .error_obj (429 , msg , source = "ApiRateLimiter" )
20942094
2095+ # expose these headers to rest clients. Otherwise they can't
2096+ # respond to:
2097+ # rate limiting (*RateLimit*, Retry-After)
2098+ # obsolete API endpoint (Sunset)
2099+ # options request to discover supported methods (Allow)
2100+ self .client .setHeader (
2101+ "Access-Control-Expose-Headers" ,
2102+ ", " .join ([
2103+ "X-RateLimit-Limit" ,
2104+ "X-RateLimit-Remaining" ,
2105+ "X-RateLimit-Reset" ,
2106+ "X-RateLimit-Limit-Period" ,
2107+ "Retry-After" ,
2108+ "Sunset" ,
2109+ "Allow" ,
2110+ ])
2111+ )
2112+
20952113 return self .format_dispatch_output (
20962114 self .__default_accept_type ,
20972115 output ,
@@ -2126,6 +2144,75 @@ def dispatch(self, method, uri, input):
21262144 'Ignoring X-HTTP-Method-Override using %s request on %s' ,
21272145 method .upper (), uri )
21282146
2147+ # parse Accept header and get the content type
2148+ # Acceptable types ordered with preferred one first
2149+ # in list.
2150+ try :
2151+ accept_header = parse_accept_header (headers .get ('Accept' ))
2152+ except UsageError as e :
2153+ output = self .error_obj (406 , _ ("Unable to parse Accept Header. %(error)s. "
2154+ "Acceptable types: %(acceptable_types)s" ) % {
2155+ 'error' : e .args [0 ],
2156+ 'acceptable_types' : " " .join (sorted (self .__accepted_content_type .keys ()))})
2157+ accept_header = []
2158+
2159+ if not accept_header :
2160+ accept_type = self .__default_accept_type
2161+ else :
2162+ accept_type = None
2163+ for part in accept_header :
2164+ if accept_type :
2165+ # we accepted the best match, stop searching for
2166+ # lower quality matches.
2167+ break
2168+ if part [0 ] in self .__accepted_content_type :
2169+ accept_type = self .__accepted_content_type [part [0 ]]
2170+ # Version order:
2171+ # 1) accept header version=X specifier
2172+ # application/vnd.x.y; version=1
2173+ # 2) from type in accept-header type/subtype-vX
2174+ # application/vnd.x.y-v1
2175+ # 3) from @apiver in query string to make browser
2176+ # use easy
2177+ # This code handles 1 and 2. Set api_version to none
2178+ # to trigger @apiver parsing below
2179+ # Places that need the api_version info should
2180+ # use default if version = None
2181+ try :
2182+ self .api_version = int (part [1 ]['version' ])
2183+ except KeyError :
2184+ self .api_version = None
2185+ except (ValueError , TypeError ):
2186+ # TypeError if int(None)
2187+ msg = ("Unrecognized api version: %s. "
2188+ "See /rest without specifying api version "
2189+ "for supported versions." % (
2190+ part [1 ]['version' ]))
2191+ output = self .error_obj (400 , msg )
2192+
2193+ # get the request format for response
2194+ # priority : extension from uri (/rest/data/issue.json),
2195+ # header (Accept: application/json, application/xml)
2196+ # default (application/json)
2197+ ext_type = os .path .splitext (urlparse (uri ).path )[1 ][1 :]
2198+
2199+ # Check to see if the length of the extension is less than 6.
2200+ # this allows use of .vcard for a future use in downloading
2201+ # user info. It also allows passing through larger items like
2202+ # JWT that has a final component > 6 items. This method also
2203+ # allow detection of mistyped types like jon for json.
2204+ if ext_type and (len (ext_type ) < 6 ):
2205+ # strip extension so uri make sense
2206+ # .../issue.json -> .../issue
2207+ uri = uri [:- (len (ext_type ) + 1 )]
2208+ else :
2209+ ext_type = None
2210+
2211+ # headers.get('Accept') is never empty if called here.
2212+ # accept_type will be set to json if there is no Accept header
2213+ # accept_type wil be empty only if there is an Accept header
2214+ # with invalid values.
2215+ data_type = ext_type or accept_type or headers .get ('Accept' ) or "invalid"
21292216 if method .upper () == 'OPTIONS' :
21302217 # add access-control-allow-* access-control-max-age to support
21312218 # CORS preflight
0 commit comments