@@ -295,6 +295,36 @@ module AiohttpWebModel {
295295 DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
296296 }
297297
298+ /**
299+ * Provides models for the `aiohttp.web.Response` class
300+ *
301+ * See https://docs.aiohttp.org/en/stable/web_reference.html#response-classes
302+ */
303+ module Response {
304+ /**
305+ * A source of instances of `aiohttp.web.Response`, extend this class to model new instances.
306+ *
307+ * This can include instantiations of the class, return values from function
308+ * calls, or a special parameter that will be set when functions are called by an external
309+ * library.
310+ *
311+ * Use `Response::instance()` predicate to get
312+ * references to instances of `aiohttp.web.Response`.
313+ */
314+ abstract class InstanceSource extends DataFlow:: LocalSourceNode { }
315+
316+ /** Gets a reference to an instance of `aiohttp.web.Response`. */
317+ private DataFlow:: LocalSourceNode instance ( DataFlow:: TypeTracker t ) {
318+ t .start ( ) and
319+ result instanceof InstanceSource
320+ or
321+ exists ( DataFlow:: TypeTracker t2 | result = instance ( t2 ) .track ( t2 , t ) )
322+ }
323+
324+ /** Gets a reference to an instance of `aiohttp.web.Response`. */
325+ DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
326+ }
327+
298328 /**
299329 * Provides models for the `aiohttp.StreamReader` class
300330 *
@@ -488,35 +518,46 @@ module AiohttpWebModel {
488518 * - https://docs.aiohttp.org/en/stable/web_quickstart.html#aiohttp-web-exceptions
489519 */
490520 class AiohttpWebResponseInstantiation extends HTTP:: Server:: HttpResponse:: Range ,
491- DataFlow:: CallCfgNode {
521+ Response:: InstanceSource , DataFlow:: CallCfgNode {
522+ API:: Node apiNode ;
523+
492524 AiohttpWebResponseInstantiation ( ) {
493- this = API:: moduleImport ( "aiohttp" ) .getMember ( "web" ) .getMember ( "Response" ) .getACall ( )
494- or
495- exists ( string httpExceptionClassName |
496- httpExceptionClassName in [
497- "HTTPException" , "HTTPSuccessful" , "HTTPOk" , "HTTPCreated" , "HTTPAccepted" ,
498- "HTTPNonAuthoritativeInformation" , "HTTPNoContent" , "HTTPResetContent" ,
499- "HTTPPartialContent" , "HTTPRedirection" , "HTTPMultipleChoices" , "HTTPMovedPermanently" ,
500- "HTTPFound" , "HTTPSeeOther" , "HTTPNotModified" , "HTTPUseProxy" , "HTTPTemporaryRedirect" ,
501- "HTTPPermanentRedirect" , "HTTPError" , "HTTPClientError" , "HTTPBadRequest" ,
502- "HTTPUnauthorized" , "HTTPPaymentRequired" , "HTTPForbidden" , "HTTPNotFound" ,
503- "HTTPMethodNotAllowed" , "HTTPNotAcceptable" , "HTTPProxyAuthenticationRequired" ,
504- "HTTPRequestTimeout" , "HTTPConflict" , "HTTPGone" , "HTTPLengthRequired" ,
505- "HTTPPreconditionFailed" , "HTTPRequestEntityTooLarge" , "HTTPRequestURITooLong" ,
506- "HTTPUnsupportedMediaType" , "HTTPRequestRangeNotSatisfiable" , "HTTPExpectationFailed" ,
507- "HTTPMisdirectedRequest" , "HTTPUnprocessableEntity" , "HTTPFailedDependency" ,
508- "HTTPUpgradeRequired" , "HTTPPreconditionRequired" , "HTTPTooManyRequests" ,
509- "HTTPRequestHeaderFieldsTooLarge" , "HTTPUnavailableForLegalReasons" , "HTTPServerError" ,
510- "HTTPInternalServerError" , "HTTPNotImplemented" , "HTTPBadGateway" ,
511- "HTTPServiceUnavailable" , "HTTPGatewayTimeout" , "HTTPVersionNotSupported" ,
512- "HTTPVariantAlsoNegotiates" , "HTTPInsufficientStorage" , "HTTPNotExtended" ,
513- "HTTPNetworkAuthenticationRequired"
514- ] and
515- this =
516- API:: moduleImport ( "aiohttp" ) .getMember ( "web" ) .getMember ( httpExceptionClassName ) .getACall ( )
525+ this = apiNode .getACall ( ) and
526+ (
527+ apiNode = API:: moduleImport ( "aiohttp" ) .getMember ( "web" ) .getMember ( "Response" )
528+ or
529+ exists ( string httpExceptionClassName |
530+ httpExceptionClassName in [
531+ "HTTPException" , "HTTPSuccessful" , "HTTPOk" , "HTTPCreated" , "HTTPAccepted" ,
532+ "HTTPNonAuthoritativeInformation" , "HTTPNoContent" , "HTTPResetContent" ,
533+ "HTTPPartialContent" , "HTTPRedirection" , "HTTPMultipleChoices" ,
534+ "HTTPMovedPermanently" , "HTTPFound" , "HTTPSeeOther" , "HTTPNotModified" ,
535+ "HTTPUseProxy" , "HTTPTemporaryRedirect" , "HTTPPermanentRedirect" , "HTTPError" ,
536+ "HTTPClientError" , "HTTPBadRequest" , "HTTPUnauthorized" , "HTTPPaymentRequired" ,
537+ "HTTPForbidden" , "HTTPNotFound" , "HTTPMethodNotAllowed" , "HTTPNotAcceptable" ,
538+ "HTTPProxyAuthenticationRequired" , "HTTPRequestTimeout" , "HTTPConflict" , "HTTPGone" ,
539+ "HTTPLengthRequired" , "HTTPPreconditionFailed" , "HTTPRequestEntityTooLarge" ,
540+ "HTTPRequestURITooLong" , "HTTPUnsupportedMediaType" , "HTTPRequestRangeNotSatisfiable" ,
541+ "HTTPExpectationFailed" , "HTTPMisdirectedRequest" , "HTTPUnprocessableEntity" ,
542+ "HTTPFailedDependency" , "HTTPUpgradeRequired" , "HTTPPreconditionRequired" ,
543+ "HTTPTooManyRequests" , "HTTPRequestHeaderFieldsTooLarge" ,
544+ "HTTPUnavailableForLegalReasons" , "HTTPServerError" , "HTTPInternalServerError" ,
545+ "HTTPNotImplemented" , "HTTPBadGateway" , "HTTPServiceUnavailable" ,
546+ "HTTPGatewayTimeout" , "HTTPVersionNotSupported" , "HTTPVariantAlsoNegotiates" ,
547+ "HTTPInsufficientStorage" , "HTTPNotExtended" , "HTTPNetworkAuthenticationRequired"
548+ ] and
549+ apiNode = API:: moduleImport ( "aiohttp" ) .getMember ( "web" ) .getMember ( httpExceptionClassName )
550+ )
517551 )
518552 }
519553
554+ /**
555+ * INTERNAL: Do not use.
556+ *
557+ * Get the internal `API::Node` that this is call of.
558+ */
559+ API:: Node getApiNode ( ) { result = apiNode }
560+
520561 override DataFlow:: Node getBody ( ) {
521562 result in [ this .getArgByName ( "text" ) , this .getArgByName ( "body" ) ]
522563 }
@@ -534,6 +575,11 @@ module AiohttpWebModel {
534575 }
535576 }
536577
578+ /** Gets an HTTP response instance. */
579+ private API:: Node aiohttpResponseInstance ( ) {
580+ result = any ( AiohttpWebResponseInstantiation call ) .getApiNode ( ) .getReturn ( )
581+ }
582+
537583 /**
538584 * An instantiation of aiohttp.web HTTP redirect exception.
539585 *
@@ -559,4 +605,62 @@ module AiohttpWebModel {
559605 result in [ this .getArg ( 0 ) , this .getArgByName ( "location" ) ]
560606 }
561607 }
608+
609+ /**
610+ * A call to `set_cookie` on a HTTP Response.
611+ */
612+ class AiohttpResponseSetCookieCall extends HTTP:: Server:: CookieWrite:: Range , DataFlow:: CallCfgNode {
613+ AiohttpResponseSetCookieCall ( ) {
614+ this = aiohttpResponseInstance ( ) .getMember ( "set_cookie" ) .getACall ( )
615+ }
616+
617+ override DataFlow:: Node getHeaderArg ( ) { none ( ) }
618+
619+ override DataFlow:: Node getNameArg ( ) { result in [ this .getArg ( 0 ) , this .getArgByName ( "name" ) ] }
620+
621+ override DataFlow:: Node getValueArg ( ) { result in [ this .getArg ( 1 ) , this .getArgByName ( "value" ) ] }
622+ }
623+
624+ /**
625+ * A call to `del_cookie` on a HTTP Response.
626+ */
627+ class AiohttpResponseDelCookieCall extends HTTP:: Server:: CookieWrite:: Range , DataFlow:: CallCfgNode {
628+ AiohttpResponseDelCookieCall ( ) {
629+ this = aiohttpResponseInstance ( ) .getMember ( "del_cookie" ) .getACall ( )
630+ }
631+
632+ override DataFlow:: Node getHeaderArg ( ) { none ( ) }
633+
634+ override DataFlow:: Node getNameArg ( ) { result in [ this .getArg ( 0 ) , this .getArgByName ( "name" ) ] }
635+
636+ override DataFlow:: Node getValueArg ( ) { none ( ) }
637+ }
638+
639+ /**
640+ * A dict-like write to an item of the `cookies` attribute on a HTTP response, such as
641+ * `response.cookies[name] = value`.
642+ */
643+ class AiohttpResponseCookieSubscriptWrite extends HTTP:: Server:: CookieWrite:: Range {
644+ DataFlow:: Node index ;
645+ DataFlow:: Node value ;
646+
647+ AiohttpResponseCookieSubscriptWrite ( ) {
648+ exists ( Assign assign , Subscript subscript |
649+ // there doesn't seem to be any _good_ choice for `this`, so just picking the
650+ // whole subscript...
651+ this .asExpr ( ) = subscript
652+ |
653+ assign .getATarget ( ) = subscript and
654+ subscript .getObject ( ) = aiohttpResponseInstance ( ) .getMember ( "cookies" ) .getAUse ( ) .asExpr ( ) and
655+ index .asExpr ( ) = subscript .getIndex ( ) and
656+ value .asExpr ( ) = assign .getValue ( )
657+ )
658+ }
659+
660+ override DataFlow:: Node getHeaderArg ( ) { none ( ) }
661+
662+ override DataFlow:: Node getNameArg ( ) { result = index }
663+
664+ override DataFlow:: Node getValueArg ( ) { result = value }
665+ }
562666}
0 commit comments