//响应添加报文头
TSReturnCode StaSerRespMimeHdrFieldAppend(TSHttpTxn txnp,char *name,int name_length,char *value,int value_len)
{
	TSMBuffer bufp;
    TSMLoc hdr_loc;
    TSMLoc field_loc;
	if (TSHttpTxnServerRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
		return TS_ERROR;
	}
	field_loc = TSMimeHdrFieldFind(bufp, hdr_loc, name, name_length);
	if(field_loc != TS_NULL_MLOC){
	    TSMimeHdrFieldValuesClear(bufp, hdr_loc, field_loc);
	    TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1, value, value_len);
	    TSHandleMLocRelease(bufp, hdr_loc, field_loc);
	}else{
		if (TSMimeHdrFieldCreate(bufp, hdr_loc, &field_loc) != TS_SUCCESS) {
			return TS_ERROR;
		}
		TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc);
		TSMimeHdrFieldValuesClear(bufp, hdr_loc, field_loc);
		TSMimeHdrFieldNameSet(bufp, hdr_loc, field_loc, name, name_length);
		TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1, value, value_len);
		TSHandleMLocRelease(bufp, hdr_loc, field_loc);
	}
	TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
	return TS_SUCCESS;
}
static int
hdr_handler(TSCont contp, TSHttpTxn txnp)
{
	TSMBuffer  	bufp;
	TSMLoc		hdr_loc, field_loc; 
	hdr_list 	*hdr;

	hdr = TSContDataGet(contp);
	if (hdr == NULL) {
		goto done;
	} 

	if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
		TSError("couldn't retrieve client response header\n");
		goto done;
	}


	for (; hdr; hdr = hdr->next) {
		TSMimeHdrFieldCreate(bufp, hdr_loc, &field_loc);
		TSMimeHdrFieldNameSet(bufp, hdr_loc, field_loc, hdr->name, strlen(hdr->name));
		TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1, hdr->val, strlen(hdr->val));
		TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc);

		TSHandleMLocRelease(bufp, hdr_loc, field_loc);
		TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
	}


done:
	TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
	
	return 0;
}
static void
handle_response(TSHttpTxn txnp)
{
  TSMBuffer bufp;
  TSMLoc hdr_loc, newfield_loc;
  char *errormsg_body = "All requests from this IP address are redirected.\n";
  char *tmp_body;

  if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
    TSError("[%s] Couldn't retrieve client response header", PLUGIN_NAME);
    goto done;
  }

  TSHttpHdrStatusSet(bufp, hdr_loc, TS_HTTP_STATUS_MOVED_PERMANENTLY);
  TSHttpHdrReasonSet(bufp, hdr_loc, TSHttpHdrReasonLookup(TS_HTTP_STATUS_MOVED_PERMANENTLY),
                     strlen(TSHttpHdrReasonLookup(TS_HTTP_STATUS_MOVED_PERMANENTLY)));

  TSMimeHdrFieldCreate(bufp, hdr_loc, &newfield_loc); /* Probably should check for errors ... */
  TSMimeHdrFieldNameSet(bufp, hdr_loc, newfield_loc, TS_MIME_FIELD_LOCATION, TS_MIME_LEN_LOCATION);
  TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, newfield_loc, -1, uri_redirect, strlen(uri_redirect));
  TSMimeHdrFieldAppend(bufp, hdr_loc, newfield_loc);

  /*
   *  Note that we can't directly use errormsg_body, as TSHttpTxnErrorBodySet()
   *  will try to free the passed buffer with TSfree().
   */
  tmp_body = TSstrdup(errormsg_body);
  TSHttpTxnErrorBodySet(txnp, tmp_body, strlen(tmp_body), NULL);
  TSHandleMLocRelease(bufp, hdr_loc, newfield_loc);
  TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);

