I have built Lua-HTTP server, and it is running perfectly fine. but when I try to get client Ip then all of my tricks failed. Even I have seen many solutions for implementing reverse proxy and all which I don't want.
Following is my server snipped.
--
-- IMPORTS
--
local HttpServer = require "http.server"
local HttpHeaders = require "http.headers"
local CJson = require "cjson"
--
-- PACKAGES
--
local Context = require "packages.context"
local RateLimiter = require "packages.dyna_modules.RateLimiter"
local Router = require "packages.routes"
--
-- GLOBALS
--
local HOST = '0.0.0.0'
local PORT = 8080
--
-- FUNCTIONS
--
local function ResponseError(ServerInformation, context, op, err)
-- Local assignment.
local msg = op .. " on " .. tostring(context) .. " failed"
-- Style guide.
Context.Debug:info(string.format("Error caught total number of active connections: %s", ServerInformation
.n_connections))
-- Check if error is available or not.
if err then
-- Update error message.
msg = msg .. ": " .. tostring(err)
end
-- Style guide.
Context.Debug:info(string.format("Error: %s", msg))
-- Return message.
assert(io.stderr:write(msg, "\n"))
end
local function ResponseBuilder(ServerInformation, stream)
-- Variable assignment.
local requestHeaders = assert(stream:get_headers())
local requestMethod = requestHeaders:get ":method"
local requestPath = requestHeaders:get(":path")
print('-x-x-x-x-x-x-x', stream:get_peer())
-- Run the netstat command to get information on active TCP connections
local handle = io.popen("netstat -tn 2>/dev/null | grep ':8080'") -- Filter by port 8080
local output = handle:read("*a")
handle:close()
print('vwbwbwbwb', output)
-- Parse the output to get the client IP address
local clientIp = output:match("tcp%s+([%d%.]+):8080")
print(clientIp)
for index, value in pairs(stream) do
print(index, value)
end
-- Check rate limit for the client IP
local isAllowed = RateLimiter.get(Context, clientIp)
-- Style guide.
Context.Debug:info(string.format("Request recivied total number of active connections are %s",
ServerInformation.n_connections))
-- Check if rate limit exceeded.
if not isAllowed then
-- If rate-limited, return 429 for too many requests.
local ResponseHeaders = HttpHeaders.new()
-- Update response headers.
ResponseHeaders:append(":status", "429")
ResponseHeaders:append("content-type", "text/plain")
-- Send response.
assert(stream:write_headers(ResponseHeaders, false))
assert(stream:write_chunk("Rate limit exceeded. Please try again later.", true))
return
end
-- Style guide.
Context.Debug:info(string.format("Request recivied total number of active connections are %s",
ServerInformation.n_connections))
Context.Debug:info(string.format("Request recivied with method: %s and path : %s", requestMethod, requestPath))
-- Build response headers
local ResponseHeaders = HttpHeaders.new()
-- Object assignment.
local NotFoundHandler = function(__requestMethod)
-- Style guide.
Context.Debug:info(string.format("Route Not found: %s %s", __requestMethod, requestPath))
-- Return response.
return "404 Not Found"
end
local Handler = Router[requestPath] or NotFoundHandler
-- Send response
ResponseHeaders:append(":status", "200")
ResponseHeaders:append("content-type", "text/plain")
-- Lookup the appropriate handler from the routes table
local responseBody = Handler(Context, requestMethod)
-- Send headers to client; end the stream immediately if this was a HEAD request
assert(stream:write_headers(ResponseHeaders, requestMethod == "HEAD"))
-- If the method is not HEAD, send the response body
if requestMethod ~= "HEAD" then
-- Style guide.
Context.Debug:info(string.format("Sending Response: %s", responseBody))
-- Encode the response body as JSON
local encodedResponseBody = CJson.encode(responseBody)
-- Assert the response body.
assert(stream:write_chunk(encodedResponseBody, true))
end
end
--
-- SERVER
--
local Server = assert(HttpServer.listen {
host = HOST,
port = PORT,
onstream = ResponseBuilder,
onerror = ResponseError
})
-- Manually call :listen() so that we are bound before calling :localname()
assert(Server:listen())
do
-- Bound server to given port.
local boundPort = select(3, Server:localname())
-- Style guide.
Context.Debug:info(string.format("Server is listening on %s:%d", HOST, boundPort))
end
-- Start the main server loop
assert(Server:loop())
Please help..i have only this small server and i want to implement Ratelimiter but without clip ip how will i going to do it.
I have built Lua-HTTP server, and it is running perfectly fine. but when I try to get client Ip then all of my tricks failed. Even I have seen many solutions for implementing reverse proxy and all which I don't want.
Following is my server snipped.
Please help..i have only this small server and i want to implement Ratelimiter but without clip ip how will i going to do it.
Regards