Beispiel #1
0
PTR_WEIBO_ENTITY show_single_weibo_byid(const char* access_token, const char* weibo_id)
{
  const char* func_name = __func__;
  debug_log_enter(FINE, func_name, "ss", access_token, weibo_id);
  char s[20] = {};
  cJSON* root = NULL;
  PTR_WEIBO_ENTITY weibo = NULL;
  PTR_HTTP_REQUEST request = alloc_http_request(2, 0, 0, 0);
  PTR_HTTP_RESPONSE response = NULL;
  request->params[0].name = "access_token";
  request->params[0].value = access_token;
  request->params[1].name = "id";
  request->params[1].value = weibo_id;

  response = https_get(WEIBO_SHOW_WEIBO_URL, request);
  if (response->status_code != 200) {
    free_http_request(request);
    free_http_response(response);
    return NULL;
  }

  root = cJSON_Parse((char*)(response->body));
  if (check_api_error(root)) {
    free_http_request(request);
    free_http_response(response);
    cJSON_Delete(root);
    return NULL;
  }
  weibo = create_weibo_entity_from_json(root);
  free_http_request(request);
  free_http_response(response);
  cJSON_Delete(root);
  debug_log_exit(FINE, func_name);
  return weibo;
}
Beispiel #2
0
PTR_WEIBO_ENTITY show_multiple_weibo_byids(const char* access_token, char** weibo_ids, uint32_t count)
{
  const char* func_name = __func__;
  debug_log_enter(FINE, func_name, "spd", access_token, weibo_ids, count);
  char s[2048] = {};
  uint32_t i = 0;
  uint32_t cnt = count>MAX_BATCH_SIZE?MAX_BATCH_SIZE:count;
  cJSON* root = NULL;
  cJSON* statuses = NULL;
  PTR_WEIBO_ENTITY list_head = NULL;
  PTR_WEIBO_ENTITY weibo = NULL;
  PTR_HTTP_REQUEST request = alloc_http_request(2, 0, 0, 0);
  PTR_HTTP_RESPONSE response = NULL;

  memset(s, 0, sizeof(char)*sizeof(s));
  sprintf(s, "%s", weibo_ids[0]);
  for (i=1; i<cnt; i++) {
    sprintf(s, "%s,%s", s, weibo_ids[i]);
  }
  s[strlen(s)] = '\0';

  request->params[0].name = "access_token";
  request->params[0].value = access_token;
  request->params[1].name = "ids";
  request->params[1].value = s;

  response = https_get(WEIBO_SHOW_WEIBO_BATCH_URL, request);
  if (response->status_code != 200) {
    free_http_request(request);
    free_http_response(response);
    return NULL;
  }

  root = cJSON_Parse((char*)(response->body));
  if (check_api_error(root)) {
    free_http_request(request);
    free_http_response(response);
    cJSON_Delete(root);
    return NULL;
  }

  statuses = cJSON_GetObjectItem(root, "statuses");
  cnt = cJSON_GetArraySize(statuses);

  for (i=0; i<cnt; i++) {
    weibo = create_weibo_entity_from_json(cJSON_GetArrayItem(statuses, i));
    weibo->next = list_head;
    weibo->prev = NULL;
    if (list_head != NULL) {
      list_head->prev = weibo;
    }
    list_head = weibo;
  }

  free_http_request(request);
  free_http_response(response);
  cJSON_Delete(root);
  debug_log_exit(FINE, func_name);
  return list_head;
}
Beispiel #3
0
char* fetch_access_token(const char* code, char* token)
{
  const char* func_name = __func__;
  debug_log_enter(FINE, func_name, "sp", code, token);
  cJSON* root = NULL;
  PTR_HTTP_REQUEST request = alloc_http_request(5, 0, 0, 0);
  PTR_HTTP_RESPONSE response = NULL;
  request->params[0].name = "client_id";
  request->params[0].value = APP_KEY;
  request->params[1].name = "client_secret";
  request->params[1].value = APP_SECRET;
  request->params[2].name = "grant_type";
  request->params[2].value = "authorization_code";
  request->params[3].name = "code";
  request->params[3].value = code;
  request->params[4].name = "redirect_uri";
  request->params[4].value = APP_AUTH_REDIRECT_URL;

  response = https_post(APP_FETCH_TOKEN_URL, request);
  if (response->status_code != 200) {
    free_http_request(request);
    free_http_response(response);
    return NULL;
  }

  root = cJSON_Parse((char*)(response->body));
  sprintf(token, "%s", cJSON_GetObjectItem(root, "access_token")->valuestring);

  free_http_request(request);
  free_http_response(response);
  cJSON_Delete(root);
  debug_log_exit(FINE, func_name);
  return token;
}
Beispiel #4
0
BOOL get_access_token_info(const char* access_token)
{
  const char* func_name = __func__;
  debug_log_enter(FINE, func_name, "s", access_token);
  cJSON* root = NULL;
  PTR_HTTP_REQUEST request = alloc_http_request(1, 0, 0, 0);
  PTR_HTTP_RESPONSE response = NULL;
  request->params[0].name = "access_token";
  request->params[0].value = access_token;

  response = https_post(APP_GET_TOKEN_INFO_URL, request);
  if (response->status_code != 200) {
    free_http_request(request);
    free_http_response(response);
    return False;
  }

  root = cJSON_Parse((char*)(response->body));
  if (check_api_error(root)) {
    free_http_request(request);
    free_http_response(response);
    cJSON_Delete(root);
    return False;
  }

  free_http_request(request);
  free_http_response(response);
  cJSON_Delete(root);
  debug_log_exit(FINE, func_name);
  return True;
}
Beispiel #5
0
PTR_WEIBO_ENTITY get_user_timeline(const char* access_token, const char* uid, int page)
{
  const char* func_name = __func__;
  debug_log_enter(FINE, func_name, "sd", access_token, page);
  char s[20] = {};
  int i=0, cnt = 0;
  cJSON* root = NULL;
  cJSON* statuses = NULL;
  PTR_WEIBO_ENTITY list_head = NULL;
  PTR_WEIBO_ENTITY weibo = NULL;
  PTR_HTTP_REQUEST request = alloc_http_request(3, 0, 0, 0);
  PTR_HTTP_RESPONSE response = NULL;
  request->params[0].name = "access_token";
  request->params[0].value = access_token;
  request->params[1].name = "page";
  snprintf(s, 20, "%d", page);
  request->params[1].value = s;
  request->params[2].name = "uid";
  request->params[2].value = uid;

  response = https_get(WEIBO_GET_USER_TIMELINE_URL, request);
  if (response->status_code != 200) {
    free_http_request(request);
    free_http_response(response);
    return NULL;
  }

  root = cJSON_Parse((char*)(response->body));
  if (check_api_error(root)) {
    free_http_request(request);
    free_http_response(response);
    cJSON_Delete(root);
    return NULL;
  }

  statuses = cJSON_GetObjectItem(root, "statuses");
  cnt = cJSON_GetArraySize(statuses);

  for (i=0; i<cnt; i++) {
    weibo = create_weibo_entity_from_json(cJSON_GetArrayItem(statuses, i));
    weibo->next = list_head;
    weibo->prev = NULL;
    if (list_head != NULL) {
      list_head->prev = weibo;
    }
    list_head = weibo;
  }

  free_http_request(request);
  free_http_response(response);
  cJSON_Delete(root);
  debug_log_exit(FINE, func_name);
  return list_head;
}
Beispiel #6
0
PTR_WEIBO_ENTITY get_user_timeline_byname(const char* access_token, const char* name, int page)
{
  const char* func_name = __func__;
  debug_log_enter(FINE, func_name, "ssd", access_token, name, page);
  char s[20] = {};
  char *weibo_id = NULL;
  int i = 0, cnt = 0;
  cJSON* root = NULL;
  PTR_WEIBO_ENTITY list_head = NULL;
  PTR_WEIBO_ENTITY weibo = NULL;
  PTR_HTTP_REQUEST request = alloc_http_request(4, 0, 0, 0);
  PTR_HTTP_RESPONSE response = NULL;
  request->params[0].name = "access_token";
  request->params[0].value = access_token;
  request->params[1].name = "name";
  request->params[1].value = name;
  snprintf(s, 20, "%d", page);
  request->params[2].name="page";
  request->params[2].value=s;
  request->params[3].name="count";
  request->params[3].value="5"; /* hard code as 5 for api invocation limit */

  response = https_get(WEIBO_GET_USER_TIMELINE_IDS_URL, request);
  if (response->status_code != 200) {
    free_http_request(request);
    free_http_response(response);
    return NULL;
  }

  root = cJSON_Parse((char*)(response->body));
  if (check_api_error(root)) {
    free_http_request(request);
    free_http_response(response);
    cJSON_Delete(root);
    return NULL;
  }
  cnt = cJSON_GetArraySize(cJSON_GetObjectItem(root, "statuses"));
  for (i=0; i<cnt; i++) {
    weibo_id = (cJSON_GetArrayItem(cJSON_GetObjectItem(root, "statuses"), i))->valuestring;
    weibo = show_single_weibo_byid(access_token, weibo_id);
    weibo->next = list_head;
    weibo->prev = NULL;
    if (list_head != NULL) {
      list_head->prev = weibo;
    }
    list_head = weibo;
  }
  free_http_request(request);
  free_http_response(response);
  cJSON_Delete(root);
  debug_log_exit(FINE, func_name);
  return list_head;
}
char* get_ip_from_url(char* url)
{
	char* ip = NULL;
	http_response* page = get_url(url, NULL);
	if(page != NULL)
	{
		if(page->data != NULL)
		{
			int status;
			regex_t re;
			if (regcomp(&re, "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)", REG_EXTENDED) == 0)
			{
				regmatch_t m[5];
				status = regexec(&re, page->data, (size_t) 5, m, 0);
				if(status == 0)
				{
					int ip_length = m[0].rm_eo - m[0].rm_so;
					ip = (char*)malloc((1+ip_length)*sizeof(char));
					ip = memcpy(ip, page->data + m[0].rm_so, ip_length);
					ip[ip_length] = '\0';
				}
				regfree(&re);
			}
		}
		free_http_response(page);
	}
	return ip;
}
Beispiel #8
0
PTR_WEIBO_ENTITY get_user_timeline_byids(const char* access_token, const char* uid, int page)
{
  const char* func_name = __func__;
  debug_log_enter(FINE, func_name, "ssd", access_token, uid, page);
  char s[20] = {};
  char **weibo_ids = NULL;
  int i = 0, cnt = 0;
  cJSON* root = NULL;
  PTR_WEIBO_ENTITY list_head = NULL;
  PTR_WEIBO_ENTITY weibo = NULL;
  PTR_HTTP_REQUEST request = alloc_http_request(3, 0, 0, 0);
  PTR_HTTP_RESPONSE response = NULL;
  request->params[0].name = "access_token";
  request->params[0].value = access_token;
  request->params[1].name = "uid";
  request->params[1].value = uid;
  snprintf(s, 20, "%d", page);
  request->params[2].name="page";
  request->params[2].value=s;

  response = https_get(WEIBO_GET_USER_TIMELINE_IDS_URL, request);
  if (response->status_code != 200) {
    free_http_request(request);
    free_http_response(response);
    return NULL;
  }

  root = cJSON_Parse((char*)(response->body));
  if (check_api_error(root)) {
    free_http_request(request);
    free_http_response(response);
    cJSON_Delete(root);
    return NULL;
  }
  cnt = cJSON_GetArraySize(cJSON_GetObjectItem(root, "statuses"));
  weibo_ids = (char**) malloc(sizeof(char*)*cnt);
  for (i=0; i<cnt; i++) {
    weibo_ids[i] = (cJSON_GetArrayItem(cJSON_GetObjectItem(root, "statuses"), i))->valuestring;
  }
  list_head = show_multiple_weibo_byids(access_token, weibo_ids, cnt);
  free_http_request(request);
  free_http_response(response);
  free(weibo_ids);
  cJSON_Delete(root);
  debug_log_exit(FINE, func_name);
  return list_head;
}
Beispiel #9
0
BOOL repost_weibo(const char* access_token, const char* text, const char* weibo_id)
{
  const char* func_name = __func__;
  debug_log_enter(FINE, func_name, "sss", access_token, text, weibo_id);
  cJSON* root = NULL;
  PTR_HTTP_REQUEST request = alloc_http_request(0, 0, 0, (100+strlen(text))*sizeof(char));
  PTR_HTTP_RESPONSE response = NULL;
  /*
  request->form[0].name = "access_token";
  request->form[0].value = access_token;
  request->form[0].type = STRING;
  request->form[1].name = "status";
  request->form[1].value = text;
  request->form[1].type = STRING;
  request->form[2].name = "id";
  request->form[2].value = weibo_id;
  request->form[2].type = STRING;
  */
  sprintf((char*)(request->body), "access_token=%s&id=%s&status=%s", access_token, weibo_id, text);
  request->body_length = strlen((char*)(request->body));
  response = https_post(WEIBO_REPOST_URL, request);
  if (response->status_code != 200) {
    free_http_request(request);
    free_http_response(response);
    return False;
  }

  root = cJSON_Parse((char*)(response->body));
  if (check_api_error(root)) {
    free_http_request(request);
    free_http_response(response);
    cJSON_Delete(root);
    return False;
  }
  free_http_request(request);
  free_http_response(response);
  cJSON_Delete(root);
  debug_log_exit(FINE, func_name);
  return True;
}
Beispiel #10
0
BOOL create_weibo_pic(const char* access_token, const char* text, const char* pic_name)
{
  const char* func_name = __func__;
  debug_log_enter(FINE, func_name, "ss", access_token, text);
  cJSON* root = NULL;
  PTR_HTTP_REQUEST request = alloc_http_request(0, 0, 3, 0);
  PTR_HTTP_RESPONSE response = NULL;
  request->form[0].name = "access_token";
  request->form[0].value = access_token;
  request->form[0].type = STRING;
  request->form[1].name = "status";
  request->form[1].value = text;
  request->form[1].type = STRING;
  request->form[2].name = "pic";
  request->form[2].value = pic_name;
  request->form[2].type = FILENAME;

  response = https_post(WEIBO_CREATE_URL, request);
  if (response->status_code != 200) {
    free_http_request(request);
    free_http_response(response);
    return False;
  }

  root = cJSON_Parse((char*)(response->body));
  if (check_api_error(root)) {
    free_http_request(request);
    free_http_response(response);
    cJSON_Delete(root);
    return False;
  }
  free_http_request(request);
  free_http_response(response);
  cJSON_Delete(root);
  debug_log_exit(FINE, func_name);
  return True;
}
Beispiel #11
0
/*********************************************************************
 *
 * Function    :  redirect_url
 *
 * Description :  Checks for redirection URLs and returns a HTTP redirect
 *                to the destination URL, if necessary
 *
 * Parameters  :
 *          1  :  csp = Current client state (buffers, headers, etc...)
 *
 * Returns     :  NULL if URL was clean, HTTP redirect otherwise.
 *
 *********************************************************************/
