~panda-roux/MoonGem

3129520781bb9ac32e8e32c42f5b10e9034de9bd — panda-roux 2 months ago 63200e5
adding methods for getting the raw (pre-standardized) request path and for overriding input parameters in --before scripts
5 files changed, 52 insertions(+), 7 deletions(-)

M README.md
M include/uri.h
M src/api.c
M src/script.c
M src/uri.c
M README.md => README.md +7 -2
@@ 87,9 87,11 @@ All of the MoonGem-defined functionality is contained within a table called `mg`

These methods are only accessible from pre-request scripts.

- `mg.set_path(<new-path>)
    - Sets the value of the incoming request path, overriding the initial value
- `mg.set_path([new-path])`
    - Overrides the incoming request path with a new value, or `/` if one is not provided
    - This can be useful for implementing virtual directories and other URL-reinterpretation features
- `mg.set_input([new-input])`
    - Overrides the incoming request's input string, or removes it if no new value is provided
- `mg.interrupt()`
    - Instructs MoonGem to bypass the rest of the requet-handling pipeline and use the current response state
    - Unless otherwise set, the default response status code will be 20 (OK)


@@ 158,6 160,9 @@ These methods are concerned with handling user-input.

- `mg.get_path()`
    - Returns the path portion of the requested URL
    - This path is standardized to include a default document (index.gmi) if one is not present (see get_raw_path)
- `mg.get_raw_path()`
    - Returns the path as requested by the client, prior to standardization
- `mg.get_input([meta])`
    - If an input argument was included in the request URL, this method returns that value
    - If no input was provided in the request, then the server responds with a code-10 status response and optional `meta` string

M include/uri.h => include/uri.h +1 -0
@@ 11,6 11,7 @@ typedef struct uri_t {
  char* scheme;
  char* host;
  char* port;
  char* raw_path;
  char* path;
  char* input;
  uri_type_t type;

M src/api.c => src/api.c +35 -4
@@ 35,11 35,12 @@ int api_set_path(lua_State* L) {
  lua_getfield(L, LUA_REGISTRYINDEX, FLD_REQUEST);
  request_t* request = (request_t*)lua_touserdata(L, -1);

  if (!lua_isnoneornil(L, 1)) {
    if (request->uri->path != NULL) {
      free(request->uri->path);
    }
  if (request->uri->path != NULL) {
    free(request->uri->path);
    request->uri->path = NULL;
  }

  if (!lua_isnoneornil(L, 1)) {
    request->uri->path = strndup(lua_tostring(L, 1), URI_PATH_MAX);
  } else {
    request->uri->path = strdup(PATH_DEFAULT);


@@ 55,6 56,23 @@ int api_interrupt(lua_State* L) {
  return 0;
}

int api_set_input(lua_State* L) {
  lua_settop(L, 1);

  lua_getfield(L, LUA_REGISTRYINDEX, FLD_REQUEST);
  request_t* request = (request_t*)lua_touserdata(L, -1);

  if (!lua_isnoneornil(L, 1)) {
    lua_pushstring(L, luaL_checkstring(L, 1));
  } else {
    lua_pushnil(L);
  }

  lua_setfield(L, LUA_REGISTRYINDEX, FLD_INPUT);

  return 0;
}

int api_set_lang(lua_State* L) {
  lua_settop(L, 1);



@@ 139,6 157,19 @@ int api_get_path(lua_State* L) {
  return 1;
}

int api_get_raw_path(lua_State* L) {
  lua_getfield(L, LUA_REGISTRYINDEX, FLD_REQUEST);
  request_t* request = (request_t*)lua_touserdata(L, -1);

  if (request->uri->raw_path != NULL) {
    lua_pushstring(L, request->uri->raw_path);
  } else {
    lua_pushnil(L);
  }

  return 1;
}

int api_success(lua_State* L) {
  lua_getfield(L, LUA_REGISTRYINDEX, FLD_RESPONSE);
  response_t* response = (response_t*)lua_touserdata(L, -1);

M src/script.c => src/script.c +6 -0
@@ 16,11 16,13 @@

#define FUNC_SET_PATH "set_path"
#define FUNC_INTERRUPT "interrupt"
#define FUNC_SET_INPUT "set_input"

#define FUNC_INPUT "get_input"
#define FUNC_INPUT_SENSITIVE "get_sensitive_input"
#define FUNC_HAS_INPUT "has_input"
#define FUNC_GET_PATH "get_path"
#define FUNC_GET_RAW_PATH "get_raw_path"

#define FUNC_CERT "get_cert"
#define FUNC_HAS_CERT "has_cert"


@@ 66,12 68,14 @@ typedef struct script_ctx_t {
/* Pre-Request */
int api_set_path(lua_State* L);
int api_interrupt(lua_State* L);
int api_set_input(lua_State* L);

/* Input */
int api_get_input(lua_State* L);
int api_get_input_sensitive(lua_State* L);
int api_has_input(lua_State* L);
int api_get_path(lua_State* L);
int api_get_raw_path(lua_State* L);

/* Certificates */
int api_get_cert(lua_State* L);


@@ 110,11 114,13 @@ int api_endblock(lua_State* L);
static void set_api_methods(lua_State* L) {
  luaL_Reg methods[] = {{FUNC_SET_PATH, api_set_path},
                        {FUNC_INTERRUPT, api_interrupt},
                        {FUNC_SET_INPUT, api_set_input},

                        {FUNC_INPUT, api_get_input},
                        {FUNC_INPUT_SENSITIVE, api_get_input_sensitive},
                        {FUNC_HAS_INPUT, api_has_input},
                        {FUNC_GET_PATH, api_get_path},
                        {FUNC_GET_RAW_PATH, api_get_raw_path},

                        {FUNC_CERT, api_get_cert},
                        {FUNC_HAS_CERT, api_has_cert},

M src/uri.c => src/uri.c +3 -1
@@ 121,9 121,10 @@ uri_t* create_uri(const char* buf) {
  uri->scheme = extract_part(&matches[URI_SCHEME], buf);
  uri->host = extract_part(&matches[URI_HOST], buf);
  uri->port = extract_part(&matches[URI_PORT], buf);
  uri->path = extract_part(&matches[URI_PATH], buf);
  uri->raw_path = extract_part(&matches[URI_PATH], buf);
  uri->input = extract_part(&matches[URI_INPUT], buf);

  uri->path = strdup(uri->raw_path);
  standardize_path(&uri->path);

  // path can be null if EOM occurred trying to add default doc


@@ 153,6 154,7 @@ void destroy_uri(uri_t* uri) {
  CHECK_FREE(uri->port);
  CHECK_FREE(uri->path);
  CHECK_FREE(uri->input);
  CHECK_FREE(uri->raw_path);

  free(uri);
}