@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Allow Celerity to return "304 Not Modified" responses

Summary:
We always return HTTP 200 right now and don't send a "Last-Modified" header, so
browsers download more data then necessary if you sit on a page mashing reload
(for example).

Test Plan:
Used Charles to verify HTTP response codes from 400, 404 and 304 responses.

Mashed reload a bunch and saw that the server sent back 304s.

Changed the resource hash seed and saw 200s, then 304s on reload.

Reviewed By: tuomaspelkonen
Reviewers: tuomaspelkonen, jungejason, aran
CC: bmaurer, aran, tuomaspelkonen
Differential Revision: 253

+299 -198
+8
conf/default.conf.php
··· 337 337 // track running daemons. 338 338 'phd.pid-directory' => '/var/tmp/phd', 339 339 340 + // This value is an input to the hash function when building resource hashes. 341 + // It has no security value, but if you accidentally poison user caches (by 342 + // pushing a bad patch or having something go wrong with a CDN, e.g.) you can 343 + // change this to something else and rebuild the Celerity map to break user 344 + // caches. Unless you are doing Celerity development, it is exceptionally 345 + // unlikely that you need to modify this. 346 + 'celerity.resource-hash' => 'd9455ea150622ee044f7931dabfa52aa', 347 + 340 348 );
+4 -1
scripts/celerity_mapper.php
··· 71 71 72 72 73 73 require_once dirname(__FILE__).'/__init_script__.php'; 74 + require_once dirname(__FILE__).'/__init_env__.php'; 74 75 75 76 if ($argc != 2) { 76 77 $self = basename($argv[0]); ··· 96 97 97 98 echo "Processing ".count($files)." files"; 98 99 100 + $resource_hash = PhabricatorEnv::getEnvConfig('celerity.resource-hash'); 101 + 99 102 $file_map = array(); 100 103 foreach ($files as $path => $hash) { 101 104 echo "."; 102 105 $name = '/'.Filesystem::readablePath($path, $root); 103 106 $file_map[$name] = array( 104 - 'hash' => $hash, 107 + 'hash' => md5($hash.$name.$resource_hash), 105 108 'disk' => $path, 106 109 ); 107 110 }
+189 -189
src/__celerity_resource_map__.php
··· 9 9 celerity_register_resource_map(array( 10 10 'aphront-crumbs-view-css' => 11 11 array( 12 - 'uri' => '/res/c666a518/rsrc/css/aphront/crumbs-view.css', 12 + 'uri' => '/res/9009e6bd/rsrc/css/aphront/crumbs-view.css', 13 13 'type' => 'css', 14 14 'requires' => 15 15 array( ··· 18 18 ), 19 19 'aphront-dark-console-css' => 20 20 array( 21 - 'uri' => '/res/0417eb95/rsrc/css/aphront/dark-console.css', 21 + 'uri' => '/res/e7011594/rsrc/css/aphront/dark-console.css', 22 22 'type' => 'css', 23 23 'requires' => 24 24 array( ··· 27 27 ), 28 28 'aphront-dialog-view-css' => 29 29 array( 30 - 'uri' => '/res/9be517dc/rsrc/css/aphront/dialog-view.css', 30 + 'uri' => '/res/79613f9b/rsrc/css/aphront/dialog-view.css', 31 31 'type' => 'css', 32 32 'requires' => 33 33 array( ··· 36 36 ), 37 37 'aphront-error-view-css' => 38 38 array( 39 - 'uri' => '/res/19b27527/rsrc/css/aphront/error-view.css', 39 + 'uri' => '/res/98c5fc69/rsrc/css/aphront/error-view.css', 40 40 'type' => 'css', 41 41 'requires' => 42 42 array( ··· 45 45 ), 46 46 'aphront-form-view-css' => 47 47 array( 48 - 'uri' => '/res/82eca506/rsrc/css/aphront/form-view.css', 48 + 'uri' => '/res/dadf31b1/rsrc/css/aphront/form-view.css', 49 49 'type' => 'css', 50 50 'requires' => 51 51 array( ··· 54 54 ), 55 55 'aphront-headsup-action-list-view-css' => 56 56 array( 57 - 'uri' => '/res/fe9accb9/rsrc/css/aphront/headsup-action-list-view.css', 57 + 'uri' => '/res/71783633/rsrc/css/aphront/headsup-action-list-view.css', 58 58 'type' => 'css', 59 59 'requires' => 60 60 array( ··· 63 63 ), 64 64 'aphront-list-filter-view-css' => 65 65 array( 66 - 'uri' => '/res/50a790ae/rsrc/css/aphront/list-filter-view.css', 66 + 'uri' => '/res/e6cff171/rsrc/css/aphront/list-filter-view.css', 67 67 'type' => 'css', 68 68 'requires' => 69 69 array( ··· 72 72 ), 73 73 'aphront-pager-view-css' => 74 74 array( 75 - 'uri' => '/res/73ec8cd5/rsrc/css/aphront/pager-view.css', 75 + 'uri' => '/res/43fb79f0/rsrc/css/aphront/pager-view.css', 76 76 'type' => 'css', 77 77 'requires' => 78 78 array( ··· 81 81 ), 82 82 'aphront-panel-view-css' => 83 83 array( 84 - 'uri' => '/res/8f9f3632/rsrc/css/aphront/panel-view.css', 84 + 'uri' => '/res/8cdfa52d/rsrc/css/aphront/panel-view.css', 85 85 'type' => 'css', 86 86 'requires' => 87 87 array( ··· 90 90 ), 91 91 'aphront-request-failure-view-css' => 92 92 array( 93 - 'uri' => '/res/97b8337a/rsrc/css/aphront/request-failure-view.css', 93 + 'uri' => '/res/c9a43002/rsrc/css/aphront/request-failure-view.css', 94 94 'type' => 'css', 95 95 'requires' => 96 96 array( ··· 99 99 ), 100 100 'aphront-side-nav-view-css' => 101 101 array( 102 - 'uri' => '/res/4f4c5ca8/rsrc/css/aphront/side-nav-view.css', 102 + 'uri' => '/res/f92966bd/rsrc/css/aphront/side-nav-view.css', 103 103 'type' => 'css', 104 104 'requires' => 105 105 array( ··· 108 108 ), 109 109 'aphront-table-view-css' => 110 110 array( 111 - 'uri' => '/res/f09b7da6/rsrc/css/aphront/table-view.css', 111 + 'uri' => '/res/910e83ec/rsrc/css/aphront/table-view.css', 112 112 'type' => 'css', 113 113 'requires' => 114 114 array( ··· 117 117 ), 118 118 'aphront-tokenizer-control-css' => 119 119 array( 120 - 'uri' => '/res/190349be/rsrc/css/aphront/tokenizer.css', 120 + 'uri' => '/res/f530af47/rsrc/css/aphront/tokenizer.css', 121 121 'type' => 'css', 122 122 'requires' => 123 123 array( ··· 127 127 ), 128 128 'aphront-typeahead-control-css' => 129 129 array( 130 - 'uri' => '/res/928df9f0/rsrc/css/aphront/typeahead.css', 130 + 'uri' => '/res/a05236a6/rsrc/css/aphront/typeahead.css', 131 131 'type' => 'css', 132 132 'requires' => 133 133 array( ··· 136 136 ), 137 137 'differential-changeset-view-css' => 138 138 array( 139 - 'uri' => '/res/32a8bac6/rsrc/css/application/differential/changeset-view.css', 139 + 'uri' => '/res/a239213a/rsrc/css/application/differential/changeset-view.css', 140 140 'type' => 'css', 141 141 'requires' => 142 142 array( ··· 145 145 ), 146 146 'differential-core-view-css' => 147 147 array( 148 - 'uri' => '/res/525d1a12/rsrc/css/application/differential/core.css', 148 + 'uri' => '/res/f67a5b9d/rsrc/css/application/differential/core.css', 149 149 'type' => 'css', 150 150 'requires' => 151 151 array( ··· 154 154 ), 155 155 'differential-revision-add-comment-css' => 156 156 array( 157 - 'uri' => '/res/aaae14d3/rsrc/css/application/differential/add-comment.css', 157 + 'uri' => '/res/070942f7/rsrc/css/application/differential/add-comment.css', 158 158 'type' => 'css', 159 159 'requires' => 160 160 array( ··· 163 163 ), 164 164 'differential-revision-comment-css' => 165 165 array( 166 - 'uri' => '/res/7185c7fe/rsrc/css/application/differential/revision-comment.css', 166 + 'uri' => '/res/e3ea8c34/rsrc/css/application/differential/revision-comment.css', 167 167 'type' => 'css', 168 168 'requires' => 169 169 array( ··· 172 172 ), 173 173 'differential-revision-comment-list-css' => 174 174 array( 175 - 'uri' => '/res/10b9a829/rsrc/css/application/differential/revision-comment-list.css', 175 + 'uri' => '/res/3b31faa3/rsrc/css/application/differential/revision-comment-list.css', 176 176 'type' => 'css', 177 177 'requires' => 178 178 array( ··· 181 181 ), 182 182 'differential-revision-detail-css' => 183 183 array( 184 - 'uri' => '/res/a63e2d06/rsrc/css/application/differential/revision-detail.css', 184 + 'uri' => '/res/ea9de420/rsrc/css/application/differential/revision-detail.css', 185 185 'type' => 'css', 186 186 'requires' => 187 187 array( ··· 190 190 ), 191 191 'differential-revision-history-css' => 192 192 array( 193 - 'uri' => '/res/755f3da3/rsrc/css/application/differential/revision-history.css', 193 + 'uri' => '/res/0d7d515d/rsrc/css/application/differential/revision-history.css', 194 194 'type' => 'css', 195 195 'requires' => 196 196 array( ··· 199 199 ), 200 200 'differential-table-of-contents-css' => 201 201 array( 202 - 'uri' => '/res/e68f6f05/rsrc/css/application/differential/table-of-contents.css', 202 + 'uri' => '/res/d173445b/rsrc/css/application/differential/table-of-contents.css', 203 203 'type' => 'css', 204 204 'requires' => 205 205 array( ··· 208 208 ), 209 209 'diffusion-commit-view-css' => 210 210 array( 211 - 'uri' => '/res/8c139192/rsrc/css/application/diffusion/commit-view.css', 211 + 'uri' => '/res/bc39d876/rsrc/css/application/diffusion/commit-view.css', 212 212 'type' => 'css', 213 213 'requires' => 214 214 array( ··· 217 217 ), 218 218 'diffusion-source-css' => 219 219 array( 220 - 'uri' => '/res/7f50817b/rsrc/css/application/diffusion/diffusion-source.css', 220 + 'uri' => '/res/494e1dd2/rsrc/css/application/diffusion/diffusion-source.css', 221 221 'type' => 'css', 222 222 'requires' => 223 223 array( ··· 226 226 ), 227 227 'herald-css' => 228 228 array( 229 - 'uri' => '/res/211a4b1b/rsrc/css/application/herald/herald.css', 229 + 'uri' => '/res/5051f3ab/rsrc/css/application/herald/herald.css', 230 230 'type' => 'css', 231 231 'requires' => 232 232 array( ··· 235 235 ), 236 236 'herald-rule-editor' => 237 237 array( 238 - 'uri' => '/res/f3122b0a/rsrc/js/application/herald/HeraldRuleEditor.js', 238 + 'uri' => '/res/402e94d2/rsrc/js/application/herald/HeraldRuleEditor.js', 239 239 'type' => 'js', 240 240 'requires' => 241 241 array( ··· 253 253 ), 254 254 'herald-test-css' => 255 255 array( 256 - 'uri' => '/res/28269358/rsrc/css/application/herald/herald-test.css', 256 + 'uri' => '/res/c0cd6bdb/rsrc/css/application/herald/herald-test.css', 257 257 'type' => 'css', 258 258 'requires' => 259 259 array( ··· 262 262 ), 263 263 'javelin-behavior' => 264 264 array( 265 - 'uri' => '/res/d7ba2775/rsrc/js/javelin/lib/behavior.js', 265 + 'uri' => '/res/3c772c64/rsrc/js/javelin/lib/behavior.js', 266 266 'type' => 'js', 267 267 'requires' => 268 268 array( ··· 272 272 ), 273 273 'javelin-behavior-aphront-basic-tokenizer' => 274 274 array( 275 - 'uri' => '/res/d48d2732/rsrc/js/application/core/behavior-tokenizer.js', 275 + 'uri' => '/res/bce3961b/rsrc/js/application/core/behavior-tokenizer.js', 276 276 'type' => 'js', 277 277 'requires' => 278 278 array( ··· 286 286 ), 287 287 0 => 288 288 array( 289 - 'uri' => '/res/e3d992aa/rsrc/js/javelin/docs/Base.js', 289 + 'uri' => '/res/39de799e/rsrc/js/javelin/docs/Base.js', 290 290 'type' => 'js', 291 291 'requires' => 292 292 array( ··· 296 296 ), 297 297 'javelin-behavior-dark-console' => 298 298 array( 299 - 'uri' => '/res/447bd50a/rsrc/js/application/core/behavior-dark-console.js', 299 + 'uri' => '/res/044c171f/rsrc/js/application/core/behavior-dark-console.js', 300 300 'type' => 'js', 301 301 'requires' => 302 302 array( ··· 310 310 ), 311 311 'javelin-behavior-differential-add-reviewers' => 312 312 array( 313 - 'uri' => '/res/fa2f29c4/rsrc/js/application/differential/behavior-add-reviewers.js', 313 + 'uri' => '/res/dc79790c/rsrc/js/application/differential/behavior-add-reviewers.js', 314 314 'type' => 'js', 315 315 'requires' => 316 316 array( ··· 324 324 ), 325 325 'javelin-behavior-differential-diff-radios' => 326 326 array( 327 - 'uri' => '/res/d3365dba/rsrc/js/application/differential/behavior-diff-radios.js', 327 + 'uri' => '/res/004cb66f/rsrc/js/application/differential/behavior-diff-radios.js', 328 328 'type' => 'js', 329 329 'requires' => 330 330 array( ··· 336 336 ), 337 337 'javelin-behavior-differential-edit-inline-comments' => 338 338 array( 339 - 'uri' => '/res/f18ee6ae/rsrc/js/application/differential/behavior-edit-inline-comments.js', 339 + 'uri' => '/res/682d1a9c/rsrc/js/application/differential/behavior-edit-inline-comments.js', 340 340 'type' => 'js', 341 341 'requires' => 342 342 array( ··· 350 350 ), 351 351 'javelin-behavior-differential-feedback-preview' => 352 352 array( 353 - 'uri' => '/res/139c85b8/rsrc/js/application/differential/behavior-comment-preview.js', 353 + 'uri' => '/res/79e7f18d/rsrc/js/application/differential/behavior-comment-preview.js', 354 354 'type' => 'js', 355 355 'requires' => 356 356 array( ··· 364 364 ), 365 365 'javelin-behavior-differential-populate' => 366 366 array( 367 - 'uri' => '/res/d4d4fd9d/rsrc/js/application/differential/behavior-populate.js', 367 + 'uri' => '/res/8bf692d0/rsrc/js/application/differential/behavior-populate.js', 368 368 'type' => 'js', 369 369 'requires' => 370 370 array( ··· 377 377 ), 378 378 'javelin-behavior-differential-show-all-comments' => 379 379 array( 380 - 'uri' => '/res/4d34a1e7/rsrc/js/application/differential/behavior-show-all-comments.js', 380 + 'uri' => '/res/b7c7e1ee/rsrc/js/application/differential/behavior-show-all-comments.js', 381 381 'type' => 'js', 382 382 'requires' => 383 383 array( ··· 389 389 ), 390 390 'javelin-behavior-differential-show-more' => 391 391 array( 392 - 'uri' => '/res/6af8c5bb/rsrc/js/application/differential/behavior-show-more.js', 392 + 'uri' => '/res/7a844635/rsrc/js/application/differential/behavior-show-more.js', 393 393 'type' => 'js', 394 394 'requires' => 395 395 array( ··· 403 403 ), 404 404 'javelin-behavior-diffusion-jump-to' => 405 405 array( 406 - 'uri' => '/res/2a8ca30b/rsrc/js/application/diffusion/behavior-jump-to.js', 406 + 'uri' => '/res/4b63e436/rsrc/js/application/diffusion/behavior-jump-to.js', 407 407 'type' => 'js', 408 408 'requires' => 409 409 array( ··· 416 416 ), 417 417 'javelin-behavior-diffusion-pull-lastmodified' => 418 418 array( 419 - 'uri' => '/res/f3e3f3a6/rsrc/js/application/diffusion/behavior-pull-lastmodified.js', 419 + 'uri' => '/res/29fe2790/rsrc/js/application/diffusion/behavior-pull-lastmodified.js', 420 420 'type' => 'js', 421 421 'requires' => 422 422 array( ··· 429 429 ), 430 430 'javelin-behavior-error-log' => 431 431 array( 432 - 'uri' => '/res/ad4e82d4/rsrc/js/application/core/behavior-error-log.js', 432 + 'uri' => '/res/a5cb42a5/rsrc/js/application/core/behavior-error-log.js', 433 433 'type' => 'js', 434 434 'requires' => 435 435 array( ··· 439 439 ), 440 440 'javelin-behavior-herald-rule-editor' => 441 441 array( 442 - 'uri' => '/res/f18bcd5e/rsrc/js/application/herald/herald-rule-editor.js', 442 + 'uri' => '/res/77a0c945/rsrc/js/application/herald/herald-rule-editor.js', 443 443 'type' => 'js', 444 444 'requires' => 445 445 array( ··· 450 450 ), 451 451 'javelin-behavior-maniphest-transaction-controls' => 452 452 array( 453 - 'uri' => '/res/f2eae88a/rsrc/js/application/maniphest/behavior-transaction-controls.js', 453 + 'uri' => '/res/94a2a395/rsrc/js/application/maniphest/behavior-transaction-controls.js', 454 454 'type' => 'js', 455 455 'requires' => 456 456 array( ··· 464 464 ), 465 465 'javelin-behavior-owners-path-editor' => 466 466 array( 467 - 'uri' => '/res/b379a0d4/rsrc/js/application/owners/owners-path-editor.js', 467 + 'uri' => '/res/9cf78ffc/rsrc/js/application/owners/owners-path-editor.js', 468 468 'type' => 'js', 469 469 'requires' => 470 470 array( ··· 475 475 ), 476 476 'javelin-behavior-phabricator-object-selector' => 477 477 array( 478 - 'uri' => '/res/e899a55e/rsrc/js/application/core/behavior-object-selector.js', 478 + 'uri' => '/res/fd4ce976/rsrc/js/application/core/behavior-object-selector.js', 479 479 'type' => 'js', 480 480 'requires' => 481 481 array( ··· 489 489 ), 490 490 'javelin-behavior-workflow' => 491 491 array( 492 - 'uri' => '/res/b5bc59cb/rsrc/js/application/core/behavior-workflow.js', 492 + 'uri' => '/res/079f49c3/rsrc/js/application/core/behavior-workflow.js', 493 493 'type' => 'js', 494 494 'requires' => 495 495 array( ··· 501 501 ), 502 502 'javelin-dom' => 503 503 array( 504 - 'uri' => '/res/37590eec/rsrc/js/javelin/lib/DOM.js', 504 + 'uri' => '/res/770d72cd/rsrc/js/javelin/lib/DOM.js', 505 505 'type' => 'js', 506 506 'requires' => 507 507 array( ··· 515 515 ), 516 516 'javelin-event' => 517 517 array( 518 - 'uri' => '/res/807b95e6/rsrc/js/javelin/core/Event.js', 518 + 'uri' => '/res/25c7c9e8/rsrc/js/javelin/core/Event.js', 519 519 'type' => 'js', 520 520 'requires' => 521 521 array( ··· 525 525 ), 526 526 'javelin-install' => 527 527 array( 528 - 'uri' => '/res/a46b4e6d/rsrc/js/javelin/core/install.js', 528 + 'uri' => '/res/f4d0e147/rsrc/js/javelin/core/install.js', 529 529 'type' => 'js', 530 530 'requires' => 531 531 array( ··· 536 536 ), 537 537 'javelin-json' => 538 538 array( 539 - 'uri' => '/res/62c8cc8d/rsrc/js/javelin/lib/JSON.js', 539 + 'uri' => '/res/315c8b24/rsrc/js/javelin/lib/JSON.js', 540 540 'type' => 'js', 541 541 'requires' => 542 542 array( ··· 547 547 ), 548 548 'javelin-magical-init' => 549 549 array( 550 - 'uri' => '/res/929da242/rsrc/js/javelin/core/init.js', 550 + 'uri' => '/res/ce002e50/rsrc/js/javelin/core/init.js', 551 551 'type' => 'js', 552 552 'requires' => 553 553 array( ··· 556 556 ), 557 557 'javelin-mask' => 558 558 array( 559 - 'uri' => '/res/ba2f665a/rsrc/js/javelin/lib/Mask.js', 559 + 'uri' => '/res/28e3bd9c/rsrc/js/javelin/lib/Mask.js', 560 560 'type' => 'js', 561 561 'requires' => 562 562 array( ··· 568 568 ), 569 569 'javelin-request' => 570 570 array( 571 - 'uri' => '/res/3947083d/rsrc/js/javelin/lib/Request.js', 571 + 'uri' => '/res/e0e6d9e4/rsrc/js/javelin/lib/Request.js', 572 572 'type' => 'js', 573 573 'requires' => 574 574 array( ··· 581 581 ), 582 582 'javelin-stratcom' => 583 583 array( 584 - 'uri' => '/res/3421b115/rsrc/js/javelin/core/Stratcom.js', 584 + 'uri' => '/res/d3f4599a/rsrc/js/javelin/core/Stratcom.js', 585 585 'type' => 'js', 586 586 'requires' => 587 587 array( ··· 594 594 ), 595 595 'javelin-tokenizer' => 596 596 array( 597 - 'uri' => '/res/f45e7c70/rsrc/js/javelin/lib/control/tokenizer/Tokenizer.js', 597 + 'uri' => '/res/83787676/rsrc/js/javelin/lib/control/tokenizer/Tokenizer.js', 598 598 'type' => 'js', 599 599 'requires' => 600 600 array( ··· 607 607 ), 608 608 'javelin-typeahead' => 609 609 array( 610 - 'uri' => '/res/5a701345/rsrc/js/javelin/lib/control/typeahead/Typeahead.js', 610 + 'uri' => '/res/ae18ee16/rsrc/js/javelin/lib/control/typeahead/Typeahead.js', 611 611 'type' => 'js', 612 612 'requires' => 613 613 array( ··· 620 620 ), 621 621 'javelin-typeahead-normalizer' => 622 622 array( 623 - 'uri' => '/res/8d49e2de/rsrc/js/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js', 623 + 'uri' => '/res/a5d60e3c/rsrc/js/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js', 624 624 'type' => 'js', 625 625 'requires' => 626 626 array( ··· 630 630 ), 631 631 'javelin-typeahead-ondemand-source' => 632 632 array( 633 - 'uri' => '/res/00b46be8/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js', 633 + 'uri' => '/res/0015bbf5/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js', 634 634 'type' => 'js', 635 635 'requires' => 636 636 array( ··· 644 644 ), 645 645 'javelin-typeahead-preloaded-source' => 646 646 array( 647 - 'uri' => '/res/aefaf410/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js', 647 + 'uri' => '/res/863a173c/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js', 648 648 'type' => 'js', 649 649 'requires' => 650 650 array( ··· 658 658 ), 659 659 'javelin-typeahead-source' => 660 660 array( 661 - 'uri' => '/res/b1184e7d/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadSource.js', 661 + 'uri' => '/res/58518dde/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadSource.js', 662 662 'type' => 'js', 663 663 'requires' => 664 664 array( ··· 671 671 ), 672 672 'javelin-uri' => 673 673 array( 674 - 'uri' => '/res/07a16bd9/rsrc/js/javelin/lib/URI.js', 674 + 'uri' => '/res/70c9d32b/rsrc/js/javelin/lib/URI.js', 675 675 'type' => 'js', 676 676 'requires' => 677 677 array( ··· 683 683 ), 684 684 'javelin-util' => 685 685 array( 686 - 'uri' => '/res/f32d6b81/rsrc/js/javelin/core/util.js', 686 + 'uri' => '/res/be43fdba/rsrc/js/javelin/core/util.js', 687 687 'type' => 'js', 688 688 'requires' => 689 689 array( ··· 692 692 ), 693 693 'javelin-vector' => 694 694 array( 695 - 'uri' => '/res/12daf99c/rsrc/js/javelin/lib/Vector.js', 695 + 'uri' => '/res/cd4721c4/rsrc/js/javelin/lib/Vector.js', 696 696 'type' => 'js', 697 697 'requires' => 698 698 array( ··· 703 703 ), 704 704 'javelin-workflow' => 705 705 array( 706 - 'uri' => '/res/b6fb108f/rsrc/js/javelin/lib/Workflow.js', 706 + 'uri' => '/res/efe645f0/rsrc/js/javelin/lib/Workflow.js', 707 707 'type' => 'js', 708 708 'requires' => 709 709 array( ··· 720 720 ), 721 721 'mainphest-task-detail-css' => 722 722 array( 723 - 'uri' => '/res/e5f3beca/rsrc/css/application/maniphest/task-detail.css', 723 + 'uri' => '/res/dbefc148/rsrc/css/application/maniphest/task-detail.css', 724 724 'type' => 'css', 725 725 'requires' => 726 726 array( ··· 729 729 ), 730 730 'maniphest-task-summary-css' => 731 731 array( 732 - 'uri' => '/res/8dc6fb13/rsrc/css/application/maniphest/task-summary.css', 732 + 'uri' => '/res/41624cb0/rsrc/css/application/maniphest/task-summary.css', 733 733 'type' => 'css', 734 734 'requires' => 735 735 array( ··· 738 738 ), 739 739 'maniphest-transaction-detail-css' => 740 740 array( 741 - 'uri' => '/res/16725026/rsrc/css/application/maniphest/transaction-detail.css', 741 + 'uri' => '/res/8e196c52/rsrc/css/application/maniphest/transaction-detail.css', 742 742 'type' => 'css', 743 743 'requires' => 744 744 array( ··· 747 747 ), 748 748 'multirow-row-manager' => 749 749 array( 750 - 'uri' => '/res/cae26c67/rsrc/js/application/core/MultirowRowManager.js', 750 + 'uri' => '/res/0a9b3dee/rsrc/js/application/core/MultirowRowManager.js', 751 751 'type' => 'js', 752 752 'requires' => 753 753 array( ··· 760 760 ), 761 761 'owners-path-editor' => 762 762 array( 763 - 'uri' => '/res/003f3d3f/rsrc/js/application/owners/OwnersPathEditor.js', 763 + 'uri' => '/res/e6c51eb6/rsrc/js/application/owners/OwnersPathEditor.js', 764 764 'type' => 'js', 765 765 'requires' => 766 766 array( ··· 774 774 ), 775 775 'owners-path-editor-css' => 776 776 array( 777 - 'uri' => '/res/f40dc6b1/rsrc/css/application/owners/owners-path-editor.css', 777 + 'uri' => '/res/9bc5332c/rsrc/css/application/owners/owners-path-editor.css', 778 778 'type' => 'css', 779 779 'requires' => 780 780 array( ··· 783 783 ), 784 784 'path-typeahead' => 785 785 array( 786 - 'uri' => '/res/594d2576/rsrc/js/application/herald/PathTypeahead.js', 786 + 'uri' => '/res/1343345d/rsrc/js/application/herald/PathTypeahead.js', 787 787 'type' => 'js', 788 788 'requires' => 789 789 array( ··· 798 798 ), 799 799 'phabricator-core-buttons-css' => 800 800 array( 801 - 'uri' => '/res/53b4f712/rsrc/css/core/buttons.css', 801 + 'uri' => '/res/f797baf5/rsrc/css/core/buttons.css', 802 802 'type' => 'css', 803 803 'requires' => 804 804 array( ··· 807 807 ), 808 808 'phabricator-core-css' => 809 809 array( 810 - 'uri' => '/res/6eebb99b/rsrc/css/core/core.css', 810 + 'uri' => '/res/78194d68/rsrc/css/core/core.css', 811 811 'type' => 'css', 812 812 'requires' => 813 813 array( ··· 816 816 ), 817 817 'phabricator-directory-css' => 818 818 array( 819 - 'uri' => '/res/6a000601/rsrc/css/application/directory/phabricator-directory.css', 819 + 'uri' => '/res/a3d307c5/rsrc/css/application/directory/phabricator-directory.css', 820 820 'type' => 'css', 821 821 'requires' => 822 822 array( ··· 825 825 ), 826 826 'phabricator-object-selector-css' => 827 827 array( 828 - 'uri' => '/res/52a7e289/rsrc/css/application/objectselector/object-selector.css', 828 + 'uri' => '/res/ced4098a/rsrc/css/application/objectselector/object-selector.css', 829 829 'type' => 'css', 830 830 'requires' => 831 831 array( ··· 835 835 ), 836 836 'phabricator-profile-css' => 837 837 array( 838 - 'uri' => '/res/259ad37f/rsrc/css/application/people/profile.css', 838 + 'uri' => '/res/adcdb5f3/rsrc/css/application/people/profile.css', 839 839 'type' => 'css', 840 840 'requires' => 841 841 array( ··· 844 844 ), 845 845 'phabricator-remarkup-css' => 846 846 array( 847 - 'uri' => '/res/41748e59/rsrc/css/core/remarkup.css', 847 + 'uri' => '/res/fc827787/rsrc/css/core/remarkup.css', 848 848 'type' => 'css', 849 849 'requires' => 850 850 array( ··· 853 853 ), 854 854 'phabricator-standard-page-view' => 855 855 array( 856 - 'uri' => '/res/0d41ea7c/rsrc/css/application/base/standard-page-view.css', 856 + 'uri' => '/res/9c468a70/rsrc/css/application/base/standard-page-view.css', 857 857 'type' => 'css', 858 858 'requires' => 859 859 array( ··· 862 862 ), 863 863 'phabricator-ui-example-css' => 864 864 array( 865 - 'uri' => '/res/365a10f1/rsrc/css/application/uiexample/example.css', 865 + 'uri' => '/res/0cef078b/rsrc/css/application/uiexample/example.css', 866 866 'type' => 'css', 867 867 'requires' => 868 868 array( ··· 871 871 ), 872 872 'syntax-highlighting-css' => 873 873 array( 874 - 'uri' => '/res/fb673ece/rsrc/css/core/syntax.css', 874 + 'uri' => '/res/e5cc3d88/rsrc/css/core/syntax.css', 875 875 'type' => 'css', 876 876 'requires' => 877 877 array( ··· 881 881 ), array ( 882 882 'packages' => 883 883 array ( 884 - '22ec468f' => 884 + '03ef179e' => 885 885 array ( 886 - 'name' => 'javelin.pkg.js', 886 + 'name' => 'diffusion.pkg.css', 887 887 'symbols' => 888 888 array ( 889 - 0 => 'javelin-util', 890 - 1 => 'javelin-install', 891 - 2 => 'javelin-event', 892 - 3 => 'javelin-stratcom', 893 - 4 => 'javelin-behavior', 894 - 5 => 'javelin-request', 895 - 6 => 'javelin-vector', 896 - 7 => 'javelin-dom', 897 - 8 => 'javelin-json', 898 - 9 => 'javelin-uri', 899 - ), 900 - 'uri' => '/res/pkg/22ec468f/javelin.pkg.js', 901 - 'type' => 'js', 902 - ), 903 - '3b698834' => 904 - array ( 905 - 'name' => 'differential.pkg.js', 906 - 'symbols' => 907 - array ( 908 - 0 => 'javelin-behavior-differential-feedback-preview', 909 - 1 => 'javelin-behavior-differential-edit-inline-comments', 910 - 2 => 'javelin-behavior-differential-populate', 911 - 3 => 'javelin-behavior-differential-show-more', 912 - 4 => 'javelin-behavior-differential-diff-radios', 889 + 0 => 'diffusion-commit-view-css', 913 890 ), 914 - 'uri' => '/res/pkg/3b698834/differential.pkg.js', 915 - 'type' => 'js', 891 + 'uri' => '/res/pkg/03ef179e/diffusion.pkg.css', 892 + 'type' => 'css', 916 893 ), 917 - '79ca6977' => 894 + '122a6b6d' => 918 895 array ( 919 896 'name' => 'workflow.pkg.js', 920 897 'symbols' => ··· 923 900 1 => 'javelin-workflow', 924 901 2 => 'javelin-behavior-workflow', 925 902 ), 926 - 'uri' => '/res/pkg/79ca6977/workflow.pkg.js', 903 + 'uri' => '/res/pkg/122a6b6d/workflow.pkg.js', 927 904 'type' => 'js', 928 905 ), 929 - '8e4ef51b' => 906 + '314934dc' => 930 907 array ( 931 908 'name' => 'differential.pkg.css', 932 909 'symbols' => ··· 940 917 6 => 'differential-revision-add-comment-css', 941 918 7 => 'differential-revision-comment-list-css', 942 919 ), 943 - 'uri' => '/res/pkg/8e4ef51b/differential.pkg.css', 920 + 'uri' => '/res/pkg/314934dc/differential.pkg.css', 944 921 'type' => 'css', 945 922 ), 946 - 'c4276ad7' => 923 + '33f413ef' => 924 + array ( 925 + 'name' => 'typeahead.pkg.js', 926 + 'symbols' => 927 + array ( 928 + 0 => 'javelin-typeahead', 929 + 1 => 'javelin-typeahead-normalizer', 930 + 2 => 'javelin-typeahead-source', 931 + 3 => 'javelin-typeahead-preloaded-source', 932 + 4 => 'javelin-typeahead-ondemand-source', 933 + 5 => 'javelin-tokenizer', 934 + 6 => 'javelin-behavior-aphront-basic-tokenizer', 935 + ), 936 + 'uri' => '/res/pkg/33f413ef/typeahead.pkg.js', 937 + 'type' => 'js', 938 + ), 939 + '711616db' => 940 + array ( 941 + 'name' => 'differential.pkg.js', 942 + 'symbols' => 943 + array ( 944 + 0 => 'javelin-behavior-differential-feedback-preview', 945 + 1 => 'javelin-behavior-differential-edit-inline-comments', 946 + 2 => 'javelin-behavior-differential-populate', 947 + 3 => 'javelin-behavior-differential-show-more', 948 + 4 => 'javelin-behavior-differential-diff-radios', 949 + ), 950 + 'uri' => '/res/pkg/711616db/differential.pkg.js', 951 + 'type' => 'js', 952 + ), 953 + '7d23deb1' => 954 + array ( 955 + 'name' => 'javelin.pkg.js', 956 + 'symbols' => 957 + array ( 958 + 0 => 'javelin-util', 959 + 1 => 'javelin-install', 960 + 2 => 'javelin-event', 961 + 3 => 'javelin-stratcom', 962 + 4 => 'javelin-behavior', 963 + 5 => 'javelin-request', 964 + 6 => 'javelin-vector', 965 + 7 => 'javelin-dom', 966 + 8 => 'javelin-json', 967 + 9 => 'javelin-uri', 968 + ), 969 + 'uri' => '/res/pkg/7d23deb1/javelin.pkg.js', 970 + 'type' => 'js', 971 + ), 972 + 'ac70e6b7' => 947 973 array ( 948 974 'name' => 'core.pkg.css', 949 975 'symbols' => ··· 964 990 13 => 'phabricator-remarkup-css', 965 991 14 => 'syntax-highlighting-css', 966 992 ), 967 - 'uri' => '/res/pkg/c4276ad7/core.pkg.css', 968 - 'type' => 'css', 969 - ), 970 - 'dc82a12d' => 971 - array ( 972 - 'name' => 'typeahead.pkg.js', 973 - 'symbols' => 974 - array ( 975 - 0 => 'javelin-typeahead', 976 - 1 => 'javelin-typeahead-normalizer', 977 - 2 => 'javelin-typeahead-source', 978 - 3 => 'javelin-typeahead-preloaded-source', 979 - 4 => 'javelin-typeahead-ondemand-source', 980 - 5 => 'javelin-tokenizer', 981 - 6 => 'javelin-behavior-aphront-basic-tokenizer', 982 - ), 983 - 'uri' => '/res/pkg/dc82a12d/typeahead.pkg.js', 984 - 'type' => 'js', 985 - ), 986 - 'eadf6ec3' => 987 - array ( 988 - 'name' => 'diffusion.pkg.css', 989 - 'symbols' => 990 - array ( 991 - 0 => 'diffusion-commit-view-css', 992 - ), 993 - 'uri' => '/res/pkg/eadf6ec3/diffusion.pkg.css', 993 + 'uri' => '/res/pkg/ac70e6b7/core.pkg.css', 994 994 'type' => 'css', 995 995 ), 996 996 ), 997 997 'reverse' => 998 998 array ( 999 - 'aphront-crumbs-view-css' => 'c4276ad7', 1000 - 'aphront-dialog-view-css' => 'c4276ad7', 1001 - 'aphront-form-view-css' => 'c4276ad7', 1002 - 'aphront-list-filter-view-css' => 'c4276ad7', 1003 - 'aphront-panel-view-css' => 'c4276ad7', 1004 - 'aphront-side-nav-view-css' => 'c4276ad7', 1005 - 'aphront-table-view-css' => 'c4276ad7', 1006 - 'aphront-tokenizer-control-css' => 'c4276ad7', 1007 - 'aphront-typeahead-control-css' => 'c4276ad7', 1008 - 'differential-changeset-view-css' => '8e4ef51b', 1009 - 'differential-core-view-css' => '8e4ef51b', 1010 - 'differential-revision-add-comment-css' => '8e4ef51b', 1011 - 'differential-revision-comment-css' => '8e4ef51b', 1012 - 'differential-revision-comment-list-css' => '8e4ef51b', 1013 - 'differential-revision-detail-css' => '8e4ef51b', 1014 - 'differential-revision-history-css' => '8e4ef51b', 1015 - 'differential-table-of-contents-css' => '8e4ef51b', 1016 - 'diffusion-commit-view-css' => 'eadf6ec3', 1017 - 'javelin-behavior' => '22ec468f', 1018 - 'javelin-behavior-aphront-basic-tokenizer' => 'dc82a12d', 1019 - 'javelin-behavior-differential-diff-radios' => '3b698834', 1020 - 'javelin-behavior-differential-edit-inline-comments' => '3b698834', 1021 - 'javelin-behavior-differential-feedback-preview' => '3b698834', 1022 - 'javelin-behavior-differential-populate' => '3b698834', 1023 - 'javelin-behavior-differential-show-more' => '3b698834', 1024 - 'javelin-behavior-workflow' => '79ca6977', 1025 - 'javelin-dom' => '22ec468f', 1026 - 'javelin-event' => '22ec468f', 1027 - 'javelin-install' => '22ec468f', 1028 - 'javelin-json' => '22ec468f', 1029 - 'javelin-mask' => '79ca6977', 1030 - 'javelin-request' => '22ec468f', 1031 - 'javelin-stratcom' => '22ec468f', 1032 - 'javelin-tokenizer' => 'dc82a12d', 1033 - 'javelin-typeahead' => 'dc82a12d', 1034 - 'javelin-typeahead-normalizer' => 'dc82a12d', 1035 - 'javelin-typeahead-ondemand-source' => 'dc82a12d', 1036 - 'javelin-typeahead-preloaded-source' => 'dc82a12d', 1037 - 'javelin-typeahead-source' => 'dc82a12d', 1038 - 'javelin-uri' => '22ec468f', 1039 - 'javelin-util' => '22ec468f', 1040 - 'javelin-vector' => '22ec468f', 1041 - 'javelin-workflow' => '79ca6977', 1042 - 'phabricator-core-buttons-css' => 'c4276ad7', 1043 - 'phabricator-core-css' => 'c4276ad7', 1044 - 'phabricator-directory-css' => 'c4276ad7', 1045 - 'phabricator-remarkup-css' => 'c4276ad7', 1046 - 'phabricator-standard-page-view' => 'c4276ad7', 1047 - 'syntax-highlighting-css' => 'c4276ad7', 999 + 'aphront-crumbs-view-css' => 'ac70e6b7', 1000 + 'aphront-dialog-view-css' => 'ac70e6b7', 1001 + 'aphront-form-view-css' => 'ac70e6b7', 1002 + 'aphront-list-filter-view-css' => 'ac70e6b7', 1003 + 'aphront-panel-view-css' => 'ac70e6b7', 1004 + 'aphront-side-nav-view-css' => 'ac70e6b7', 1005 + 'aphront-table-view-css' => 'ac70e6b7', 1006 + 'aphront-tokenizer-control-css' => 'ac70e6b7', 1007 + 'aphront-typeahead-control-css' => 'ac70e6b7', 1008 + 'differential-changeset-view-css' => '314934dc', 1009 + 'differential-core-view-css' => '314934dc', 1010 + 'differential-revision-add-comment-css' => '314934dc', 1011 + 'differential-revision-comment-css' => '314934dc', 1012 + 'differential-revision-comment-list-css' => '314934dc', 1013 + 'differential-revision-detail-css' => '314934dc', 1014 + 'differential-revision-history-css' => '314934dc', 1015 + 'differential-table-of-contents-css' => '314934dc', 1016 + 'diffusion-commit-view-css' => '03ef179e', 1017 + 'javelin-behavior' => '7d23deb1', 1018 + 'javelin-behavior-aphront-basic-tokenizer' => '33f413ef', 1019 + 'javelin-behavior-differential-diff-radios' => '711616db', 1020 + 'javelin-behavior-differential-edit-inline-comments' => '711616db', 1021 + 'javelin-behavior-differential-feedback-preview' => '711616db', 1022 + 'javelin-behavior-differential-populate' => '711616db', 1023 + 'javelin-behavior-differential-show-more' => '711616db', 1024 + 'javelin-behavior-workflow' => '122a6b6d', 1025 + 'javelin-dom' => '7d23deb1', 1026 + 'javelin-event' => '7d23deb1', 1027 + 'javelin-install' => '7d23deb1', 1028 + 'javelin-json' => '7d23deb1', 1029 + 'javelin-mask' => '122a6b6d', 1030 + 'javelin-request' => '7d23deb1', 1031 + 'javelin-stratcom' => '7d23deb1', 1032 + 'javelin-tokenizer' => '33f413ef', 1033 + 'javelin-typeahead' => '33f413ef', 1034 + 'javelin-typeahead-normalizer' => '33f413ef', 1035 + 'javelin-typeahead-ondemand-source' => '33f413ef', 1036 + 'javelin-typeahead-preloaded-source' => '33f413ef', 1037 + 'javelin-typeahead-source' => '33f413ef', 1038 + 'javelin-uri' => '7d23deb1', 1039 + 'javelin-util' => '7d23deb1', 1040 + 'javelin-vector' => '7d23deb1', 1041 + 'javelin-workflow' => '122a6b6d', 1042 + 'phabricator-core-buttons-css' => 'ac70e6b7', 1043 + 'phabricator-core-css' => 'ac70e6b7', 1044 + 'phabricator-directory-css' => 'ac70e6b7', 1045 + 'phabricator-remarkup-css' => 'ac70e6b7', 1046 + 'phabricator-standard-page-view' => 'ac70e6b7', 1047 + 'syntax-highlighting-css' => 'ac70e6b7', 1048 1048 ), 1049 1049 ));
+2
src/__phutil_library_map__.php
··· 8 8 phutil_register_library_map(array( 9 9 'class' => 10 10 array( 11 + 'Aphront304Response' => 'aphront/response/304', 11 12 'Aphront400Response' => 'aphront/response/400', 12 13 'Aphront404Response' => 'aphront/response/404', 13 14 'AphrontAjaxResponse' => 'aphront/response/ajax', ··· 503 504 ), 504 505 'requires_class' => 505 506 array( 507 + 'Aphront304Response' => 'AphrontResponse', 506 508 'Aphront400Response' => 'AphrontResponse', 507 509 'Aphront404Response' => 'AphrontResponse', 508 510 'AphrontAjaxResponse' => 'AphrontResponse',
+3
src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php
··· 315 315 316 316 public function handleException(Exception $ex) { 317 317 318 + // Always log the unhandled exception. 319 + phlog($ex); 320 + 318 321 $class = phutil_escape_html(get_class($ex)); 319 322 $message = phutil_escape_html($ex->getMessage()); 320 323
+1
src/aphront/default/configuration/__init__.php
··· 18 18 phutil_require_module('phabricator', 'view/page/failure'); 19 19 phutil_require_module('phabricator', 'view/page/standard'); 20 20 21 + phutil_require_module('phutil', 'error'); 21 22 phutil_require_module('phutil', 'markup'); 22 23 phutil_require_module('phutil', 'utils'); 23 24
+32
src/aphront/response/304/Aphront304Response.php
··· 1 + <?php 2 + 3 + /* 4 + * Copyright 2011 Facebook, Inc. 5 + * 6 + * Licensed under the Apache License, Version 2.0 (the "License"); 7 + * you may not use this file except in compliance with the License. 8 + * You may obtain a copy of the License at 9 + * 10 + * http://www.apache.org/licenses/LICENSE-2.0 11 + * 12 + * Unless required by applicable law or agreed to in writing, software 13 + * distributed under the License is distributed on an "AS IS" BASIS, 14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + * See the License for the specific language governing permissions and 16 + * limitations under the License. 17 + */ 18 + 19 + /** 20 + * @group aphront 21 + */ 22 + class Aphront304Response extends AphrontResponse { 23 + 24 + public function getHTTPResponseCode() { 25 + return 304; 26 + } 27 + 28 + public function buildResponseString() { 29 + return '304 Not Modified'; 30 + } 31 + 32 + }
+12
src/aphront/response/304/__init__.php
··· 1 + <?php 2 + /** 3 + * This file is automatically generated. Lint this module to rebuild it. 4 + * @generated 5 + */ 6 + 7 + 8 + 9 + phutil_require_module('phabricator', 'aphront/response/base'); 10 + 11 + 12 + phutil_require_source('Aphront304Response.php');
+4
src/aphront/response/400/Aphront400Response.php
··· 21 21 */ 22 22 class Aphront400Response extends AphrontResponse { 23 23 24 + public function getHTTPResponseCode() { 25 + return 400; 26 + } 27 + 24 28 public function buildResponseString() { 25 29 return '400 Bad Request'; 26 30 }
+4
src/aphront/response/404/Aphront404Response.php
··· 21 21 */ 22 22 class Aphront404Response extends AphrontResponse { 23 23 24 + public function getHTTPResponseCode() { 25 + return 404; 26 + } 27 + 24 28 public function buildResponseString() { 25 29 return '404 Not Found'; 26 30 }
+28 -8
src/aphront/response/base/AphrontResponse.php
··· 24 24 private $request; 25 25 private $cacheable = false; 26 26 private $responseCode = 200; 27 + private $lastModified = null; 27 28 28 29 public function setRequest($request) { 29 30 $this->request = $request; ··· 43 44 return $this; 44 45 } 45 46 47 + public function setLastModified($epoch_timestamp) { 48 + $this->lastModified = $epoch_timestamp; 49 + return $this; 50 + } 51 + 46 52 public function setHTTPResponseCode($code) { 47 53 $this->responseCode = $code; 48 54 return $this; ··· 53 59 } 54 60 55 61 public function getCacheHeaders() { 62 + $headers = array(); 56 63 if ($this->cacheable) { 57 - $epoch = time() + $this->cacheable; 58 - return array( 59 - array('Expires', gmdate('D, d M Y H:i:s', $epoch) . ' GMT'), 60 - ); 64 + $headers[] = array( 65 + 'Expires', 66 + $this->formatEpochTimestampForHTTPHeader(time() + $this->cacheable)); 61 67 } else { 62 - return array( 63 - array('Cache-Control', 'private, no-cache, no-store, must-revalidate'), 64 - array('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT'), 65 - ); 68 + $headers[] = array( 69 + 'Cache-Control', 70 + 'private, no-cache, no-store, must-revalidate'); 71 + $headers[] = array( 72 + 'Expires', 73 + 'Sat, 01 Jan 2000 00:00:00 GMT'); 66 74 } 75 + 76 + if ($this->lastModified) { 77 + $headers[] = array( 78 + 'Last-Modified', 79 + $this->formatEpochTimestampForHTTPHeader($this->lastModified)); 80 + } 81 + 82 + return $headers; 83 + } 84 + 85 + private function formatEpochTimestampForHTTPHeader($epoch_timestamp) { 86 + return gmdate('D, d M Y H:i:s', $epoch_timestamp).' GMT'; 67 87 } 68 88 69 89 abstract public function buildResponseString();
+11
src/infrastructure/celerity/controller/CelerityResourceController.php
··· 38 38 throw new Exception("Only CSS and JS resources may be served."); 39 39 } 40 40 41 + if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { 42 + // Return a "304 Not Modified". We don't care about the value of this 43 + // field since we never change what resource is served by a given URI. 44 + return $this->makeResponseCacheable(new Aphront304Response()); 45 + } 46 + 41 47 $type = $matches[1]; 42 48 43 49 $root = dirname(phutil_get_library_root('phabricator')); ··· 77 83 break; 78 84 } 79 85 86 + return $this->makeResponseCacheable($response); 87 + } 88 + 89 + private function makeResponseCacheable(AphrontResponse $response) { 80 90 $response->setCacheDurationInSeconds(60 * 60 * 24 * 30); 91 + $response->setLastModified(time()); 81 92 82 93 return $response; 83 94 }
+1
src/infrastructure/celerity/controller/__init__.php
··· 7 7 8 8 9 9 phutil_require_module('phabricator', 'aphront/controller'); 10 + phutil_require_module('phabricator', 'aphront/response/304'); 10 11 phutil_require_module('phabricator', 'aphront/response/404'); 11 12 phutil_require_module('phabricator', 'aphront/response/file'); 12 13 phutil_require_module('phabricator', 'infrastructure/celerity/map');