struct http_response *redirect_url(struct client_state *csp)
{
   char *p, *q;
   struct http_response *rsp;

   p = q = csp->http->path;
   log_error(LOG_LEVEL_REDIRECTS, "checking path for redirects: %s", p);

   /*
    * find the last URL encoded in the request
    */
   while ((p = strstr(p, "http://")) != NULL)
   {
      q = p++;
   }

   /*
    * if there was any, generate and return a HTTP redirect
    */
   if (q != csp->http->path)
   {
      log_error(LOG_LEVEL_REDIRECTS, "redirecting to: %s", q);

      if (NULL == (rsp = alloc_http_response()))
      {
         return cgi_error_memory();
      }

      if ( enlist_unique_header(rsp->headers, "Location", q)
        || (NULL == (rsp->status = strdup("302 Local Redirect from Privoxy"))) )
      {
         free_http_response(rsp);
         return cgi_error_memory();
      }

      return finish_http_response(rsp);
   }
   else
   {
      return NULL;
   }

}
Beispiel #12
0
/*
 * Parses return code from libcurl operation and
 * reports if different than 200 and 100
 */
void check_response_code(churl_context* context)
{
	long 	 response_code;
	char	*response_text = NULL;
	int 	 curl_error;

	if (CURLE_OK != (curl_error = curl_easy_getinfo(context->curl_handle, CURLINFO_RESPONSE_CODE, &response_code)))
		elog(ERROR, "internal error: curl_easy_getinfo failed(%d - %s)",
			 curl_error, curl_easy_strerror(curl_error));

	elog(DEBUG2, "http response code: %ld", response_code);
	if ((response_code == 0) && (context->curl_still_running > 0))
	{
		elog(DEBUG2, "check_response_code: curl is still running, but no data was received.");
	}
	else if (response_code != 200 && response_code != 100)
	{
		StringInfoData err;
		char    *http_error_msg;
		char    *addr;

		initStringInfo(&err);

		/* prepare response text if any */
		if (context->download_buffer->ptr)
		{
			context->download_buffer->ptr[context->download_buffer->top] = '\0';
			response_text = context->download_buffer->ptr + context->download_buffer->bot;
		}

		/* add remote http error code */
		appendStringInfo(&err, "remote component error (%ld)", response_code);

		addr = get_dest_address(context->curl_handle);
		if (strlen(addr) != 0)
		{
			appendStringInfo(&err, " from %s", addr);
		}
		pfree(addr);

		if (!handle_special_error(response_code, &err))
		{
			/*
			 * add detailed error message from the http response. response_text
			 * could be NULL in some cases. get_http_error_msg checks for that.
			 */
			http_error_msg = get_http_error_msg(response_code, response_text, context->curl_error_buffer);
			/* check for a specific confusing error, and replace with a clearer one */
			if (strstr(http_error_msg, "instance does not contain any root resource classes") != NULL)
			{
				appendStringInfo(&err, " : PXF not correctly installed in CLASSPATH");
			}
			else
			{
				appendStringInfo(&err, ": %s", http_error_msg);
			}
		}

		elog(ERROR, "%s", err.data);

	}

	free_http_response(context);
}
Beispiel #13
0
/*********************************************************************
 *
 * Function    :  trust_url FIXME: I should be called distrust_url
 *
 * Description :  Calls is_untrusted_url to determine if the URL is trusted
 *                and if not, returns a HTTP 304 response with a reject message.
 *
 * Parameters  :
 *          1  :  csp = Current client state (buffers, headers, etc...)
 *
 * Returns     :  NULL => trusted, else http_response.
 *
 *********************************************************************/
