1
0
mirror of https://github.com/lammertb/libhttp.git synced 2026-01-27 08:02:47 +03:00

Moved prepare_cgi_environment to own file

This commit is contained in:
Lammert Bies
2016-12-10 22:59:06 +01:00
parent e9109ba7fc
commit 1345f8bebb
4 changed files with 162 additions and 122 deletions

View File

@@ -78,6 +78,7 @@ LIB_SOURCES = src/libhttp.c \
src/httplib_master_thread.c \
src/httplib_mkcol.c \
src/httplib_parse_net.c \
src/httplib_prepare_cgi_environment.c \
src/httplib_process_new_connection.c \
src/httplib_produce_socket.c \
src/httplib_put_file.c \

View File

@@ -0,0 +1,159 @@
/*
* Copyright (c) 2016 Lammert Bies
* Copyright (c) 2013-2016 the Civetweb developers
* Copyright (c) 2004-2013 Sergey Lyubka
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "libhttp-private.h"
/*
* void XX_httplib_prepare_cgi_environment( struct mg_connection *conn, const char *prog, struct cgi_environment *env );
*
* The function XX_httplib_prepare_cgi_environment() is used to prepare all
* environment variables before a CGI script is called.
*/
#if !defined(NO_CGI)
void XX_httplib_prepare_cgi_environment( struct mg_connection *conn, const char *prog, struct cgi_environment *env ) {
const char *s;
struct vec var_vec;
char *p;
char src_addr[IP_ADDR_STR_LEN];
char http_var_name[128];
int i;
int truncated;
if ( conn == NULL || prog == NULL || env == NULL ) return;
env->conn = conn;
env->buflen = CGI_ENVIRONMENT_SIZE;
env->bufused = 0;
env->buf = (char *)XX_httplib_malloc(env->buflen);
env->varlen = MAX_CGI_ENVIR_VARS;
env->varused = 0;
env->var = (char **)XX_httplib_malloc(env->buflen * sizeof(char *));
XX_httplib_addenv( env, "SERVER_NAME=%s", conn->ctx->config[AUTHENTICATION_DOMAIN] );
XX_httplib_addenv( env, "SERVER_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT] );
XX_httplib_addenv( env, "DOCUMENT_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT] );
XX_httplib_addenv( env, "SERVER_SOFTWARE=%s/%s", "LibHTTP", mg_version() );
/* Prepare the environment block */
XX_httplib_addenv( env, "%s", "GATEWAY_INTERFACE=CGI/1.1" );
XX_httplib_addenv( env, "%s", "SERVER_PROTOCOL=HTTP/1.1" );
XX_httplib_addenv( env, "%s", "REDIRECT_STATUS=200" ); /* For PHP */
#if defined(USE_IPV6)
if (conn->client.lsa.sa.sa_family == AF_INET6) {
XX_httplib_addenv(env, "SERVER_PORT=%d", ntohs(conn->client.lsa.sin6.sin6_port));
} else
#endif
{
XX_httplib_addenv(env, "SERVER_PORT=%d", ntohs(conn->client.lsa.sin.sin_port));
}
XX_httplib_sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
XX_httplib_addenv( env, "REMOTE_ADDR=%s", src_addr );
XX_httplib_addenv( env, "REQUEST_METHOD=%s", conn->request_info.request_method );
XX_httplib_addenv( env, "REMOTE_PORT=%d", conn->request_info.remote_port );
XX_httplib_addenv( env, "REQUEST_URI=%s", conn->request_info.request_uri );
XX_httplib_addenv( env, "LOCAL_URI=%s", conn->request_info.local_uri );
/* SCRIPT_NAME */
XX_httplib_addenv(env,
"SCRIPT_NAME=%.*s",
(int)strlen(conn->request_info.local_uri)
- ((conn->path_info == NULL) ? 0 : (int)strlen(conn->path_info)),
conn->request_info.local_uri);
XX_httplib_addenv(env, "SCRIPT_FILENAME=%s", prog);
if ( conn->path_info == NULL ) XX_httplib_addenv( env, "PATH_TRANSLATED=%s", conn->ctx->config[DOCUMENT_ROOT] );
else XX_httplib_addenv( env, "PATH_TRANSLATED=%s%s", conn->ctx->config[DOCUMENT_ROOT], conn->path_info );
XX_httplib_addenv(env, "HTTPS=%s", (conn->ssl == NULL) ? "off" : "on");
if ( (s = mg_get_header( conn, "Content-Type" ) ) != NULL ) XX_httplib_addenv( env, "CONTENT_TYPE=%s", s );
if ( conn->request_info.query_string != NULL ) XX_httplib_addenv( env, "QUERY_STRING=%s", conn->request_info.query_string );
if ( (s = mg_get_header( conn, "Content-Length" ) ) != NULL ) XX_httplib_addenv( env, "CONTENT_LENGTH=%s", s );
if ( (s = getenv( "PATH" )) != NULL ) XX_httplib_addenv( env, "PATH=%s", s );
if ( conn->path_info != NULL ) XX_httplib_addenv( env, "PATH_INFO=%s", conn->path_info );
if (conn->status_code > 0) {
/* CGI error handler should show the status code */
XX_httplib_addenv(env, "STATUS=%d", conn->status_code);
}
#if defined(_WIN32)
if ( (s = getenv( "COMSPEC" )) != NULL ) XX_httplib_addenv( env, "COMSPEC=%s", s );
if ( (s = getenv( "SYSTEMROOT" )) != NULL ) XX_httplib_addenv( env, "SYSTEMROOT=%s", s );
if ( (s = getenv( "SystemDrive" )) != NULL ) XX_httplib_addenv( env, "SystemDrive=%s", s );
if ( (s = getenv( "ProgramFiles" )) != NULL ) XX_httplib_addenv( env, "ProgramFiles=%s", s );
if ( (s = getenv( "ProgramFiles(x86)" )) != NULL ) XX_httplib_addenv( env, "ProgramFiles(x86)=%s", s );
#else
if ( (s = getenv("LD_LIBRARY_PATH" )) != NULL ) XX_httplib_addenv( env, "LD_LIBRARY_PATH=%s", s );
#endif /* _WIN32 */
if ( (s = getenv("PERLLIB" )) != NULL ) XX_httplib_addenv( env, "PERLLIB=%s", s );
if (conn->request_info.remote_user != NULL) {
XX_httplib_addenv(env, "REMOTE_USER=%s", conn->request_info.remote_user);
XX_httplib_addenv(env, "%s", "AUTH_TYPE=Digest");
}
/* Add all headers as HTTP_* variables */
for (i = 0; i < conn->request_info.num_headers; i++) {
XX_httplib_snprintf(conn, &truncated, http_var_name, sizeof(http_var_name), "HTTP_%s", conn->request_info.http_headers[i].name);
if (truncated) {
mg_cry(conn, "%s: HTTP header variable too long [%s]", __func__, conn->request_info.http_headers[i].name);
continue;
}
/* Convert variable name into uppercase, and change - to _ */
for (p = http_var_name; *p != '\0'; p++) {
if (*p == '-') *p = '_';
*p = (char)toupper(*(unsigned char *)p);
}
XX_httplib_addenv(env, "%s=%s", http_var_name, conn->request_info.http_headers[i].value);
}
/* Add user-specified variables */
s = conn->ctx->config[CGI_ENVIRONMENT];
while ((s = XX_httplib_next_option(s, &var_vec, NULL)) != NULL) {
XX_httplib_addenv(env, "%.*s", (int)var_vec.len, var_vec.ptr);
}
env->var[env->varused] = NULL;
env->buf[env->bufused] = '\0';
} /* XX_httplib_prepare_cgi_environment */
#endif /* !NO_CGI */

View File

@@ -878,6 +878,7 @@ void SHA1Init( SHA1_CTX *context );
void SHA1Update( SHA1_CTX *context, const unsigned char *data, uint32_t len );
void XX_httplib_accept_new_connection( const struct socket *listener, struct mg_context *ctx );
void XX_httplib_addenv( struct cgi_environment *env, PRINTF_FORMAT_STRING(const char *fmt), ... ) PRINTF_ARGS(2, 3);
int XX_httplib_atomic_dec( volatile int *addr );
int XX_httplib_atomic_inc( volatile int *addr );
void XX_httplib_base64_encode( const unsigned char *src, int src_len, char *dst );

View File

@@ -5528,11 +5528,10 @@ int XX_httplib_forward_body_data( struct mg_connection *conn, FILE *fp, SOCKET s
#if !defined(NO_CGI)
static void addenv(struct cgi_environment *env, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
/* Append VARIABLE=VALUE\0 string to the buffer, and add a respective
* pointer into the vars array. Assumes env != NULL and fmt != NULL. */
static void addenv(struct cgi_environment *env, const char *fmt, ...) {
void XX_httplib_addenv( struct cgi_environment *env, const char *fmt, ... ) {
size_t n;
size_t space;
@@ -5593,124 +5592,4 @@ static void addenv(struct cgi_environment *env, const char *fmt, ...) {
env->varused++;
}
void XX_httplib_prepare_cgi_environment( struct mg_connection *conn, const char *prog, struct cgi_environment *env ) {
const char *s;
struct vec var_vec;
char *p;
char src_addr[IP_ADDR_STR_LEN];
char http_var_name[128];
int i;
int truncated;
if ( conn == NULL || prog == NULL || env == NULL ) return;
env->conn = conn;
env->buflen = CGI_ENVIRONMENT_SIZE;
env->bufused = 0;
env->buf = (char *)XX_httplib_malloc(env->buflen);
env->varlen = MAX_CGI_ENVIR_VARS;
env->varused = 0;
env->var = (char **)XX_httplib_malloc(env->buflen * sizeof(char *));
addenv( env, "SERVER_NAME=%s", conn->ctx->config[AUTHENTICATION_DOMAIN] );
addenv( env, "SERVER_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT] );
addenv( env, "DOCUMENT_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT] );
addenv( env, "SERVER_SOFTWARE=%s/%s", "LibHTTP", mg_version() );
/* Prepare the environment block */
addenv( env, "%s", "GATEWAY_INTERFACE=CGI/1.1" );
addenv( env, "%s", "SERVER_PROTOCOL=HTTP/1.1" );
addenv( env, "%s", "REDIRECT_STATUS=200" ); /* For PHP */
#if defined(USE_IPV6)
if (conn->client.lsa.sa.sa_family == AF_INET6) {
addenv(env, "SERVER_PORT=%d", ntohs(conn->client.lsa.sin6.sin6_port));
} else
#endif
{
addenv(env, "SERVER_PORT=%d", ntohs(conn->client.lsa.sin.sin_port));
}
XX_httplib_sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
addenv( env, "REMOTE_ADDR=%s", src_addr );
addenv( env, "REQUEST_METHOD=%s", conn->request_info.request_method );
addenv( env, "REMOTE_PORT=%d", conn->request_info.remote_port );
addenv( env, "REQUEST_URI=%s", conn->request_info.request_uri );
addenv( env, "LOCAL_URI=%s", conn->request_info.local_uri );
/* SCRIPT_NAME */
addenv(env,
"SCRIPT_NAME=%.*s",
(int)strlen(conn->request_info.local_uri)
- ((conn->path_info == NULL) ? 0 : (int)strlen(conn->path_info)),
conn->request_info.local_uri);
addenv(env, "SCRIPT_FILENAME=%s", prog);
if ( conn->path_info == NULL ) addenv( env, "PATH_TRANSLATED=%s", conn->ctx->config[DOCUMENT_ROOT] );
else addenv( env, "PATH_TRANSLATED=%s%s", conn->ctx->config[DOCUMENT_ROOT], conn->path_info );
addenv(env, "HTTPS=%s", (conn->ssl == NULL) ? "off" : "on");
if ( (s = mg_get_header( conn, "Content-Type" ) ) != NULL ) addenv( env, "CONTENT_TYPE=%s", s );
if ( conn->request_info.query_string != NULL ) addenv( env, "QUERY_STRING=%s", conn->request_info.query_string );
if ( (s = mg_get_header( conn, "Content-Length" ) ) != NULL ) addenv( env, "CONTENT_LENGTH=%s", s );
if ( (s = getenv( "PATH" )) != NULL ) addenv( env, "PATH=%s", s );
if ( conn->path_info != NULL ) addenv( env, "PATH_INFO=%s", conn->path_info );
if (conn->status_code > 0) {
/* CGI error handler should show the status code */
addenv(env, "STATUS=%d", conn->status_code);
}
#if defined(_WIN32)
if ( (s = getenv( "COMSPEC" )) != NULL ) addenv( env, "COMSPEC=%s", s );
if ( (s = getenv( "SYSTEMROOT" )) != NULL ) addenv( env, "SYSTEMROOT=%s", s );
if ( (s = getenv( "SystemDrive" )) != NULL ) addenv( env, "SystemDrive=%s", s );
if ( (s = getenv( "ProgramFiles" )) != NULL ) addenv( env, "ProgramFiles=%s", s );
if ( (s = getenv( "ProgramFiles(x86)" )) != NULL ) addenv( env, "ProgramFiles(x86)=%s", s );
#else
if ( (s = getenv("LD_LIBRARY_PATH" )) != NULL ) addenv( env, "LD_LIBRARY_PATH=%s", s );
#endif /* _WIN32 */
if ( (s = getenv("PERLLIB" )) != NULL ) addenv( env, "PERLLIB=%s", s );
if (conn->request_info.remote_user != NULL) {
addenv(env, "REMOTE_USER=%s", conn->request_info.remote_user);
addenv(env, "%s", "AUTH_TYPE=Digest");
}
/* Add all headers as HTTP_* variables */
for (i = 0; i < conn->request_info.num_headers; i++) {
XX_httplib_snprintf(conn, &truncated, http_var_name, sizeof(http_var_name), "HTTP_%s", conn->request_info.http_headers[i].name);
if (truncated) {
mg_cry(conn, "%s: HTTP header variable too long [%s]", __func__, conn->request_info.http_headers[i].name);
continue;
}
/* Convert variable name into uppercase, and change - to _ */
for (p = http_var_name; *p != '\0'; p++) {
if (*p == '-') *p = '_';
*p = (char)toupper(*(unsigned char *)p);
}
addenv(env, "%s=%s", http_var_name, conn->request_info.http_headers[i].value);
}
/* Add user-specified variables */
s = conn->ctx->config[CGI_ENVIRONMENT];
while ((s = XX_httplib_next_option(s, &var_vec, NULL)) != NULL) {
addenv(env, "%.*s", (int)var_vec.len, var_vec.ptr);
}
env->var[env->varused] = NULL;
env->buf[env->bufused] = '\0';
} /* XX_httplib_prepare_cgi_environment */
#endif /* !NO_CGI */