done:
  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
}
static void
replace_header(TSHttpTxn txnp)
{
    TSMBuffer resp_bufp;
    TSMLoc resp_loc;
    TSMLoc field_loc;

    if (TSHttpTxnServerRespGet(txnp, &resp_bufp, &resp_loc) != TS_SUCCESS) {
        TSError("couldn't retrieve server response header.\n");
        goto done;
    }

    field_loc = TSMimeHdrFieldFind(resp_bufp, resp_loc, TS_MIME_FIELD_ACCEPT_RANGES, TS_MIME_LEN_ACCEPT_RANGES);
    if (field_loc == TS_NULL_MLOC) {
        /* field was not found */

        /* create a new field in the header */
        TSMimeHdrFieldCreate(resp_bufp, resp_loc, &field_loc); /* Probably should check for errors. */
        /* set its name */
        TSMimeHdrFieldNameSet(resp_bufp, resp_loc, field_loc, TS_MIME_FIELD_ACCEPT_RANGES, TS_MIME_LEN_ACCEPT_RANGES);
        /* set its value */
        TSMimeHdrFieldValueAppend(resp_bufp, resp_loc, field_loc, -1, "none", 4);
        /* insert it into the header */
        TSMimeHdrFieldAppend(resp_bufp, resp_loc, field_loc);
        TSHandleMLocRelease(resp_bufp, resp_loc, field_loc);
        TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);
    } else {
        /* clear the field */
        TSMimeHdrFieldValuesClear(resp_bufp, resp_loc, field_loc);
        /* set the value to "none" */
        TSMimeHdrFieldValueStringInsert(resp_bufp, resp_loc, field_loc, -1, "none", 4);
        TSHandleMLocRelease(resp_bufp, resp_loc, field_loc);
        TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);
    }

done:
    TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
}
void
TSPluginInit(int argc, const char *argv[])
{
  TSMLoc field_loc;
  const char *p;
  int i, retval;
  TSPluginRegistrationInfo info;

  info.plugin_name = "add-header";
  info.vendor_name = "MyCompany";
  info.support_email = "*****@*****.**";

  if (TSPluginRegister(TS_SDK_VERSION_3_0, &info) != TS_SUCCESS) {
    TSError("[PluginInit] Plugin registration failed.\n");
    goto error;
  }

  if (!check_ts_version()) {
    TSError("[PluginInit] Plugin requires Traffic Server 3.0 or later\n");
    goto error;
  }

  if (argc < 2) {
    TSError("[PluginInit] Usage: %s \"name1: value1\" \"name2: value2\" ...>\n", argv[0]);
    goto error;
  }

  hdr_bufp = TSMBufferCreate();
  if (TSMimeHdrCreate(hdr_bufp, &hdr_loc) != TS_SUCCESS) {
    TSError("[PluginInit] Can not create mime header");
    goto error;
  }

  for (i = 1; i < argc; i++) {
    if (TSMimeHdrFieldCreate(hdr_bufp, hdr_loc, &field_loc) != TS_SUCCESS) {
      TSError("[PluginInit] Error while creating field");
      goto error;
    }

    retval = TSMimeHdrFieldAppend(hdr_bufp, hdr_loc, field_loc);
    if (retval != TS_SUCCESS) {
      TSError("[PluginInit] Error while adding field");
      goto error;
    }

    p = strchr(argv[i], ':');
    if (p) {
      retval = TSMimeHdrFieldNameSet(hdr_bufp, hdr_loc, field_loc, argv[i], p - argv[i]);
      if (retval == TS_ERROR) {
        TSError("[PluginInit] Error while naming field");
        goto error;
      }

      p += 1;
      while (isspace(*p)) {
        p += 1;
      }
      retval = TSMimeHdrFieldValueStringInsert(hdr_bufp, hdr_loc, field_loc, -1, p, strlen(p));
      if (retval == TS_ERROR) {
        TSError("[PluginInit] Error while inserting field value");
        goto error;
      }
    } else {
      retval = TSMimeHdrFieldNameSet(hdr_bufp, hdr_loc, field_loc, argv[i], strlen(argv[i]));
      if (retval == TS_ERROR) {
        TSError("[PluginInit] Error while inserting field value");
        goto error;
      }
    }
  }

  /* Create a continuation with a mutex as there is a shared global structure
     containing the headers to add */
  TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, TSContCreate(add_header_plugin, TSMutexCreate()));
  goto done;