struct http_response *trust_url(struct client_state *csp)
{
   struct http_response *rsp;
   struct map * exports;
   char buf[BUFFER_SIZE];
   char *p;
   struct url_spec **tl;
   struct url_spec *t;
   jb_err err;

   /*
    * Don't bother to work on trusted URLs
    */
   if (!is_untrusted_url(csp))
   {
      return NULL;
   }

   /*
    * Else, prepare a response:
    */
   if (NULL == (rsp = alloc_http_response()))
   {
      return cgi_error_memory();
   }

   exports = default_exports(csp, NULL);
   if (exports == NULL)
   {
      free_http_response(rsp);
      return cgi_error_memory();
   }

   /*
    * Export the protocol, host, port, and referrer information
    */
   err = map(exports, "hostport", 1, csp->http->hostport, 1);
   if (!err) err = map(exports, "protocol", 1, csp->http->ssl ? "https://" : "http://", 1); 
   if (!err) err = map(exports, "path", 1, csp->http->path, 1);

   if (NULL != (p = get_header_value(csp->headers, "Referer:")))
   {
      if (!err) err = map(exports, "referrer", 1, html_encode(p), 0);
   }
   else
   {
      if (!err) err = map(exports, "referrer", 1, "unknown", 1);
   }

   if (err)
   {
      free_map(exports);
      free_http_response(rsp);
      return cgi_error_memory();
   }

