Skip to content

Commit

Permalink
Use ETag and If-None-Match when getting issues
Browse files Browse the repository at this point in the history
When getting an issue, return an `ETag`, even if the issue doesn’t exist.

When request contains `If-None-Match` and hash matches, then return `304 Not Modified`.
The 304 response will be returned whether issue exists or not.

The hash depends on:
- a hasing version
- user id
- issue id
- issue last updated

Fixes #23648
  • Loading branch information
vboctor committed Nov 25, 2017
1 parent 2fd81a3 commit df98373
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
11 changes: 11 additions & 0 deletions api/rest/restcore/issues_rest.php
Expand Up @@ -59,6 +59,17 @@ function rest_issue_get( \Slim\Http\Request $p_request, \Slim\Http\Response $p_r
if( !is_blank( $t_issue_id ) ) {
# Get Issue By Id

# Calculate etag for issue. This will work even if issue doesn't exist.
$t_etag = bug_hash( $t_issue_id );
$p_response = $p_response->withAddedHeader( HEADER_ETAG, $t_etag );

if( $p_request->hasHeader( HEADER_IF_NONE_MATCH ) ) {
$t_match_etag = $p_request->getHeaderLine( HEADER_IF_NONE_MATCH );
if( $t_etag == $t_match_etag ) {
return $p_response->withStatus( HTTP_STATUS_NOT_MODIFIED, 'Not Modified' );
}
}

# Username and password below are ignored, since middleware already done the auth.
$t_issue = mc_issue_get( /* username */ '', /* password */ '', $t_issue_id );

Expand Down
29 changes: 29 additions & 0 deletions core/bug_api.php
Expand Up @@ -978,6 +978,35 @@ function bug_text_clear_cache( $p_bug_id = null ) {
return true;
}

/**
* Get hash for the bug information. Used in scenarios like ETag for REST API.
* A proper hash will be returned even if the issue doesn't exist.
*
* @param integer $p_bug_id The bug id.
* @param integer|null $p_user_id The user id or null for current logged in user.
* @return string The hash.
*/
function bug_hash( $p_bug_id, $p_user_id = null ) {
# Change this version when it is desired to force clients to refresh issues.
$t_version = 'v1';

if( auth_is_user_authenticated() ) {
$t_user_id = $p_user_id ?: auth_get_current_user_id();
} else {
$t_user_id = $p_user_id ?: '';
}

if( bug_exists( $p_bug_id ) ) {
$t_bug_data = bug_get( $p_bug_id, false );
$t_last_updated = $t_bug_data->last_updated;
} else {
$t_last_updated = '';
}

$t_str_to_hash = $p_bug_id . '_' . $t_last_updated . '_' . $t_user_id . '_' . $t_version;
return hash( 'sha256', $t_str_to_hash );
}

/**
* Check if a bug exists
* @param integer $p_bug_id Integer representing bug identifier.
Expand Down
3 changes: 3 additions & 0 deletions core/constant_inc.php
Expand Up @@ -665,6 +665,7 @@
define( 'HTTP_STATUS_SUCCESS', 200 );
define( 'HTTP_STATUS_CREATED', 201 );
define( 'HTTP_STATUS_NO_CONTENT', 204 );
define( 'HTTP_STATUS_NOT_MODIFIED', 304 );
define( 'HTTP_STATUS_BAD_REQUEST', 400 );
define( 'HTTP_STATUS_UNAUTHORIZED', 401 );
define( 'HTTP_STATUS_FORBIDDEN', 403 );
Expand All @@ -678,6 +679,8 @@
define( 'HEADER_LOGIN_METHOD', 'X-Mantis-LoginMethod' );
define( 'HEADER_USERNAME', 'X-Mantis-Username' );
define( 'HEADER_VERSION', 'X-Mantis-Version' );
define( 'HEADER_IF_NONE_MATCH', 'If-None-Match' );
define( 'HEADER_ETAG', 'ETag' );

# LOGIN METHODS
define( 'LOGIN_METHOD_COOKIE', 'cookie' );
Expand Down

0 comments on commit df98373

Please sign in to comment.