error:
  TSError("[PluginInit] Plugin not initialized");

done:
  return;
}
Exemple #6
0
/**
 * Handler function to generate an error response
 */
static void error_response(TSHttpTxn txnp, tsib_txn_ctx *txndata)
{
    const char *reason;
    TSMBuffer bufp;
    TSMLoc hdr_loc;
    TSMLoc field_loc;
    hdr_list *hdrs;
    TSReturnCode rv;

    /* make caller responsible for sanity checking */
    assert((txndata != NULL) && (txndata->tx != NULL));

    reason = TSHttpHdrReasonLookup(txndata->status);

    if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
        ib_log_error_tx(txndata->tx,
                        "ErrorDoc: couldn't retrieve client response header.");
        TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
        return;
    }
    rv = TSHttpHdrStatusSet(bufp, hdr_loc, txndata->status);
    if (rv != TS_SUCCESS) {
        ib_log_error_tx(txndata->tx,
                        "ErrorDoc: TSHttpHdrStatusSet");
    }
    if (reason == NULL) {
        reason = "Other";
    }
    rv = TSHttpHdrReasonSet(bufp, hdr_loc, reason, strlen(reason));
    if (rv != TS_SUCCESS) {
        ib_log_error_tx(txndata->tx,
                        "ErrorDoc: TSHttpHdrReasonSet");
    }

    while (hdrs = txndata->err_hdrs, hdrs != 0) {
        txndata->err_hdrs = hdrs->next;
        rv = TSMimeHdrFieldCreate(bufp, hdr_loc, &field_loc);
        if (rv != TS_SUCCESS) {
            ib_log_error_tx(txndata->tx,
                            "ErrorDoc: TSMimeHdrFieldCreate");
            continue;
        }
        rv = TSMimeHdrFieldNameSet(bufp, hdr_loc, field_loc,
                                   hdrs->hdr, strlen(hdrs->hdr));
        if (rv != TS_SUCCESS) {
            ib_log_error_tx(txndata->tx,
                            "ErrorDoc: TSMimeHdrFieldNameSet");
            goto errordoc_free1;
        }
        rv = TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1,
                                        hdrs->value, strlen(hdrs->value));
        if (rv != TS_SUCCESS) {
            ib_log_error_tx(txndata->tx,
                            "ErrorDoc: TSMimeHdrFieldValueStringInsert");
            goto errordoc_free1;
        }
        rv = TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc);
        if (rv != TS_SUCCESS) {
            ib_log_error_tx(txndata->tx,
                            "ErrorDoc: TSMimeHdrFieldAppend");
            goto errordoc_free1;
        }

errordoc_free1:
        rv = TSHandleMLocRelease(bufp, hdr_loc, field_loc);
        if (rv != TS_SUCCESS) {
            ib_log_error_tx(txndata->tx,
                            "ErrorDoc: TSHandleMLocRelease 1");
            continue;
        }
    }

    if (txndata->err_body) {
        /* this will free the body, so copy it first! */
        TSHttpTxnErrorBodySet(txnp, txndata->err_body,
                              txndata->err_body_len, NULL);
    }
    rv = TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    if (rv != TS_SUCCESS) {
        ib_log_error_tx(txndata->tx,
                        "ErrorDoc: TSHandleMLocRelease 2");
    }

    ib_log_debug_tx(txndata->tx,
                    "Sent error page %d \"%s\".", txndata->status, reason);
}
Exemple #7
0
/**
 * Handler function to generate an internal error response
 * when ironbee is unavailable to fill the fields or log errors.
 *
 * This may come from a TXN_START event, in which case we're
 * returning an HTTP/0.9 response and most of this is superfluous.
 */