   /*
    * Export the trust list
    */
   p = strdup("");
   for (tl = csp->config->trust_list; (t = *tl) != NULL ; tl++)
   {
      sprintf(buf, "<li>%s</li>\n", t->spec);
      string_append(&p, buf);
   }
   err = map(exports, "trusted-referrers", 1, p, 0);

   if (err)
   {
      free_map(exports);
      free_http_response(rsp);
      return cgi_error_memory();
   }

   /*
    * Export the trust info, if available
    */
   if (csp->config->trust_info->first)
   {
      struct list_entry *l;

      p = strdup("");
      for (l = csp->config->trust_info->first; l ; l = l->next)
      {
         sprintf(buf, "<li> <a href=\"%s\">%s</a><br>\n",l->str, l->str);
         string_append(&p, buf);
      }
      err = map(exports, "trust-info", 1, p, 0);
   }
   else
   {
      err = map_block_killer(exports, "have-trust-info");
   }

   if (err)
   {
      free_map(exports);
      free_http_response(rsp);
      return cgi_error_memory();
   }

   /*
    * Export the force prefix or the force conditional block killer
    */
#ifdef FEATURE_FORCE_LOAD
   err = map(exports, "force-prefix", 1, FORCE_PREFIX, 1);
#else /* ifndef FEATURE_FORCE_LOAD */
   err = map_block_killer(exports, "force-support");
#endif /* ndef FEATURE_FORCE_LOAD */

