-const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.71 2008/04/25 13:33:56 fabiankeil Exp $";
+const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.88 2008/08/30 12:03:07 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/cgisimple.c,v $
*
* Revisions :
* $Log: cgisimple.c,v $
+ * Revision 1.88 2008/08/30 12:03:07 fabiankeil
+ * Remove FEATURE_COOKIE_JAR.
+ *
+ * Revision 1.87 2008/08/29 15:59:22 fabiankeil
+ * Fix two comments.
+ *
+ * Revision 1.86 2008/06/28 14:19:05 fabiankeil
+ * Protocol detection is done case-insensitive, fix assertion
+ * to do the same. Yay for Privoxy-Regression-Test and zzuf.
+ *
+ * Revision 1.85 2008/05/26 17:30:55 fabiankeil
+ * Provide an OpenSearch Description to access the
+ * show-url-info page through "search engine plugins".
+ *
+ * Revision 1.84 2008/05/26 16:16:55 fabiankeil
+ * Spell error correctly.
+ *
+ * Revision 1.83 2008/05/12 14:51:30 fabiankeil
+ * Don't complain about an invalid URL if show-url-info is requested
+ * without parameters. Regression introduced in 1.81 by yours truly.
+ *
+ * Revision 1.82 2008/05/10 20:01:47 fabiankeil
+ * Fix an assertion that could erroneously
+ * trigger in case of memory shortage.
+ *
+ * Revision 1.81 2008/05/05 09:54:39 fabiankeil
+ * In cgi_show_url_info(), make sure ftp URLs are
+ * declared invalid. Also simplify the code that adds
+ * "http://" if no protocol has been specified.
+ *
+ * Revision 1.80 2008/05/04 16:18:32 fabiankeil
+ * Provide parse_http_url() with a third parameter to specify
+ * whether or not URLs without protocol are acceptable.
+ *
+ * Revision 1.79 2008/05/04 13:30:56 fabiankeil
+ * Streamline parse_http_url()'s prototype.
+ *
+ * Revision 1.78 2008/05/03 16:50:11 fabiankeil
+ * Leverage content_filters_enabled() in cgi_show_url_info().
+ *
+ * Revision 1.77 2008/05/02 09:47:48 fabiankeil
+ * In cgi_show_url_info, pass an initialized http structure
+ * to parse_http_url() as that will be required soonish and
+ * assert that https URLs are recognized correctly.
+ *
+ * Revision 1.76 2008/04/28 09:13:30 fabiankeil
+ * In load_file(), remember the error reason and fclose()
+ * and return later on instead of right away.
+ *
+ * Revision 1.75 2008/04/27 13:52:52 fabiankeil
+ * Move CGI file loading code into load_file() and
+ * add checks for unexpected errors.
+ *
+ * Revision 1.74 2008/04/26 15:50:56 fabiankeil
+ * Fix macro name in cgi_show_file() error path.
+ *
+ * Revision 1.73 2008/04/26 12:21:55 fabiankeil
+ * Forget about JB_ERR_PARSE. JB_ERR_CGI_PARAMS to the rescue.
+ *
+ * Revision 1.72 2008/04/26 10:34:15 fabiankeil
+ * If zlib support is unavailable and there are content filters active
+ * but the prevent-compression action is disabled, include a warning
+ * on the show-url-info page that compression might prevent filtering.
+ *
* Revision 1.71 2008/04/25 13:33:56 fabiankeil
* - Factor cgi_show_file() out of cgi_show_status().
* - Adjust cgi_show_status()'s parameter description to match reality.
static jb_err cgi_show_file(struct client_state *csp,
struct http_response *rsp,
const struct map *parameters);
+static jb_err load_file(const char *filename, char **buffer, size_t *length);
/*********************************************************************
*
return JB_ERR_OK;
}
+
+
+/*********************************************************************
+ *
+ * Function : cgi_send_url_info_osd
+ *
+ * Description : CGI function that sends the OpenSearch Description
+ * template for the show-url-info page. It allows to
+ * access the page through "search engine plugins".
+ *
+ * Parameters :
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ * 2 : rsp = http_response data structure for output
+ * 3 : parameters = map of cgi parameters
+ *
+ * CGI Parameters : None
+ *
+ * Returns : JB_ERR_OK on success
+ * JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err cgi_send_url_info_osd(struct client_state *csp,
+ struct http_response *rsp,
+ const struct map *parameters)
+{
+ jb_err err = JB_ERR_MEMORY;
+ struct map *exports = default_exports(csp, NULL);
+
+ if (NULL != exports)
+ {
+ err = template_fill_for_cgi(csp, "url-info-osd.xml", exports, rsp);
+ if (JB_ERR_OK == err)
+ {
+ err = enlist(rsp->headers,
+ "Content-Type: application/opensearchdescription+xml");
+ }
+ }
+
+ return err;
+
+}
+
+
/*********************************************************************
*
* Function : cgi_send_user_manual
{
const char * filename;
char *full_path;
- FILE *fp;
jb_err err = JB_ERR_OK;
size_t length;
return JB_ERR_MEMORY;
}
- /* Open user-manual file */
- if (NULL == (fp = fopen(full_path, "rb")))
+ err = load_file(full_path, &rsp->body, &rsp->content_length);
+ if (JB_ERR_OK != err)
{
- log_error(LOG_LEVEL_ERROR, "Cannot open user-manual file %s: %E", full_path);
- err = cgi_error_no_template(csp, rsp, full_path);
- free(full_path);
+ assert((JB_ERR_FILE == err) || (JB_ERR_MEMORY == err));
+ if (JB_ERR_FILE == err)
+ {
+ err = cgi_error_no_template(csp, rsp, full_path);
+ }
+ freez(full_path);
return err;
}
-
- /* Get file length */
- fseek(fp, 0, SEEK_END);
- length = (size_t)ftell(fp);
- fseek(fp, 0, SEEK_SET);
-
- /* Allocate memory and load the file directly into the body */
- rsp->body = (char *)zalloc(length+1);
- if (!rsp->body)
- {
- fclose(fp);
- free(full_path);
- return JB_ERR_MEMORY;
- }
- if (!fread(rsp->body, length, 1, fp))
- {
- /*
- * May happen if the file size changes between fseek() and fread().
- * If it does, we just log it and serve what we got.
- */
- log_error(LOG_LEVEL_ERROR, "Couldn't completely read user-manual file %s.", full_path);
- }
- fclose(fp);
- free(full_path);
-
- rsp->content_length = length;
+ freez(full_path);
/* Guess correct Content-Type based on the filename's ending */
if (filename)
url_param[0] = '\0';
}
}
- else if (url_param[0] != '\0')
+ else if ((url_param[0] != '\0') && (NULL == strstr(url_param, "://")))
{
- /*
- * Unknown prefix - assume http://
- */
- const size_t url_param_prefixed_size = 7 + 1 + strlen(url_param);
- char * url_param_prefixed = malloc(url_param_prefixed_size);
- if (NULL == url_param_prefixed)
+ /* No prefix - assume http:// */
+ char *url_param_prefixed = strdup("http://");
+
+ if (JB_ERR_OK != string_join(&url_param_prefixed, url_param))
{
- free(url_param);
free_map(exports);
return JB_ERR_MEMORY;
}
- strlcpy(url_param_prefixed, "http://", url_param_prefixed_size);
- strlcat(url_param_prefixed, url_param, url_param_prefixed_size);
- free(url_param);
url_param = url_param_prefixed;
}
return JB_ERR_MEMORY;
}
- err = parse_http_url(url_param, url_to_query, csp);
+ memset(url_to_query, '\0', sizeof(url_to_query));
+ err = parse_http_url(url_param, url_to_query, REQUIRE_PROTOCOL);
+ assert((err != JB_ERR_OK) || (url_to_query->ssl == !strncmpic(url_param, "https://", 8)));
free(url_param);
* If zlib support is available, if no content filters
* are enabled or if the prevent-compression action is enabled,
* suppress the "compression could prevent filtering" warning.
- *
- * XXX: Change content_filters_enabled()'s prototype so we can
- * use it here.
*/
#ifndef FEATURE_ZLIB
- if ((list_is_empty(action->multi[ACTION_MULTI_FILTER])
- && !(action->flags & ACTION_DEANIMATE))
- || (action->flags & ACTION_NO_COMPRESSION))
+ if (!content_filters_enabled(action) ||
+ (action->flags & ACTION_NO_COMPRESSION))
#endif
{
if (!err) err = map_block_killer(exports, "filters-might-be-ineffective");
#ifdef FEATURE_CGI_EDIT_ACTIONS
if (!err) err = map_conditional(exports, "FEATURE_CGI_EDIT_ACTIONS", 1);
-#else /* ifndef FEATURE_COOKIE_JAR */
+#else /* ifndef FEATURE_CGI_EDIT_ACTIONS */
if (!err) err = map_conditional(exports, "FEATURE_CGI_EDIT_ACTIONS", 0);
-#endif /* ndef FEATURE_COOKIE_JAR */
+#endif /* ndef FEATURE_CGI_EDIT_ACTIONS */
-#ifdef FEATURE_COOKIE_JAR
- if (!err) err = map_conditional(exports, "FEATURE_COOKIE_JAR", 1);
-#else /* ifndef FEATURE_COOKIE_JAR */
- if (!err) err = map_conditional(exports, "FEATURE_COOKIE_JAR", 0);
-#endif /* ndef FEATURE_COOKIE_JAR */
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ if (!err) err = map_conditional(exports, "FEATURE_CONNECTION_KEEP_ALIVE", 1);
+#else /* ifndef FEATURE_CGI_EDIT_ACTIONS */
+ if (!err) err = map_conditional(exports, "FEATURE_CONNECTION_KEEP_ALIVE", 0);
+#endif /* ndef FEATURE_CONNECTION_KEEP_ALIVE */
#ifdef FEATURE_FAST_REDIRECTS
if (!err) err = map_conditional(exports, "FEATURE_FAST_REDIRECTS", 1);
{
struct map *exports;
char *s;
- FILE * fp;
+ jb_err err;
+ size_t length;
exports = default_exports(csp, "show-status");
if (NULL == exports)
return JB_ERR_MEMORY;
}
- if ((fp = fopen(filename, "rb")) == NULL)
+ err = load_file(filename, &s, &length);
+ if (JB_ERR_OK != err)
{
- if (map(exports, "content", 1, "<h1>ERROR OPENING FILE!</h1>", 1))
+ if (map(exports, "contents", 1, "<h1>ERROR OPENING FILE!</h1>", 1))
{
free_map(exports);
return JB_ERR_MEMORY;
}
else
{
- /*
- * XXX: this code is "quite similar" to the one
- * in cgi_send_user_manual() and should be refactored.
- * While at it, the return codes for ftell() and fseek
- * should be verified.
- */
- size_t length;
- /* Get file length */
- fseek(fp, 0, SEEK_END);
- length = (size_t)ftell(fp);
- fseek(fp, 0, SEEK_SET);
-
- s = (char *)zalloc(length+1);
- if (NULL == s)
- {
- fclose(fp);
- return JB_ERR_MEMORY;
- }
- if (!fread(s, length, 1, fp))
- {
- /*
- * May happen if the file size changes between fseek() and fread().
- * If it does, we just log it and serve what we got.
- */
- log_error(LOG_LEVEL_ERROR, "Couldn't completely read file %s.", filename);
- }
- fclose(fp);
-
s = html_encode_and_free_original(s);
if (NULL == s)
{
return template_fill_for_cgi(csp, "show-status-file", exports, rsp);
}
- /*
- * XXX: should return JB_ERR_PARSE but CGI handlers
- * currently aren't expected to do that.
- */
- return JB_ERR_OK;
+ return JB_ERR_CGI_PARAMS;
}
+
+/*********************************************************************
+ *
+ * Function : load_file
+ *
+ * Description : Loads a file into a buffer.
+ *
+ * Parameters :
+ * 1 : filename = Name of the file to be loaded.
+ * 2 : buffer = Used to return the file's content.
+ * 3 : length = Used to return the size of the file.
+ *
+ * Returns : JB_ERR_OK in case of success,
+ * JB_ERR_FILE in case of ordinary file loading errors
+ * (fseek() and ftell() errors are fatal)
+ * JB_ERR_MEMORY in case of out-of-memory.
+ *
+ *********************************************************************/
+static jb_err load_file(const char *filename, char **buffer, size_t *length)
+{
+ FILE *fp;
+ int ret;
+ jb_err err = JB_ERR_OK;
+
+ fp = fopen(filename, "rb");
+ if (NULL == fp)
+ {
+ return JB_ERR_FILE;
+ }
+
+ /* Get file length */
+ if (fseek(fp, 0, SEEK_END))
+ {
+ log_error(LOG_LEVEL_FATAL,
+ "Unexpected error while fseek()ing to the end of %s: %E",
+ filename);
+ }
+ ret = ftell(fp);
+ if (-1 == ret)
+ {
+ log_error(LOG_LEVEL_FATAL,
+ "Unexpected ftell() error while loading %s: %E",
+ filename);
+ }
+ *length = (size_t)ret;
+
+ /* Go back to the beginning. */
+ if (fseek(fp, 0, SEEK_SET))
+ {
+ log_error(LOG_LEVEL_FATAL,
+ "Unexpected error while fseek()ing to the beginning of %s: %E",
+ filename);
+ }
+
+ *buffer = (char *)zalloc(*length + 1);
+ if (NULL == *buffer)
+ {
+ err = JB_ERR_MEMORY;
+ }
+ else if (!fread(*buffer, *length, 1, fp))
+ {
+ /*
+ * May happen if the file size changes between fseek() and
+ * fread(). If it does, we just log it and serve what we got.
+ */
+ log_error(LOG_LEVEL_ERROR,
+ "Couldn't completely read file %s.", filename);
+ err = JB_ERR_FILE;
+ }
+
+ fclose(fp);
+
+ return err;
+
+}
+
/*
Local Variables: