guint id;
};
+struct rspamd_lua_upstream {
+ struct upstream *up;
+ gint upref;
+};
+
/* Common utility functions */
/**
*/
bool lua_is_text_binary(struct rspamd_lua_text *t);
-struct rspamd_lua_regexp *lua_check_regexp (lua_State *L, gint pos);
+struct rspamd_lua_regexp* lua_check_regexp (lua_State *L, gint pos);
+
+struct rspamd_lua_upstream* lua_check_upstream(lua_State *L, int pos);
enum rspamd_lua_task_header_type {
RSPAMD_TASK_HEADER_PUSH_SIMPLE = 0,
#include "lua_common.h"
#include "lua_thread_pool.h"
#include "libserver/http/http_private.h"
+#include "libutil/upstream.h"
#include "ref.h"
#include "unix-std.h"
#include "zlib.h"
gchar *mime_type;
gchar *host;
gchar *auth;
+ struct upstream *up;
const gchar *url;
gsize max_size;
gint flags;
lua_http_error_handler (struct rspamd_http_connection *conn, GError *err)
{
struct lua_http_cbdata *cbd = (struct lua_http_cbdata *)conn->ud;
+
+ if (cbd->up) {
+ rspamd_upstream_fail(cbd->up, false, err ? err->message : "unknown error");
+ }
+
if (cbd->cbref == -1) {
if (cbd->flags & RSPAMD_LUA_HTTP_FLAG_YIELDED) {
cbd->flags &= ~RSPAMD_LUA_HTTP_FLAG_YIELDED;
struct rspamd_config *cfg = NULL;
struct rspamd_cryptobox_pubkey *peer_key = NULL;
struct rspamd_cryptobox_keypair *local_kp = NULL;
+ struct upstream *up = NULL;
const gchar *url, *lua_body;
rspamd_fstring_t *body = NULL;
gint cbref = -1;
lua_pop (L, 1);
+ lua_pushstring (L, "upstream");
+ lua_gettable (L, 1);
+
+ if (lua_type (L, -1) == LUA_TUSERDATA) {
+ struct rspamd_lua_upstream *lup = lua_check_upstream(L, -1);
+
+ if (lup) {
+ /* Preserve pointer in case if lup is destructed */
+ up = lup->up;
+ }
+ }
+
+ lua_pop (L, 1);
+
lua_pushstring (L, "user");
lua_gettable (L, 1);
cbd->url = url;
cbd->auth = auth;
cbd->task = task;
+ cbd->up = up;
if (cbd->cbref == -1) {
cbd->thread = lua_thread_pool_get_running_entry (cfg->lua_thread_pool);
bool numeric_ip = false;
/* Check if we can skip resolving */
+
gsize hostlen = 0;
const gchar *host = rspamd_http_message_get_http_host (msg, &hostlen);
cbd->host = g_malloc (hostlen + 1);
rspamd_strlcpy (cbd->host, host, hostlen + 1);
+ /* Keep-alive entry is available */
if (cbd->flags & RSPAMD_LUA_HTTP_FLAG_KEEP_ALIVE) {
const rspamd_inet_addr_t *ka_addr = rspamd_http_context_has_keepalive(NULL,
cbd->host,
}
}
+ /*
+ * No keep-alive stuff, check if we have upstream or if we can parse host as
+ * a numeric address
+ */
if (!cbd->addr) {
- /* We use msg->host here, not cbd->host ! */
- if (rspamd_parse_inet_address (&cbd->addr,
- msg->host->str, msg->host->len,
- RSPAMD_INET_ADDRESS_PARSE_DEFAULT)) {
+ if (cbd->up) {
numeric_ip = true;
+ cbd->addr = rspamd_inet_address_copy(rspamd_upstream_addr_next(cbd->up), NULL);
+ }
+ else {
+ /* We use msg->host here, not cbd->host ! */
+ if (rspamd_parse_inet_address(&cbd->addr,
+ msg->host->str, msg->host->len,
+ RSPAMD_INET_ADDRESS_PARSE_DEFAULT)) {
+ numeric_ip = true;
+ }
}
}
}
else {
+ if (cbd->up) {
+ numeric_ip = true;
+ cbd->addr = rspamd_inet_address_copy(rspamd_upstream_addr_next(cbd->up), NULL);
+ }
cbd->host = NULL;
}
ret = lua_http_make_connection (cbd);
if (!ret) {
+ if (cbd->up) {
+ rspamd_upstream_fail(cbd->up, true, "HTTP connection failed");
+ }
if (cbd->ref.refcount > 1) {
/* Not released by make_connection */
REF_RELEASE (cbd);
/* Upstream class */
-struct rspamd_lua_upstream {
- struct upstream *up;
- gint upref;
-};
-
-static struct rspamd_lua_upstream *
-lua_check_upstream (lua_State * L)
+struct rspamd_lua_upstream *
+lua_check_upstream(lua_State *L, int pos)
{
- void *ud = rspamd_lua_check_udata (L, 1, "rspamd{upstream}");
+ void *ud = rspamd_lua_check_udata (L, pos, "rspamd{upstream}");
luaL_argcheck (L, ud != NULL, 1, "'upstream' expected");
return ud ? (struct rspamd_lua_upstream *)ud : NULL;
lua_upstream_get_addr (lua_State *L)
{
LUA_TRACE_POINT;
- struct rspamd_lua_upstream *up = lua_check_upstream (L);
+ struct rspamd_lua_upstream *up = lua_check_upstream(L, 1);
if (up) {
rspamd_lua_ip_push (L, rspamd_upstream_addr_next (up->up));
lua_upstream_get_name (lua_State *L)
{
LUA_TRACE_POINT;
- struct rspamd_lua_upstream *up = lua_check_upstream (L);
+ struct rspamd_lua_upstream *up = lua_check_upstream(L, 1);
if (up) {
lua_pushstring (L, rspamd_upstream_name (up->up));
lua_upstream_get_port (lua_State *L)
{
LUA_TRACE_POINT;
- struct rspamd_lua_upstream *up = lua_check_upstream (L);
+ struct rspamd_lua_upstream *up = lua_check_upstream(L, 1);
if (up) {
lua_pushinteger (L, rspamd_upstream_port (up->up));
lua_upstream_fail (lua_State *L)
{
LUA_TRACE_POINT;
- struct rspamd_lua_upstream *up = lua_check_upstream (L);
+ struct rspamd_lua_upstream *up = lua_check_upstream(L, 1);
gboolean fail_addr = FALSE;
const gchar *reason = "unknown";
lua_upstream_ok (lua_State *L)
{
LUA_TRACE_POINT;
- struct rspamd_lua_upstream *up = lua_check_upstream (L);
+ struct rspamd_lua_upstream *up = lua_check_upstream(L, 1);
if (up) {
rspamd_upstream_ok (up->up);
lua_upstream_destroy (lua_State *L)
{
LUA_TRACE_POINT;
- struct rspamd_lua_upstream *up = lua_check_upstream (L);
+ struct rspamd_lua_upstream *up = lua_check_upstream(L, 1);
if (up) {
/* Remove reference to the parent */