   if (err)
   {
      free_map(exports);
      free_http_response(rsp);
      return cgi_error_memory();
   }

   /*
    * Build the response
    */
   err = template_fill_for_cgi(csp, "untrusted", exports, rsp);
   if (err)
   {
      free_http_response(rsp);
      return cgi_error_memory();
   }

   return finish_http_response(rsp);
}
Beispiel #14
0
/*********************************************************************
 *
 * Function    :  block_url
 *
 * Description :  Called from `chat'.  Check to see if we need to block this.
 *
 * Parameters  :
 *          1  :  csp = Current client state (buffers, headers, etc...)
 *
 * Returns     :  NULL => unblocked, else HTTP block response
 *
 *********************************************************************/
struct http_response *block_url(struct client_state *csp)
{
#ifdef FEATURE_IMAGE_BLOCKING
   char *p;
#endif /* def FEATURE_IMAGE_BLOCKING */
   struct http_response *rsp;

   /*
    * If it's not blocked, don't block it ;-)
    */
   if ((csp->action->flags & ACTION_BLOCK) == 0)
   {
      return NULL;
   }

   /*
    * Else, prepare a response
    */
   if (NULL == (rsp = alloc_http_response()))
   {
      return cgi_error_memory();
   }

   /*
    * If it's an image-url, send back an image or redirect
    * as specified by the relevant +image action
    */
#ifdef FEATURE_IMAGE_BLOCKING
   if (((csp->action->flags & ACTION_IMAGE_BLOCKER) != 0)
        && is_imageurl(csp))
   {
      /* determine HOW images should be blocked */
      p = csp->action->string[ACTION_STRING_IMAGE_BLOCKER];

#if 1 /* Two alternative strategies, use this one for now: */

      /* and handle accordingly: */
      if ((p == NULL) || (0 == strcmpic(p, "pattern")))
      {
         rsp->body = bindup(image_pattern_data, image_pattern_length);
         if (rsp->body == NULL)
         {
            free_http_response(rsp);
            return cgi_error_memory();
         }
         rsp->content_length = image_pattern_length;

         if (enlist_unique_header(rsp->headers, "Content-Type", BUILTIN_IMAGE_MIMETYPE))
         {
            free_http_response(rsp);
            return cgi_error_memory();
         }
      }

      else if (0 == strcmpic(p, "blank"))
      {
         rsp->body = bindup(image_blank_data, image_blank_length);
         if (rsp->body == NULL)
         {
            free_http_response(rsp);
            return cgi_error_memory();
         }
         rsp->content_length = image_blank_length;

         if (enlist_unique_header(rsp->headers, "Content-Type", BUILTIN_IMAGE_MIMETYPE))
         {
            free_http_response(rsp);
            return cgi_error_memory();
         }
      }

      else
      {
         rsp->status = strdup("302 Local Redirect from Privoxy");
         if (rsp->status == NULL)
         {
            free_http_response(rsp);
            return cgi_error_memory();
         }

         if (enlist_unique_header(rsp->headers, "Location", p))
         {
            free_http_response(rsp);
            return cgi_error_memory();
         }
      }

#else /* Following code is disabled for now */

      /* and handle accordingly: */
      if ((p == NULL) || (0 == strcmpic(p, "pattern")))
      {
         p = CGI_PREFIX "send-banner?type=pattern";
      }
      else if (0 == strcmpic(p, "blank"))
      {
         p = CGI_PREFIX "send-banner?type=blank";
      }
      rsp->status = strdup("302 Local Redirect from Privoxy");
      if (rsp->status == NULL)
      {
         free_http_response(rsp);
         return cgi_error_memory();
      }

      if (enlist_unique_header(rsp->headers, "Location", p))
      {
         free_http_response(rsp);
         return cgi_error_memory();
      }
#endif /* Preceeding code is disabled for now */
   }
   else
#endif /* def FEATURE_IMAGE_BLOCKING */

