about summary refs log blame commit diff stats
path: root/src/types/urimethodmap.nim
blob: 464c9b694e43a3fba52156633b6ac6cfad2a8202 (plain) (tree)
1
2
3
4

                              

                   















                                                
                      










                      



















                                                                            
                                                                 
                                 
           
                                       
                        

                      


                                                      

                                                  

                                                     

                                                       

                                                
                                      



                                                  



                                                          
# w3m's URI method map format.

import std/strutils
import std/tables

import types/opt
import types/url
import utils/twtstr

type URIMethodMap* = object
  map: Table[string, string]

func rewriteURL(pattern, surl: string): string =
  result = ""
  var was_perc = false
  for c in pattern:
    if was_perc:
      if c == '%':
        result &= '%'
      elif c == 's':
        result &= surl
      else:
        result &= '%'
        result &= c
      was_perc = false
    elif c != '%':
      result &= c
    else:
      was_perc = true
  if was_perc:
    result &= '%'

type URIMethodMapResult* = enum
  URI_RESULT_NOT_FOUND, URI_RESULT_SUCCESS, URI_RESULT_WRONG_URL

proc findAndRewrite*(this: URIMethodMap, url: var URL): URIMethodMapResult =
  let protocol = url.protocol
  if protocol in this.map:
    let surl = this.map[protocol].rewriteURL($url)
    let x = newURL(surl)
    if x.isNone:
      return URI_RESULT_WRONG_URL
    url = x.get
    return URI_RESULT_SUCCESS
  return URI_RESULT_NOT_FOUND

proc parseURIMethodMap*(this: var URIMethodMap, s: string) =
  for line in s.split('\n'):
    if line.len == 0 or line[0] == '#':
      continue # comments
    var k = ""
    var i = 0
    while i < line.len and line[i] notin AsciiWhitespace + {':'}:
      k &= line[i].toLowerAscii()
      inc i
    if i >= line.len or line[i] != ':':
      continue # invalid
    k &= ':'
    inc i # skip colon
    while i < line.len and line[i] in AsciiWhitespace:
      inc i
    var v = line.until(AsciiWhitespace, i)
    # Basic w3m compatibility.
    # If needed, w3m-cgi-compat covers more cases.
    if v.startsWith("file:/cgi-bin/"):
      v = "cgi-bin:" & v.substr("file:/cgi-bin/".len)
    elif v.startsWith("file:///cgi-bin/"):
      v = "cgi-bin:" & v.substr("file:///cgi-bin/".len)
    elif v.startsWith("/cgi-bin/"):
      v = "cgi-bin:" & v.substr("/cgi-bin/".len)
    discard this.map.hasKeyOrPut(k, v)

proc parseURIMethodMap*(s: string): URIMethodMap =
  result = URIMethodMap()
  result.parseURIMethodMap(s)

proc append*(this: var URIMethodMap, that: URIMethodMap) =
  for k, v in that.map:
    discard this.map.hasKeyOrPut(k, v)