static void internal_error_response(TSHttpTxn txnp)
{
    TSReturnCode rv;
    const char *reason = "Server Unavailable";
    TSMBuffer bufp;
    TSMLoc hdr_loc;
    TSMLoc field_loc;
    char *body;
    char clen[8];
    int i;
    const struct {
        const char *name;
        const char *val;
    } headers[2] = {
        { "Content-Type", "text/plain" },
        { "Content-Length", clen }
    };

    if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
        TSError("[ironbee] ErrorDoc: couldn't retrieve client response header.");
        return;
    }
    rv = TSHttpHdrStatusSet(bufp, hdr_loc, 503);
    if (rv != TS_SUCCESS) {
        TSError("[ironbee] ErrorDoc: TSHttpHdrStatusSet");
    }
    rv = TSHttpHdrReasonSet(bufp, hdr_loc, reason, strlen(reason));
    if (rv != TS_SUCCESS) {
        TSError("[ironbee] ErrorDoc: TSHttpHdrReasonSet");
    }

    /* this will free the body, so copy it first! */
    body = TSstrdup("Server unavailable or disabled.\n");

    snprintf(clen, sizeof(clen), "%zd", strlen(body));

    for (i = 0; i < 2; ++i) {
        rv = TSMimeHdrFieldCreate(bufp, hdr_loc, &field_loc);
        if (rv != TS_SUCCESS) {
            TSError("[ironbee] ErrorDoc: TSMimeHdrFieldCreate");
            continue;
        }
        rv = TSMimeHdrFieldNameSet(bufp, hdr_loc, field_loc,
                                   headers[i].name, strlen(headers[i].name));
        if (rv != TS_SUCCESS) {
            TSError("[ironbee] ErrorDoc: TSMimeHdrFieldNameSet");
            goto freehdr;
        }
        rv = TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1,
                                             headers[i].val, strlen(headers[i].val));
        if (rv != TS_SUCCESS) {
            TSError("[ironbee] ErrorDoc: TSMimeHdrFieldValueStringInsert");
            goto freehdr;
        }
        rv = TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc);
        if (rv != TS_SUCCESS) {
            TSError("[ironbee] ErrorDoc: TSMimeHdrFieldAppend");
            goto freehdr;
        }

