when NimMajor >= 2:
import std/envvars
else:
import std/os
import curl
import curlerrors
import curlwrap
import ../gophertypes
import loader/connecterror
import utils/twtstr
type GopherHandle = ref object
curl: CURL
t: GopherType
statusline: bool
proc onStatusLine(op: GopherHandle) =
var status: clong
op.curl.getinfo(CURLINFO_RESPONSE_CODE, addr status)
stdout.write("Status: " & $status & "\n")
let s = case op.t
of DIRECTORY, SEARCH: "Content-Type: text/gopher\n"
of HTML: "Content-Type: text/html\n"
of GIF: "Content-Type: image/gif\n"
of PNG: "Content-Type: image/png\n"
of TEXT_FILE, ERROR: "Content-Type: text/plain\n"
else: ""
stdout.write(s & "\n")
proc loadSearch(op: GopherHandle, surl: string) =
stdout.write("""
Content-Type: text/html
Search """ & htmlEscape(surl) & """
""")
# From the documentation: size is always 1.
proc curlWriteBody(p: cstring, size, nmemb: csize_t, userdata: pointer):
csize_t {.cdecl.} =
let op = cast[GopherHandle](userdata)
if not op.statusline:
op.statusline = true
op.onStatusLine()
return csize_t(stdout.writeBuffer(p, int(nmemb)))
proc main() =
let curl = curl_easy_init()
doAssert curl != nil
if getEnv("REQUEST_METHOD") != "GET":
stdout.write("Cha-Control: ConnectionError " & $int(ERROR_INVALID_METHOD))
return
var path = getEnv("MAPPED_URI_PATH")
if path.len < 1:
path &= '/'
if path.len < 2:
path &= '1'
let url = curl_url()
const flags = cuint(CURLU_PATH_AS_IS)
url.set(CURLUPART_SCHEME, getEnv("MAPPED_URI_SCHEME"), flags)
url.set(CURLUPART_HOST, getEnv("MAPPED_URI_HOST"), flags)
let port = getEnv("MAPPED_URI_PORT")
if port != "":
url.set(CURLUPART_PORT, port, flags)
url.set(CURLUPART_PATH, path, flags)
let query = getEnv("MAPPED_URI_QUERY")
if query != "":
url.set(CURLUPART_QUERY, query.after('='), flags)
let op = GopherHandle(
curl: curl,
t: gopherType(path[1])
)
if op.t == SEARCH and query == "":
const flags = cuint(CURLU_PUNY2IDN)
let surl = url.get(CURLUPART_URL, flags)
if surl == nil:
stdout.write("Cha-Control: ConnectionError " & $int(ERROR_INVALID_URL))
else:
op.loadSearch($surl)
else:
curl.setopt(CURLOPT_CURLU, url)
curl.setopt(CURLOPT_WRITEDATA, op)
curl.setopt(CURLOPT_WRITEFUNCTION, curlWriteBody)
let proxy = getEnv("ALL_PROXY")
if proxy != "":
curl.setopt(CURLOPT_PROXY, proxy)
let res = curl_easy_perform(curl)
if res != CURLE_OK and not op.statusline:
stdout.write(getCurlConnectionError(res))
curl_easy_cleanup(curl)
main()