[ 
https://issues.apache.org/jira/browse/TS-4395?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15357328#comment-15357328
 ] 

ASF GitHub Bot commented on TS-4395:
------------------------------------

Github user jpeach commented on a diff in the pull request:

    https://github.com/apache/trafficserver/pull/747#discussion_r69159927
  
    --- Diff: plugins/experimental/remap_purge/remap_purge.c ---
    @@ -0,0 +1,335 @@
    +/** @file
    +
    +  Per-remap purge RESTful API for stateful generation ID management.
    +
    +  @section license License
    +
    +  Licensed to the Apache Software Foundation (ASF) under one
    +  or more contributor license agreements.  See the NOTICE file
    +  distributed with this work for additional information
    +  regarding copyright ownership.  The ASF licenses this file
    +  to you under the Apache License, Version 2.0 (the
    +  "License"); you may not use this file except in compliance
    +  with the License.  You may obtain a copy of the License at
    +
    +      http://www.apache.org/licenses/LICENSE-2.0
    +
    +  Unless required by applicable law or agreed to in writing, software
    +  distributed under the License is distributed on an "AS IS" BASIS,
    +  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +  See the License for the specific language governing permissions and
    +  limitations under the License.
    + */
    +
    +#include <stdio.h>
    +#include <stdlib.h>
    +#include <ctype.h>
    +#include <string.h>
    +#include <sys/types.h>
    +#include <unistd.h>
    +#include <getopt.h>
    +#include <sys/stat.h>
    +#include <sys/types.h>
    +
    +#include "ts/ts.h"
    +#include "ts/remap.h"
    +#include "ts/ink_defs.h"
    +
    +static const char *PLUGIN_NAME = "remap_purge";
    +static const char *DEFAULT_DIR = "var/trafficserver"; /* Not perfect, but 
no better API) */
    +
    +typedef struct PurgeInstance_t {
    +  char *id;
    +  char *secret;
    +  int secret_len;
    +  char *header;
    +  int header_len;
    +  char *state_file;
    +  bool allow_get;
    +  int64_t gen_id;
    +  TSMutex lock;
    +} PurgeInstance;
    +
    +static char *
    +make_state_path(const char *filename)
    +{
    +  if ('/' == *filename) {
    +    return TSstrdup(filename);
    +  } else {
    +    char buf[8192];
    +    struct stat s;
    +    const char *dir = TSInstallDirGet();
    +
    +    snprintf(buf, sizeof(buf) - 1, "%s/%s/%s", dir, DEFAULT_DIR, 
PLUGIN_NAME);
    +    if (-1 == stat(buf, &s)) {
    +      if (ENOENT == errno) {
    +        if (-1 == mkdir(buf, S_IRWXU)) {
    +          TSError("[%s] Unable to create directory %s: errno=%d", 
PLUGIN_NAME, buf, errno);
    +          return NULL;
    +        }
    +      } else {
    +        TSError("[%s] Unable to stat() directory %s: errno=%d", 
PLUGIN_NAME, buf, errno);
    +        return NULL;
    +      }
    +    } else {
    +      if (!S_ISDIR(s.st_mode)) {
    +        TSError("[%s] Can not create directory %s, file exists", 
PLUGIN_NAME, buf);
    +        return NULL;
    +      }
    +    }
    +    snprintf(buf, sizeof(buf) - 1, "%s/%s/%s/%s.genid", dir, DEFAULT_DIR, 
PLUGIN_NAME, filename);
    +    return TSstrdup(buf);
    +  }
    +
    +  return NULL;
    +}
    +
    +/* Constructor and destructor for the PurgeInstance */
    +static void
    +init_purge_instance(PurgeInstance *purge, char *id)
    +{
    +  FILE *file = fopen(purge->state_file, "r");
    +
    +  if (file) {
    +    fscanf(file, "%" PRId64 "", &purge->gen_id);
    +    TSDebug(PLUGIN_NAME, "Read genID from %s for %s", purge->state_file, 
purge->id);
    +  }
    +
    +  /* If not specified, we set the ID tag to the fromURL from the remap 
rule that triggered */
    +  if (!purge->id) {
    +    purge->id = TSstrdup(id);
    +  }
    +
    +  purge->lock = TSMutexCreate();
    +}
    +
    +static void
    +delete_purge_instance(PurgeInstance *purge)
    +{
    +  if (purge) {
    +    TSfree(purge->id);
    +    TSfree(purge->state_file);
    +    TSfree(purge->secret);
    +    TSfree(purge->header);
    +    TSMutexDestroy(purge->lock);
    +    TSfree(purge);
    +  }
    +}
    +
    +/* This is where we start the PURGE events, setting up the transactino to 
fail,
    +   and bump the generation ID, and finally save the state. */
    +static int
    +on_http_cache_lookup_complete(TSHttpTxn txnp, TSCont contp, PurgeInstance 
*purge)
    +{
    +  FILE *file;
    +
    +  TSMutexLock(purge->lock);
    +
    +  ++purge->gen_id;
    +  TSDebug(PLUGIN_NAME, "Bumping the Generation ID to %" PRId64 " for %s", 
purge->gen_id, purge->id);
    +
    +  if ((file = fopen(purge->state_file, "w"))) {
    +    TSDebug(PLUGIN_NAME, "\tsaving state to %s", purge->state_file);
    +    fprintf(file, "%" PRId64 "", purge->gen_id);
    +    fclose(file);
    +  } else {
    +    TSError("[%s] Unable to save state to file %s: errno=%d", PLUGIN_NAME, 
purge->state_file, errno);
    +  }
    +
    +  TSMutexUnlock(purge->lock);
    +
    +  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR);
    +  return TS_SUCCESS;
    +}
    +
    +/* Before we can send the response, we want to modify it to a "200 OK" 
again,
    +   and produce some reasonabel body output. */
    +static int
    +on_send_response_header(TSHttpTxn txnp, TSCont contp, PurgeInstance *purge)
    +{
    +  TSMBuffer bufp;
    +  TSMLoc hdr_loc;
    +
    +  TSDebug(PLUGIN_NAME, "Fixing up the response on the succseful PURGE");
    --- End diff --
    
    "successful"


> conf_purge: Simple plugin to purge an entire remap rule
> -------------------------------------------------------
>
>                 Key: TS-4395
>                 URL: https://issues.apache.org/jira/browse/TS-4395
>             Project: Traffic Server
>          Issue Type: New Feature
>          Components: Plugins
>            Reporter: Leif Hedstrom
>            Assignee: Leif Hedstrom
>             Fix For: 7.0.0
>
>
> This is similar to the existing plugin to purge based on a genID stored in a 
> persistent storage. The difference is that the purging is done exclusively 
> via a restful API, and has little (no) overhead on performance (since the 
> generation ID is always in memory).
> Example:
> {code}
> map http://example.com/p1  http://p1.example.com
>     @plugin=remap_purge.so @pparam=--path=__secret_purge__  
> @pparam=--state=example_p1
> {code}
> And to purge:
> {code}
> $ curl -s -D - -X PURGE http://example.com/p1/__secret_purge__
> HTTP/1.1 200 OK
> Date: Sat, 30 Apr 2016 00:09:34 GMT
> Connection: close
> Server: ATS/7.0.0
> Content-Length: 39
> Content-Type: text/html
> PURGED http://example.com/p1
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to