freehdr:
        rv = TSHandleMLocRelease(bufp, hdr_loc, field_loc);
        if (rv != TS_SUCCESS) {
            TSError("[ironbee] ErrorDoc: TSHandleMLocRelease 3");
            continue;
        }
    }

    TSHttpTxnErrorBodySet(txnp, body, strlen(body), NULL);

    rv = TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    if (rv != TS_SUCCESS) {
        TSError("[ironbee] ErrorDoc: TSHandleMLocRelease 4");
    }
}
static void
modify_header(TSHttpTxn txnp)
{
  TSMBuffer resp_bufp;
  TSMBuffer cached_bufp;
  TSMLoc resp_loc;
  TSMLoc cached_loc;
  TSHttpStatus resp_status;
  TSMLoc new_field_loc;
  TSMLoc cached_field_loc;
  time_t recvd_time;

  const char *chkptr;
  int chklength;

  int num_refreshes = 0;

  if (!init_buffer_status)
    return; /* caller reenables */

  if (TSHttpTxnServerRespGet(txnp, &resp_bufp, &resp_loc) != TS_SUCCESS) {
    TSError("couldn't retrieve server response header\n");
    return; /* caller reenables */
  }

  /* TSqa06246/TSqa06144 */
  resp_status = TSHttpHdrStatusGet(resp_bufp, resp_loc);

  if (TS_HTTP_STATUS_OK == resp_status) {
    TSDebug("resphdr", "Processing 200 OK");
    TSMimeHdrFieldCreate(resp_bufp, resp_loc, &new_field_loc); /* Probably should check for errors */
    TSDebug("resphdr", "Created new resp field with loc %p", new_field_loc);

    /* copy name/values created at init
     * ( "x-num-served-from-cache" ) : ( "0"  )
     */
    TSMimeHdrFieldCopy(resp_bufp, resp_loc, new_field_loc, hdr_bufp, hdr_loc, field_loc);

    /*********** Unclear why this is needed **************/
    TSMimeHdrFieldAppend(resp_bufp, resp_loc, new_field_loc);


    /* Cache-Control: Public */
    TSMimeHdrFieldCreate(resp_bufp, resp_loc, &new_field_loc); /* Probably should check for errors */
    TSDebug("resphdr", "Created new resp field with loc %p", new_field_loc);
    TSMimeHdrFieldAppend(resp_bufp, resp_loc, new_field_loc);
    TSMimeHdrFieldNameSet(resp_bufp, resp_loc, new_field_loc, TS_MIME_FIELD_CACHE_CONTROL, TS_MIME_LEN_CACHE_CONTROL);
    TSMimeHdrFieldValueStringInsert(resp_bufp, resp_loc, new_field_loc, -1, TS_HTTP_VALUE_PUBLIC, TS_HTTP_LEN_PUBLIC);

    /*
     * mimehdr2_name  = TSstrdup( "x-date-200-recvd" ) : CurrentDateTime
     */
    TSMimeHdrFieldCreate(resp_bufp, resp_loc, &new_field_loc); /* Probably should check for errors */
    TSDebug("resphdr", "Created new resp field with loc %p", new_field_loc);
    TSMimeHdrFieldAppend(resp_bufp, resp_loc, new_field_loc);
    TSMimeHdrFieldNameSet(resp_bufp, resp_loc, new_field_loc, mimehdr2_name, strlen(mimehdr2_name));
    recvd_time = time(NULL);
    TSMimeHdrFieldValueDateInsert(resp_bufp, resp_loc, new_field_loc, recvd_time);

    TSHandleMLocRelease(resp_bufp, resp_loc, new_field_loc);
    TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);

  } else if (TS_HTTP_STATUS_NOT_MODIFIED == resp_status) {
    TSDebug("resphdr", "Processing 304 Not Modified");

    /* N.B.: Protect writes to data (hash on URL + mutex: (ies)) */

    /* Get the cached HTTP header */
    if (TSHttpTxnCachedRespGet(txnp, &cached_bufp, &cached_loc) != TS_SUCCESS) {
      TSError("STATUS 304, TSHttpTxnCachedRespGet():");
      TSError("couldn't retrieve cached response header\n");
      TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);
      return; /* Caller reenables */
    }

    /* Get the cached MIME field name for this HTTP header */
    cached_field_loc = TSMimeHdrFieldFind(cached_bufp, cached_loc, (const char *)mimehdr1_name, strlen(mimehdr1_name));
    if (TS_NULL_MLOC == cached_field_loc) {
      TSError("Can't find header %s in cached document", mimehdr1_name);
      TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);
      TSHandleMLocRelease(cached_bufp, TS_NULL_MLOC, cached_loc);
      return; /* Caller reenables */
    }

    /* Get the cached MIME value for this name in this HTTP header */
    chkptr = TSMimeHdrFieldValueStringGet(cached_bufp, cached_loc, cached_field_loc, -1, &chklength);
    if (NULL == chkptr || !chklength) {
      TSError("Could not find value for cached MIME field name %s", mimehdr1_name);
      TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);
      TSHandleMLocRelease(cached_bufp, TS_NULL_MLOC, cached_loc);
      TSHandleMLocRelease(cached_bufp, cached_loc, cached_field_loc);
      return; /* Caller reenables */
    }
    TSDebug("resphdr", "Header field value is %s, with length %d", chkptr, chklength);


    /* Get the cached MIME value for this name in this HTTP header */
    /*
       TSMimeHdrFieldValueUintGet(cached_bufp, cached_loc, cached_field_loc, 0, &num_refreshes);
       TSDebug("resphdr",
       "Cached header shows %d refreshes so far", num_refreshes );

       num_refreshes++ ;
     */

    /* txn origin server response for this transaction stored
    * in resp_bufp, resp_loc
    *
    * Create a new MIME field/value. Cached value has been incremented.
    * Insert new MIME field/value into the server response buffer,
    * allow HTTP processing to continue. This will update
    * (indirectly invalidates) the cached HTTP headers MIME field.
    * It is apparently not necessary to update all of the MIME fields
    * in the in-process response in order to have the cached response
    * become invalid.
  */
    TSMimeHdrFieldCreate(resp_bufp, resp_loc, &new_field_loc); /* Probaby should check for errrors */

    /* mimehdr1_name : TSstrdup( "x-num-served-from-cache" ) ; */

    TSMimeHdrFieldAppend(resp_bufp, resp_loc, new_field_loc);
    TSMimeHdrFieldNameSet(resp_bufp, resp_loc, new_field_loc, mimehdr1_name, strlen(mimehdr1_name));

    TSMimeHdrFieldValueUintInsert(resp_bufp, resp_loc, new_field_loc, -1, num_refreshes);

    TSHandleMLocRelease(resp_bufp, resp_loc, new_field_loc);
    TSHandleMLocRelease(cached_bufp, cached_loc, cached_field_loc);
    TSHandleMLocRelease(cached_bufp, TS_NULL_MLOC, cached_loc);
    TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);

  } else {
    TSDebug("resphdr", "other response code %d", resp_status);
  }

  /*
   *  Additional 200/304 processing can go here, if so desired.
   */

  /* Caller reneables */
}
void
TSPluginInit(int argc, const char *argv[])
{
  TSMLoc chk_field_loc;

  TSPluginRegistrationInfo info;

  info.plugin_name = "response-header-1";
  info.vendor_name = "MyCompany";
  info.support_email = "*****@*****.**";

  if (TSPluginRegister(&info) != TS_SUCCESS) {
    TSError("Plugin registration failed.\n");
  }

  init_buffer_status = 0;
  if (argc > 1) {
    TSError("usage: %s \n", argv[0]);
    TSError("warning: too many args %d\n", argc);
    TSError("warning: ignoring unused arguments beginning with %s\n", argv[1]);
  }

  /*
   *  The following code sets up an "init buffer" containing an extension header
   *  and its initial value.  This will be the same for all requests, so we try
   *  to be efficient and do all of the work here rather than on a per-transaction
   *  basis.
   */


  hdr_bufp = TSMBufferCreate();
  TSMimeHdrCreate(hdr_bufp, &hdr_loc);

  mimehdr1_name = TSstrdup("x-num-served-from-cache");
  mimehdr1_value = TSstrdup("0");

  /* Create name here and set DateTime value when o.s.
   * response 200 is received
   */
  mimehdr2_name = TSstrdup("x-date-200-recvd");

  TSDebug("resphdr", "Inserting header %s with value %s into init buffer", mimehdr1_name, mimehdr1_value);

  TSMimeHdrFieldCreate(hdr_bufp, hdr_loc, &field_loc); /* Probably should check for errors */
  TSMimeHdrFieldAppend(hdr_bufp, hdr_loc, field_loc);
  TSMimeHdrFieldNameSet(hdr_bufp, hdr_loc, field_loc, mimehdr1_name, strlen(mimehdr1_name));
  TSMimeHdrFieldValueStringInsert(hdr_bufp, hdr_loc, field_loc, -1, mimehdr1_value, strlen(mimehdr1_value));
  TSDebug("resphdr", "init buffer hdr, field and value locs are %p, %p and %p", hdr_loc, field_loc, value_loc);
  init_buffer_status = 1;


  TSHttpHookAdd(TS_HTTP_READ_RESPONSE_HDR_HOOK, TSContCreate(modify_response_header_plugin, NULL));

  /*
   *  The following code demonstrates how to extract the field_loc from the header.
   *  In this plugin, the init buffer and thus field_loc never changes.  Code
   *  similar to this may be used to extract header fields from any buffer.
   */

  if (TS_NULL_MLOC == (chk_field_loc = TSMimeHdrFieldGet(hdr_bufp, hdr_loc, 0))) {
    TSError("couldn't retrieve header field from init buffer");
    TSError("marking init buffer as corrupt; no more plugin processing");
    init_buffer_status = 0;
    /* bail out here and reenable transaction */
  } else {
    if (field_loc != chk_field_loc)
      TSError("retrieved buffer field loc is %p when it should be %p", chk_field_loc, field_loc);
  }
}