   /*
    * Else, generate an HTML "blocked" message:
    */
   {
      jb_err err;
      struct map * exports;

      /*
       * Workaround for stupid Netscape bug which prevents
       * pages from being displayed if loading a referenced
       * JavaScript or style sheet fails. So make it appear
       * as if it succeeded.
       */
      if ( NULL != (p = get_header_value(csp->headers, "User-Agent:"))
           && !strncmpic(p, "mozilla", 7) /* Catch Netscape but */
           && !strstr(p, "Gecko")         /* save Mozilla, */
           && !strstr(p, "compatible")    /* MSIE */
           && !strstr(p, "Opera"))        /* and Opera. */
      {
         rsp->status = strdup("200 Request for blocked URL");
      }
      else
      {
         rsp->status = strdup("404 Request for blocked URL");
      }

      if (rsp->status == NULL)
      {
         free_http_response(rsp);
         return cgi_error_memory();
      }

      exports = default_exports(csp, NULL);
      if (exports == NULL)
      {
         free_http_response(rsp);
         return cgi_error_memory();
      }

#ifdef FEATURE_FORCE_LOAD
      err = map(exports, "force-prefix", 1, FORCE_PREFIX, 1);
      if (csp->http->ssl != 0)
#endif /* ndef FEATURE_FORCE_LOAD */
      {
         err = map_block_killer(exports, "force-support");
      }

      if (!err) err = map(exports, "protocol", 1, csp->http->ssl ? "https://" : "http://", 1);
      if (!err) err = map(exports, "hostport", 1, html_encode(csp->http->hostport), 0);
      if (!err) err = map(exports, "path", 1, html_encode(csp->http->path), 0);
      if (!err) err = map(exports, "path-ue", 1, url_encode(csp->http->path), 0);

      if (err)
      {
         free_map(exports);
         free_http_response(rsp);
         return cgi_error_memory();
      }

      err = template_fill_for_cgi(csp, "blocked", exports, rsp);
      if (err)
      {
         free_http_response(rsp);
         return cgi_error_memory();
      }
   }

   return finish_http_response(rsp);

}