├── .travis.yml ├── CMakeLists.txt ├── COPYRIGHT ├── Changes ├── MANIFEST ├── Makefile ├── README ├── TODO ├── cmake ├── FindLua.cmake ├── dist.cmake └── lua.cmake ├── debian ├── Makefile.Debian.conf ├── changelog ├── compat ├── control ├── copyright ├── liblua5.1-uri-dev.manpages └── rules ├── dist.info ├── doc ├── lua-uri-_login.3 ├── lua-uri-_login.pod ├── lua-uri-_util.3 ├── lua-uri-_util.pod ├── lua-uri-data.3 ├── lua-uri-data.pod ├── lua-uri-file.3 ├── lua-uri-file.pod ├── lua-uri-ftp.3 ├── lua-uri-ftp.pod ├── lua-uri-http.3 ├── lua-uri-http.pod ├── lua-uri-pop.3 ├── lua-uri-pop.pod ├── lua-uri-rtsp.3 ├── lua-uri-rtsp.pod ├── lua-uri-telnet.3 ├── lua-uri-telnet.pod ├── lua-uri-urn-isbn.3 ├── lua-uri-urn-isbn.pod ├── lua-uri-urn-issn.3 ├── lua-uri-urn-issn.pod ├── lua-uri-urn-oid.3 ├── lua-uri-urn-oid.pod ├── lua-uri-urn.3 ├── lua-uri-urn.pod ├── lua-uri.3 └── lua-uri.pod ├── lunit.lua ├── test ├── _generic.lua ├── _pristine.lua ├── _relative.lua ├── _resolve.lua ├── _util.lua ├── data.lua ├── file.lua ├── ftp.lua ├── http.lua ├── pop.lua ├── rtsp.lua ├── telnet.lua ├── urn-isbn.lua ├── urn-issn.lua ├── urn-oid.lua └── urn.lua ├── uri-test.lua ├── uri.lua └── uri ├── _login.lua ├── _relative.lua ├── _util.lua ├── data.lua ├── file.lua ├── file ├── unix.lua └── win32.lua ├── ftp.lua ├── http.lua ├── https.lua ├── pop.lua ├── rtsp.lua ├── rtspu.lua ├── telnet.lua ├── urn.lua └── urn ├── isbn.lua ├── issn.lua └── oid.lua /.travis.yml: -------------------------------------------------------------------------------- 1 | # 2 | # LuaDist Travis-CI Hook 3 | # 4 | 5 | # We assume C build environments 6 | language: C 7 | 8 | # Try using multiple Lua Implementations 9 | env: 10 | - TOOL="gcc" # Use native compiler (GCC usually) 11 | - TOOL="clang" # Use clang 12 | - TOOL="i686-w64-mingw32" # 32bit MinGW 13 | - TOOL="x86_64-w64-mingw32" # 64bit MinGW 14 | - TOOL="arm-linux-gnueabihf" # ARM hard-float (hf), linux 15 | 16 | # Crosscompile builds may fail 17 | matrix: 18 | allow_failures: 19 | - env: TOOL="i686-w64-mingw32" 20 | - env: TOOL="x86_64-w64-mingw32" 21 | - env: TOOL="arm-linux-gnueabihf" 22 | 23 | # Install dependencies 24 | install: 25 | - git clone git://github.com/LuaDist/Tools.git ~/_tools 26 | - ~/_tools/travis/travis install 27 | 28 | # Bootstap 29 | before_script: 30 | - ~/_tools/travis/travis bootstrap 31 | 32 | # Build the module 33 | script: 34 | - ~/_tools/travis/travis build 35 | 36 | # Execute additional tests or commands 37 | after_script: 38 | - ~/_tools/travis/travis test 39 | 40 | # Only watch the master branch 41 | branches: 42 | only: 43 | - master 44 | 45 | # Notify the LuaDist Dev group if needed 46 | notifications: 47 | recipients: 48 | - luadist-dev@googlegroups.com 49 | email: 50 | on_success: change 51 | on_failure: always 52 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2007-2012 LuaDist. 2 | # Created by Peter Kapec 3 | # Redistribution and use of this file is allowed according to the terms of the MIT license. 4 | # For details see the COPYRIGHT file distributed with LuaDist. 5 | # Please note that the package source code is licensed under its own license. 6 | 7 | project ( lua-uri NONE ) 8 | cmake_minimum_required ( VERSION 2.8 ) 9 | include ( cmake/dist.cmake ) 10 | include ( lua ) 11 | 12 | # Install all files and documentation 13 | install_lua_module ( uri uri.lua ) 14 | install ( DIRECTORY uri DESTINATION ${INSTALL_LMOD} COMPONENT Runtime ) 15 | install_data ( COPYRIGHT Changes README TODO ) 16 | install_doc ( doc/ ) 17 | install_test ( test/ uri-test.lua ) 18 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | This software and documentation is distributed under the same terms as 2 | Lua version 5.0, the MIT/X Consortium license. The full terms are as 3 | follows: 4 | 5 | Copyright (C) 2007 Geoff Richards 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /Changes: -------------------------------------------------------------------------------- 1 | 1.0 2007-11-30 2 | 3 | * Initial release. 4 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | debian/Makefile.Debian.conf 2 | debian/changelog 3 | debian/compat 4 | debian/control 5 | debian/copyright 6 | debian/liblua5.1-uri-dev.manpages 7 | debian/rules 8 | COPYRIGHT 9 | Changes 10 | MANIFEST 11 | Makefile 12 | README 13 | TODO 14 | doc/lua-uri-_login.3 15 | doc/lua-uri-_login.pod 16 | doc/lua-uri-_util.3 17 | doc/lua-uri-_util.pod 18 | doc/lua-uri-data.3 19 | doc/lua-uri-data.pod 20 | doc/lua-uri-file.3 21 | doc/lua-uri-file.pod 22 | doc/lua-uri-ftp.3 23 | doc/lua-uri-ftp.pod 24 | doc/lua-uri-http.3 25 | doc/lua-uri-http.pod 26 | doc/lua-uri-pop.3 27 | doc/lua-uri-pop.pod 28 | doc/lua-uri-rtsp.3 29 | doc/lua-uri-rtsp.pod 30 | doc/lua-uri-telnet.3 31 | doc/lua-uri-telnet.pod 32 | doc/lua-uri-urn-isbn.3 33 | doc/lua-uri-urn-isbn.pod 34 | doc/lua-uri-urn-issn.3 35 | doc/lua-uri-urn-issn.pod 36 | doc/lua-uri-urn-oid.3 37 | doc/lua-uri-urn-oid.pod 38 | doc/lua-uri-urn.3 39 | doc/lua-uri-urn.pod 40 | doc/lua-uri.3 41 | doc/lua-uri.pod 42 | lunit.lua 43 | test/_generic.lua 44 | test/_pristine.lua 45 | test/_relative.lua 46 | test/_resolve.lua 47 | test/_util.lua 48 | test/data.lua 49 | test/file.lua 50 | test/ftp.lua 51 | test/http.lua 52 | test/pop.lua 53 | test/rtsp.lua 54 | test/telnet.lua 55 | test/urn-isbn.lua 56 | test/urn-issn.lua 57 | test/urn-oid.lua 58 | test/urn.lua 59 | uri-test.lua 60 | uri.lua 61 | uri/_login.lua 62 | uri/_relative.lua 63 | uri/_util.lua 64 | uri/data.lua 65 | uri/file.lua 66 | uri/file/unix.lua 67 | uri/file/win32.lua 68 | uri/ftp.lua 69 | uri/http.lua 70 | uri/https.lua 71 | uri/pop.lua 72 | uri/rtsp.lua 73 | uri/rtspu.lua 74 | uri/telnet.lua 75 | uri/urn.lua 76 | uri/urn/isbn.lua 77 | uri/urn/issn.lua 78 | uri/urn/oid.lua 79 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PACKAGE=lua-uri 2 | VERSION=$(shell head -1 Changes | sed 's/ .*//') 3 | RELEASEDATE=$(shell head -1 Changes | sed 's/.* //') 4 | PREFIX=/usr/local 5 | DISTNAME=$(PACKAGE)-$(VERSION) 6 | 7 | # The path to where the module's source files should be installed. 8 | LUA_SPATH:=$(shell pkg-config lua5.1 --define-variable=prefix=$(PREFIX) \ 9 | --variable=INSTALL_LMOD) 10 | 11 | MANPAGES = doc/lua-uri.3 doc/lua-uri-_login.3 doc/lua-uri-_util.3 doc/lua-uri-data.3 doc/lua-uri-file.3 doc/lua-uri-ftp.3 doc/lua-uri-http.3 doc/lua-uri-pop.3 doc/lua-uri-rtsp.3 doc/lua-uri-telnet.3 doc/lua-uri-urn.3 doc/lua-uri-urn-isbn.3 doc/lua-uri-urn-issn.3 doc/lua-uri-urn-oid.3 12 | 13 | all: $(MANPAGES) 14 | 15 | doc/lua-%.3: doc/lua-%.pod 16 | sed 's/E/(c)/g' <$< | sed 's/E/-/g' | \ 17 | pod2man --center="Lua $(shell echo $< | sed 's/^doc\/lua-//' | sed 's/\.pod$$//' | sed 's/-/./g') module" \ 18 | --name="$(shell echo $< | sed 's/^doc\///' | sed 's/\.pod$$//' | tr a-z A-Z)" --section=3 \ 19 | --release="$(VERSION)" --date="$(RELEASEDATE)" >$@ 20 | 21 | test: all 22 | for f in test/*.lua; do lua $$f; done 23 | 24 | install: all 25 | mkdir -p $(LUA_SPATH)/uri/{file,urn} 26 | mkdir -p $(PREFIX)/share/man/man3 27 | install --mode=644 uri.lua $(LUA_SPATH)/ 28 | for module in _login _relative _util data file ftp http https pop rtsp rtspu telnet urn; do \ 29 | install --mode=644 uri/$$module.lua $(LUA_SPATH)/uri/; \ 30 | done 31 | for module in unix win32; do \ 32 | install --mode=644 uri/file/$$module.lua $(LUA_SPATH)/uri/file/; \ 33 | done 34 | for module in isbn issn oid; do \ 35 | install --mode=644 uri/urn/$$module.lua $(LUA_SPATH)/uri/urn/; \ 36 | done 37 | for manpage in $(MANPAGES); do \ 38 | gzip -c $$manpage >$(PREFIX)/share/man/man3/$$(echo $$manpage | sed -e 's/^doc\///').gz; \ 39 | done 40 | 41 | checktmp: 42 | @if [ -e tmp ]; then \ 43 | echo "Can't proceed if file 'tmp' exists"; \ 44 | false; \ 45 | fi 46 | dist: all checktmp 47 | mkdir -p tmp/$(DISTNAME) 48 | tar cf - --files-from MANIFEST | (cd tmp/$(DISTNAME) && tar xf -) 49 | cd tmp && tar cf - $(DISTNAME) | gzip -9 >../$(DISTNAME).tar.gz 50 | cd tmp && tar cf - $(DISTNAME) | bzip2 -9 >../$(DISTNAME).tar.bz2 51 | rm -f $(DISTNAME).zip 52 | cd tmp && zip -q -r -9 ../$(DISTNAME).zip $(DISTNAME) 53 | rm -rf tmp 54 | 55 | clean: 56 | rm -f $(MANPAGES) 57 | 58 | .PHONY: all test install checktmp dist clean 59 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This library allows you to normalize and validate URIs, and provides methods 2 | for manipulating them in various ways. 3 | 4 | The Lua-URI library is written in pure Lua. No C compilation is required 5 | to install it. 6 | 7 | When you unpack the source code everything should already be ready for 8 | installation. Doing "make install" as root will install the Lua source 9 | files and the man pages containing the documentation. 10 | 11 | See lua-uri(3) for information about how to use the library. The same 12 | documentation is available on the website, where you can also get the 13 | latest packages: 14 | 15 | http://www.daizucms.org/lua/library/uri/ 16 | 17 | Send bug reports, suggestions, etc. to Geoff Richards 18 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Perhaps incorporate Mozilla test suite for data: URIs: 2 | http://www.mozilla.org/quality/networking/testing/datatests.html 3 | also validate the mediatype part and normalize it by omitting things which 4 | will be the same by default. 5 | 6 | Check for compliance with latest RFC: 7 | http://tools.ietf.org/html/rfc3986 8 | (uri_encode might use the wrong default for 'patn') 9 | 10 | Try to integrate support for IRIs: 11 | http://tools.ietf.org/html/rfc3987 12 | 13 | Other schemes: 14 | complete IANA list: http://www.iana.org/assignments/uri-schemes.html 15 | opaquelocktoken - http://www.rfc-editor.org/rfc/rfc4918.txt (Appendix C) 16 | svn 17 | mailto - http://tools.ietf.org/html/rfc2368 18 | info - http://tools.ietf.org/html/rfc4452 19 | prospero - http://tools.ietf.org/html/rfc4157 20 | wais - http://tools.ietf.org/html/rfc4156 21 | tel - http://tools.ietf.org/html/rfc3966 22 | sip and sips - http://tools.ietf.org/html/rfc3261 23 | gopher - http://tools.ietf.org/html/rfc4266 24 | tag - http://tools.ietf.org/html/rfc4151 25 | 26 | new IMAP URI RFC: 27 | http://www.rfc-editor.org/rfc/rfc5092.txt 28 | 29 | Other NIDs for URNs, some of which are shown here: 30 | http://en.wikipedia.org/wiki/Uniform_Resource_Name 31 | 32 | Other NIDs which have RFCs: 33 | ietf - http://tools.ietf.org/html/rfc2648 34 | publicid - http://tools.ietf.org/html/rfc3151 35 | uuid - http://tools.ietf.org/html/rfc4122 36 | sici - http://tools.ietf.org/html/rfc2288 (not really standardised there, but is there a proper RFC?) 37 | 38 | check these CPAN bugs against URI module: 39 | mailto encoding: http://rt.cpan.org/Public/Bug/Display.html?id=24934 40 | encode: http://rt.cpan.org/Public/Bug/Display.html?id=21640 41 | 42 | gopher URI found in the wild, use for testing: 43 | 44 | 45 | Once again provide the stripping of '' and such like. 46 | -------------------------------------------------------------------------------- /cmake/FindLua.cmake: -------------------------------------------------------------------------------- 1 | # Locate Lua library 2 | # This module defines 3 | # LUA_EXECUTABLE, if found 4 | # LUA_FOUND, if false, do not try to link to Lua 5 | # LUA_LIBRARIES 6 | # LUA_INCLUDE_DIR, where to find lua.h 7 | # LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8) 8 | # 9 | # Note that the expected include convention is 10 | # #include "lua.h" 11 | # and not 12 | # #include 13 | # This is because, the lua location is not standardized and may exist 14 | # in locations other than lua/ 15 | 16 | #============================================================================= 17 | # Copyright 2007-2009 Kitware, Inc. 18 | # Modified to support Lua 5.2 by LuaDist 2012 19 | # 20 | # Distributed under the OSI-approved BSD License (the "License"); 21 | # see accompanying file Copyright.txt for details. 22 | # 23 | # This software is distributed WITHOUT ANY WARRANTY; without even the 24 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 25 | # See the License for more information. 26 | #============================================================================= 27 | # (To distribute this file outside of CMake, substitute the full 28 | # License text for the above reference.) 29 | # 30 | # The required version of Lua can be specified using the 31 | # standard syntax, e.g. FIND_PACKAGE(Lua 5.1) 32 | # Otherwise the module will search for any available Lua implementation 33 | 34 | # Always search for non-versioned lua first (recommended) 35 | SET(_POSSIBLE_LUA_INCLUDE include include/lua) 36 | SET(_POSSIBLE_LUA_EXECUTABLE lua) 37 | SET(_POSSIBLE_LUA_LIBRARY lua) 38 | 39 | # Determine possible naming suffixes (there is no standard for this) 40 | IF(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR) 41 | SET(_POSSIBLE_SUFFIXES "${Lua_FIND_VERSION_MAJOR}${Lua_FIND_VERSION_MINOR}" "${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR}" "-${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR}") 42 | ELSE(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR) 43 | SET(_POSSIBLE_SUFFIXES "52" "5.2" "-5.2" "51" "5.1" "-5.1") 44 | ENDIF(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR) 45 | 46 | # Set up possible search names and locations 47 | FOREACH(_SUFFIX ${_POSSIBLE_SUFFIXES}) 48 | LIST(APPEND _POSSIBLE_LUA_INCLUDE "include/lua${_SUFFIX}") 49 | LIST(APPEND _POSSIBLE_LUA_EXECUTABLE "lua${_SUFFIX}") 50 | LIST(APPEND _POSSIBLE_LUA_LIBRARY "lua${_SUFFIX}") 51 | ENDFOREACH(_SUFFIX) 52 | 53 | # Find the lua executable 54 | FIND_PROGRAM(LUA_EXECUTABLE 55 | NAMES ${_POSSIBLE_LUA_EXECUTABLE} 56 | ) 57 | 58 | # Find the lua header 59 | FIND_PATH(LUA_INCLUDE_DIR lua.h 60 | HINTS 61 | $ENV{LUA_DIR} 62 | PATH_SUFFIXES ${_POSSIBLE_LUA_INCLUDE} 63 | PATHS 64 | ~/Library/Frameworks 65 | /Library/Frameworks 66 | /usr/local 67 | /usr 68 | /sw # Fink 69 | /opt/local # DarwinPorts 70 | /opt/csw # Blastwave 71 | /opt 72 | ) 73 | 74 | # Find the lua library 75 | FIND_LIBRARY(LUA_LIBRARY 76 | NAMES ${_POSSIBLE_LUA_LIBRARY} 77 | HINTS 78 | $ENV{LUA_DIR} 79 | PATH_SUFFIXES lib64 lib 80 | PATHS 81 | ~/Library/Frameworks 82 | /Library/Frameworks 83 | /usr/local 84 | /usr 85 | /sw 86 | /opt/local 87 | /opt/csw 88 | /opt 89 | ) 90 | 91 | IF(LUA_LIBRARY) 92 | # include the math library for Unix 93 | IF(UNIX AND NOT APPLE) 94 | FIND_LIBRARY(LUA_MATH_LIBRARY m) 95 | SET( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries") 96 | # For Windows and Mac, don't need to explicitly include the math library 97 | ELSE(UNIX AND NOT APPLE) 98 | SET( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries") 99 | ENDIF(UNIX AND NOT APPLE) 100 | ENDIF(LUA_LIBRARY) 101 | 102 | # Determine Lua version 103 | IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h") 104 | FILE(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"") 105 | 106 | STRING(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}") 107 | UNSET(lua_version_str) 108 | ENDIF() 109 | 110 | INCLUDE(FindPackageHandleStandardArgs) 111 | # handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if 112 | # all listed variables are TRUE 113 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua 114 | REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR 115 | VERSION_VAR LUA_VERSION_STRING) 116 | 117 | MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY LUA_EXECUTABLE) 118 | 119 | -------------------------------------------------------------------------------- /debian/Makefile.Debian.conf: -------------------------------------------------------------------------------- 1 | PKG_NAME=uri 2 | 3 | LUA_SOURCES=uri.lua uri 4 | LUA_MODNAME=uri 5 | 6 | PKG_VERSION=$(shell dpkg-parsechangelog|grep ^Ver|cut -d ' ' -f 2|cut -d '-' -f 1) 7 | PKG_URL=http://www.daizucms.org/lua/library/uri/ 8 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | lua-uri (1.0-1) unstable; urgency=low 2 | 3 | * Initial release. 4 | 5 | -- Geoff Richards Thu, 30 Nov 2007 00:30:08 +0000 6 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: lua-uri 2 | Section: interpreters 3 | Priority: optional 4 | Maintainer: Geoff Richards 5 | Build-Depends: cdbs (>= 0.4.23-1.1), debhelper (>= 5), dpatch, lua5.1-policy-dev (>= 8) 6 | Standards-Version: 3.7.2 7 | 8 | Package: liblua5.1-uri 9 | Architecture: all 10 | Depends: 11 | Description: library for manipulating URIs in Lua programs 12 | This library allows you to normalize and validate URIs, and provides methods 13 | for manipulating them in various ways. 14 | . 15 | The latest source code and documentation is always available from the 16 | module's website: 17 | 18 | Package: liblua5.1-uri-dev 19 | Architecture: all 20 | Depends: liblua5.1-uri (= ${binary:Version}) 21 | Description: documentation for the Lua URI module 22 | This package contains documentation for the liblua5.1-uri package, as a 23 | series of man pages. The main one is lua-uri(3), which describes the 24 | general API and gives examples of how to use it. There are other pages 25 | describing the different handling of URIs of certain schemes. 26 | A more attractive version of the same thing is available on the module's 27 | website: 28 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | ../COPYRIGHT -------------------------------------------------------------------------------- /debian/liblua5.1-uri-dev.manpages: -------------------------------------------------------------------------------- 1 | doc/lua-uri-_login.3 2 | doc/lua-uri-_util.3 3 | doc/lua-uri-data.3 4 | doc/lua-uri-file.3 5 | doc/lua-uri-ftp.3 6 | doc/lua-uri-http.3 7 | doc/lua-uri-pop.3 8 | doc/lua-uri-rtsp.3 9 | doc/lua-uri-telnet.3 10 | doc/lua-uri-urn-isbn.3 11 | doc/lua-uri-urn-issn.3 12 | doc/lua-uri-urn-oid.3 13 | doc/lua-uri-urn.3 14 | doc/lua-uri.3 15 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | include /usr/share/cdbs/1/class/makefile.mk 4 | include /usr/share/cdbs/1/rules/debhelper.mk 5 | include /usr/share/cdbs/1/rules/dpatch.mk 6 | 7 | DEB_MAKE_BUILD_TARGET := all -f Makefile.Debian 8 | DEB_MAKE_CHECK_TARGET := test -f Makefile.Debian 9 | DEB_MAKE_CLEAN_TARGET := clean -f Makefile.Debian 10 | DEB_MAKE_INSTALL_TARGET := install -f Makefile.Debian DESTDIR=$(DEB_DESTDIR) 11 | DEB_DH_INSTALL_SOURCEDIR := $(DEB_DESTDIR) 12 | pre-build:: 13 | lua5.1-policy-apply 14 | clean:: 15 | lua5.1-policy-apply --reverse 16 | -------------------------------------------------------------------------------- /dist.info: -------------------------------------------------------------------------------- 1 | --- This file is part of LuaDist project 2 | 3 | name = "lua-uri" 4 | version = "1.0" 5 | 6 | desc = "Lua module for manipulating URIs" 7 | author = "Geoff Richards" 8 | license = "MIT/X Consortium" 9 | url = "http://www.daizucms.org/lua/library/uri" 10 | maintainer = "Peter Kapec" 11 | 12 | depends = { 13 | "lua ~> 5.1" 14 | } 15 | -------------------------------------------------------------------------------- /doc/lua-uri-_login.3: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 2 | .\" 3 | .\" Standard preamble: 4 | .\" ======================================================================== 5 | .de Sh \" Subsection heading 6 | .br 7 | .if t .Sp 8 | .ne 5 9 | .PP 10 | \fB\\$1\fR 11 | .PP 12 | .. 13 | .de Sp \" Vertical space (when we can't use .PP) 14 | .if t .sp .5v 15 | .if n .sp 16 | .. 17 | .de Vb \" Begin verbatim text 18 | .ft CW 19 | .nf 20 | .ne \\$1 21 | .. 22 | .de Ve \" End verbatim text 23 | .ft R 24 | .fi 25 | .. 26 | .\" Set up some character translations and predefined strings. \*(-- will 27 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left 28 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will 29 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and 30 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, 31 | .\" nothing in troff, for use with C<>. 32 | .tr \(*W- 33 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' 34 | .ie n \{\ 35 | . ds -- \(*W- 36 | . ds PI pi 37 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch 38 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch 39 | . ds L" "" 40 | . ds R" "" 41 | . ds C` "" 42 | . ds C' "" 43 | 'br\} 44 | .el\{\ 45 | . ds -- \|\(em\| 46 | . ds PI \(*p 47 | . ds L" `` 48 | . ds R" '' 49 | 'br\} 50 | .\" 51 | .\" If the F register is turned on, we'll generate index entries on stderr for 52 | .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index 53 | .\" entries marked with X<> in POD. Of course, you'll have to process the 54 | .\" output yourself in some meaningful fashion. 55 | .if \nF \{\ 56 | . de IX 57 | . tm Index:\\$1\t\\n%\t"\\$2" 58 | .. 59 | . nr % 0 60 | . rr F 61 | .\} 62 | .\" 63 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes 64 | .\" way too many mistakes in technical documents. 65 | .hy 0 66 | .if n .na 67 | .\" 68 | .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). 69 | .\" Fear. Run. Save yourself. No user-serviceable parts. 70 | . \" fudge factors for nroff and troff 71 | .if n \{\ 72 | . ds #H 0 73 | . ds #V .8m 74 | . ds #F .3m 75 | . ds #[ \f1 76 | . ds #] \fP 77 | .\} 78 | .if t \{\ 79 | . ds #H ((1u-(\\\\n(.fu%2u))*.13m) 80 | . ds #V .6m 81 | . ds #F 0 82 | . ds #[ \& 83 | . ds #] \& 84 | .\} 85 | . \" simple accents for nroff and troff 86 | .if n \{\ 87 | . ds ' \& 88 | . ds ` \& 89 | . ds ^ \& 90 | . ds , \& 91 | . ds ~ ~ 92 | . ds / 93 | .\} 94 | .if t \{\ 95 | . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" 96 | . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' 97 | . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' 98 | . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' 99 | . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' 100 | . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' 101 | .\} 102 | . \" troff and (daisy-wheel) nroff accents 103 | .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' 104 | .ds 8 \h'\*(#H'\(*b\h'-\*(#H' 105 | .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] 106 | .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' 107 | .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' 108 | .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] 109 | .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] 110 | .ds ae a\h'-(\w'a'u*4/10)'e 111 | .ds Ae A\h'-(\w'A'u*4/10)'E 112 | . \" corrections for vroff 113 | .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' 114 | .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' 115 | . \" for low resolution devices (crt and lpr) 116 | .if \n(.H>23 .if \n(.V>19 \ 117 | \{\ 118 | . ds : e 119 | . ds 8 ss 120 | . ds o a 121 | . ds d- d\h'-1'\(ga 122 | . ds D- D\h'-1'\(hy 123 | . ds th \o'bp' 124 | . ds Th \o'LP' 125 | . ds ae ae 126 | . ds Ae AE 127 | .\} 128 | .rm #[ #] #H #V #F C 129 | .\" ======================================================================== 130 | .\" 131 | .IX Title "LUA-URI-_LOGIN 3" 132 | .TH LUA-URI-_LOGIN 3 "2007-11-02" "1.0" "Lua uri._login module" 133 | .SH "Name" 134 | .IX Header "Name" 135 | lua\-uri\-_login \- Lua \s-1URI\s0 library support for URIs containing usernames and passwords 136 | .SH "Description" 137 | .IX Header "Description" 138 | The \f(CW\*(C`uri._login\*(C'\fR class is used as a base class by classes implementing \s-1URI\s0 139 | schemes which can have a username and password in the userinfo part, separated 140 | by a colon. 141 | .PP 142 | A \s-1URI\s0 of this type where the userinfo part contains more than one colon 143 | is considered invalid. They must also have a non-empty host part. The 144 | username and password are each optional. 145 | .PP 146 | The current implementation requires subclasses to call this class's 147 | \&\f(CW\*(C`init_base\*(C'\fR method within their \f(CW\*(C`init\*(C'\fR method to do the extra validation. 148 | This may change if I think of a better way of doing it. 149 | .SH "Methods" 150 | .IX Header "Methods" 151 | All the methods defined in \fIlua\-uri\fR\|(3) are supported, in addition to the 152 | following: 153 | .IP "uri:username(...)" 4 154 | .IX Item "uri:username(...)" 155 | Mutator for the username in the userinfo part. Returns an optionally sets 156 | the first part of the userinfo, before the colon. If there is no password 157 | then the username will be the whole of the userinfo part, and no colon will 158 | be present. 159 | .Sp 160 | .Vb 3 161 | \& local uri = assert(URI:new("ftp://host/path")) 162 | \& uri:username("fred") \-\- ftp://fred@host/path 163 | \& uri:username(nil) \-\- ftp://host/path 164 | .Ve 165 | .Sp 166 | Passing nil as the new username will also remove any password in the userinfo, 167 | since the password is expected to be meaningless without the username. 168 | .Sp 169 | The username is appropriately percent encoded and decoded by this method. 170 | .IP "uri:password(...)" 4 171 | .IX Item "uri:password(...)" 172 | Mutator for the password part of the userinfo. This will appear after a 173 | colon, whether or not there is a username. 174 | .Sp 175 | The password is appropriately percent encoded and decoded by this method. 176 | .Sp 177 | .Vb 2 178 | \& local password = uri:password() 179 | \& uri:password("secret") 180 | .Ve 181 | .SH "References" 182 | .IX Header "References" 183 | The main \s-1RFC\s0 for URIs (\*(L"\s-1RFC\s0 3986\*(R") does not specify a syntax for the 184 | userinfo part of the authority, which is why the \f(CW\*(C`username\*(C'\fR and \f(CW\*(C`password\*(C'\fR 185 | methods are not provided in the generic \f(CW\*(C`uri\*(C'\fR class. The use of the colon 186 | to separate these parts, and the escaping conventions, are instead derived 187 | from the older \*(L"\s-1RFC\s0 1738 section 3.1\*(R", and the up to date telnet \s-1URI\s0 188 | specification in \*(L"\s-1RFC\s0 4248\*(R". 189 | -------------------------------------------------------------------------------- /doc/lua-uri-_login.pod: -------------------------------------------------------------------------------- 1 | =head1 Name 2 | 3 | lua-uri-_login - Lua URI library support for URIs containing usernames and passwords 4 | 5 | =head1 Description 6 | 7 | The C class is used as a base class by classes implementing URI 8 | schemes which can have a username and password in the userinfo part, separated 9 | by a colon. 10 | 11 | A URI of this type where the userinfo part contains more than one colon 12 | is considered invalid. They must also have a non-empty host part. The 13 | username and password are each optional. 14 | 15 | The current implementation requires subclasses to call this class's 16 | C method within their C method to do the extra validation. 17 | This may change if I think of a better way of doing it. 18 | 19 | =head1 Methods 20 | 21 | All the methods defined in L are supported, in addition to the 22 | following: 23 | 24 | =over 25 | 26 | =item uri:username(...) 27 | 28 | Mutator for the username in the userinfo part. Returns an optionally sets 29 | the first part of the userinfo, before the colon. If there is no password 30 | then the username will be the whole of the userinfo part, and no colon will 31 | be present. 32 | 33 | =for syntax-highlight lua 34 | 35 | local uri = assert(URI:new("ftp://host/path")) 36 | uri:username("fred") -- ftp://fred@host/path 37 | uri:username(nil) -- ftp://host/path 38 | 39 | Passing nil as the new username will also remove any password in the userinfo, 40 | since the password is expected to be meaningless without the username. 41 | 42 | The username is appropriately percent encoded and decoded by this method. 43 | 44 | =item uri:password(...) 45 | 46 | Mutator for the password part of the userinfo. This will appear after a 47 | colon, whether or not there is a username. 48 | 49 | The password is appropriately percent encoded and decoded by this method. 50 | 51 | =for syntax-highlight lua 52 | 53 | local password = uri:password() 54 | uri:password("secret") 55 | 56 | =back 57 | 58 | =head1 References 59 | 60 | The main RFC for URIs (L) does not specify a syntax for the 61 | userinfo part of the authority, which is why the C and C 62 | methods are not provided in the generic C class. The use of the colon 63 | to separate these parts, and the escaping conventions, are instead derived 64 | from the older L, and the up to date telnet URI 65 | specification in L. 66 | 67 | =for comment 68 | vi:ts=4 sw=4 expandtab 69 | -------------------------------------------------------------------------------- /doc/lua-uri-_util.pod: -------------------------------------------------------------------------------- 1 | =head1 Name 2 | 3 | lua-uri-_util - Utility functions for Lua URI library 4 | 5 | =head1 Description 6 | 7 | This module contains various utility functions used by the rest of the 8 | library. They are mostly intended only for internal use, and are subject 9 | to change in future versions, but the URI encoding and decoding functions 10 | may be more widely useful. 11 | 12 | On loading, the module returns a table containing the functions, but like 13 | all the modules in this library it does not install itself into any global 14 | variables. 15 | 16 | =for syntax-highlight lua 17 | 18 | local Util = require "uri._util" 19 | 20 | =head1 Functions 21 | 22 | The following functions can be found in the table returned from C: 23 | 24 | =over 25 | 26 | =item uri_encode(text, pattern) 27 | 28 | Use URI encoding (or 'percent encoding') to encode any unsafe characters 29 | in C. If C is specified then it should be part of a Lua 30 | pattern which can be enclosed in square brackets to make a character class. 31 | Usually it will start with C<^> so that the rest of the characters will be 32 | considered the 'safe' ones, not to be encoded. Any character matched by the 33 | pattern will be encoded. 34 | 35 | =for syntax-highlight lua 36 | 37 | print(Util.uri_encode("foo bar!")) 38 | ---> foo%20bar! 39 | print(Util.uri_encode("foo bar!", "^A-Za-z0-9")) 40 | ---> foo%20bar%21 41 | 42 | The default pattern is: C<^A-Za-z0-9%-_.!~*'()> 43 | 44 | =item uri_decode(text, pattern) 45 | 46 | Decode any URI encoding in C. If C is nil then all encoded 47 | characters will be decoded. If a pattern is supplied then it should be in 48 | the same form as for C. Any character not matched by the pattern 49 | will be left encoded as it was. 50 | 51 | =for syntax-highlight lua 52 | 53 | print(Util.uri_decode("foo%20bar%21")) 54 | ---> foo bar! 55 | print(Util.uri_decode("foo%20bar%21", "^!")) 56 | ---> foo bar%21 57 | 58 | =item remove_dot_segments(path) 59 | 60 | Removes single and double dot segments from a URI path. 61 | 62 | This is the 'remove_dot_segments' algorithm from L. 63 | The value of C is used as the input buffer, and the contents of the 64 | output buffer are returned. 65 | 66 | =item split(pattern, str, max) 67 | 68 | Split the string C wherever C matches it, returning the pieces 69 | as individual strings in an array. If C is not nil, then stop splitting 70 | after that many pieces have been created. 71 | 72 | =item attempt_require(name) 73 | 74 | Calling this function is the same as calling Lua's built in C 75 | function, except that if a module called C cannot be found, it returns 76 | nil instead of throwing an exception. If loading the module is successful 77 | then the result of C is returned. An exception is thrown if any 78 | error occurs loading the module other than it not being found. 79 | 80 | =item subclass_of(class, baseclass) 81 | 82 | Sets up the metatable and a few other things for the table C so that it 83 | will be a subclass of C. This is used by the classes in this 84 | library to implement inheritance. 85 | 86 | =item do_class_changing_change(uri, baseclass, changedesc, newvalue, changefunc) 87 | 88 | This is used when a mutator method changes something about a URI which leads it 89 | to need to belong to a different class. C is the URI object to change, 90 | C is the class to reset it to before making the change, 91 | C is a description to be included in an error message if necessary, 92 | C is the new value to be set (which must be a string, as it is also 93 | included in error messages), and C is a function which is called 94 | with a temporary URI object it should adjust and C. 95 | 96 | =item uri_part_not_allowed (class, method) 97 | 98 | This should be called in scheme-specific classes where certain parts of URIs 99 | are not allowed to be present (e.g., the 'host' part in a URN). It will 100 | override the named method in the class with one which throws an exception 101 | if an attempt is made to set the part to anything other than nil. If the 102 | rest of the code for the scheme keeps objects internally consistent then the 103 | new method should always return nil, although when a URI is being validated 104 | during the C method's execution, it may return other things, which can 105 | be used to detect disallowed parts in a URI being parsed. 106 | 107 | =back 108 | 109 | =for comment 110 | vi:ts=4 sw=4 expandtab 111 | -------------------------------------------------------------------------------- /doc/lua-uri-data.3: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 2 | .\" 3 | .\" Standard preamble: 4 | .\" ======================================================================== 5 | .de Sh \" Subsection heading 6 | .br 7 | .if t .Sp 8 | .ne 5 9 | .PP 10 | \fB\\$1\fR 11 | .PP 12 | .. 13 | .de Sp \" Vertical space (when we can't use .PP) 14 | .if t .sp .5v 15 | .if n .sp 16 | .. 17 | .de Vb \" Begin verbatim text 18 | .ft CW 19 | .nf 20 | .ne \\$1 21 | .. 22 | .de Ve \" End verbatim text 23 | .ft R 24 | .fi 25 | .. 26 | .\" Set up some character translations and predefined strings. \*(-- will 27 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left 28 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will 29 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and 30 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, 31 | .\" nothing in troff, for use with C<>. 32 | .tr \(*W- 33 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' 34 | .ie n \{\ 35 | . ds -- \(*W- 36 | . ds PI pi 37 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch 38 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch 39 | . ds L" "" 40 | . ds R" "" 41 | . ds C` "" 42 | . ds C' "" 43 | 'br\} 44 | .el\{\ 45 | . ds -- \|\(em\| 46 | . ds PI \(*p 47 | . ds L" `` 48 | . ds R" '' 49 | 'br\} 50 | .\" 51 | .\" If the F register is turned on, we'll generate index entries on stderr for 52 | .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index 53 | .\" entries marked with X<> in POD. Of course, you'll have to process the 54 | .\" output yourself in some meaningful fashion. 55 | .if \nF \{\ 56 | . de IX 57 | . tm Index:\\$1\t\\n%\t"\\$2" 58 | .. 59 | . nr % 0 60 | . rr F 61 | .\} 62 | .\" 63 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes 64 | .\" way too many mistakes in technical documents. 65 | .hy 0 66 | .if n .na 67 | .\" 68 | .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). 69 | .\" Fear. Run. Save yourself. No user-serviceable parts. 70 | . \" fudge factors for nroff and troff 71 | .if n \{\ 72 | . ds #H 0 73 | . ds #V .8m 74 | . ds #F .3m 75 | . ds #[ \f1 76 | . ds #] \fP 77 | .\} 78 | .if t \{\ 79 | . ds #H ((1u-(\\\\n(.fu%2u))*.13m) 80 | . ds #V .6m 81 | . ds #F 0 82 | . ds #[ \& 83 | . ds #] \& 84 | .\} 85 | . \" simple accents for nroff and troff 86 | .if n \{\ 87 | . ds ' \& 88 | . ds ` \& 89 | . ds ^ \& 90 | . ds , \& 91 | . ds ~ ~ 92 | . ds / 93 | .\} 94 | .if t \{\ 95 | . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" 96 | . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' 97 | . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' 98 | . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' 99 | . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' 100 | . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' 101 | .\} 102 | . \" troff and (daisy-wheel) nroff accents 103 | .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' 104 | .ds 8 \h'\*(#H'\(*b\h'-\*(#H' 105 | .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] 106 | .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' 107 | .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' 108 | .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] 109 | .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] 110 | .ds ae a\h'-(\w'a'u*4/10)'e 111 | .ds Ae A\h'-(\w'A'u*4/10)'E 112 | . \" corrections for vroff 113 | .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' 114 | .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' 115 | . \" for low resolution devices (crt and lpr) 116 | .if \n(.H>23 .if \n(.V>19 \ 117 | \{\ 118 | . ds : e 119 | . ds 8 ss 120 | . ds o a 121 | . ds d- d\h'-1'\(ga 122 | . ds D- D\h'-1'\(hy 123 | . ds th \o'bp' 124 | . ds Th \o'LP' 125 | . ds ae ae 126 | . ds Ae AE 127 | .\} 128 | .rm #[ #] #H #V #F C 129 | .\" ======================================================================== 130 | .\" 131 | .IX Title "LUA-URI-DATA 3" 132 | .TH LUA-URI-DATA 3 "2007-11-02" "1.0" "Lua uri.data module" 133 | .SH "Name" 134 | .IX Header "Name" 135 | lua-uri-data \- data \s-1URI\s0 support for Lua \s-1URI\s0 library 136 | .SH "Description" 137 | .IX Header "Description" 138 | The class \f(CW\*(C`uri.data\*(C'\fR is used for URIs with the \f(CW\*(C`data\*(C'\fR scheme. It inherits 139 | from the uri class. 140 | .PP 141 | Some of the features of this module require the \fIlua\-datafilter\fR\|(3) library 142 | to be installed, but \s-1URI\s0 objects can still be created from \f(CW\*(C`data\*(C'\fR URIs 143 | even if it isn't available. 144 | .PP 145 | Any \f(CW\*(C`data\*(C'\fR \s-1URI\s0 containing an authority part is considered to be invalid, 146 | as is one whose path does not contain a comma. If the \s-1URI\s0 has the 147 | \&\f(CW\*(C`;base64\*(C'\fR parameter, then the data must consist only of characters allowed 148 | in base64 encoded data (upper and lowercase \s-1ASCII\s0 letters, digits, and the 149 | forward slash and plus characters). 150 | .SH "Methods" 151 | .IX Header "Methods" 152 | All the methods defined in \fIlua\-uri\fR\|(3) are supported. The \f(CW\*(C`userinfo\*(C'\fR, 153 | \&\f(CW\*(C`host\*(C'\fR, and \f(CW\*(C`port\*(C'\fR methods will always return nil, and will throw an 154 | exception when passed anything other than nil. The \f(CW\*(C`path\*(C'\fR method will throw 155 | an exception if given a new path which is nil or not valid for the \f(CW\*(C`data\*(C'\fR 156 | scheme. 157 | .PP 158 | The following additional methods are supported: 159 | .IP "uri:data_bytes(...)" 4 160 | .IX Item "uri:data_bytes(...)" 161 | Get or set the data stored in the \s-1URI\s0. The existing data is decoded and 162 | returned. If a new value is supplied it must be a string, and will cause 163 | the path of the \s-1URI\s0 to be changed to encode the new data. The method will 164 | choose the encoding which will result in the smallest \s-1URI\s0, unless the 165 | datafilter module is not installed, in which case it will always use 166 | percent encoding. 167 | .Sp 168 | An exception is thrown if the datafilter module is not installed and the data 169 | in the \s-1URI\s0 is encoded as base64, although a data \s-1URI\s0 using percent encoding 170 | will not cause an exception. 171 | .Sp 172 | The data passed in and returned should not be encoded in any special way, 173 | that is taken care of by the library. 174 | .IP "uri:data_media_type(...)" 4 175 | .IX Item "uri:data_media_type(...)" 176 | Get or set the media type (\s-1MIME\s0 type) stored in the \s-1URI\s0's path before the 177 | comma. This should not include the \f(CW\*(C`;base64\*(C'\fR parameter, which will be 178 | included in the path automatically when appropriate. 179 | .Sp 180 | If there is no media type given in the \s-1URI\s0 then the default value of 181 | \&\f(CW\*(C`text/plain\*(C'\fR will be returned, and if there is no \f(CW\*(C`charset\*(C'\fR parameter 182 | given then the default \f(CW\*(C`;charset=US\-ASCII\*(C'\fR will be included. 183 | .Sp 184 | The media type is encoded and decoded automatically by this method. 185 | .SH "References" 186 | .IX Header "References" 187 | This class is based on \*(L"\s-1RFC\s0 2397\*(R". 188 | -------------------------------------------------------------------------------- /doc/lua-uri-data.pod: -------------------------------------------------------------------------------- 1 | =head1 Name 2 | 3 | lua-uri-data - data URI support for Lua URI library 4 | 5 | =head1 Description 6 | 7 | The class C is used for URIs with the C scheme. It inherits 8 | from the L class. 9 | 10 | Some of the features of this module require the L library 11 | to be installed, but URI objects can still be created from C URIs 12 | even if it isn't available. 13 | 14 | Any C URI containing an authority part is considered to be invalid, 15 | as is one whose path does not contain a comma. If the URI has the 16 | C<;base64> parameter, then the data must consist only of characters allowed 17 | in base64 encoded data (upper and lowercase ASCII letters, digits, and the 18 | forward slash and plus characters). 19 | 20 | =head1 Methods 21 | 22 | All the methods defined in L are supported. The C, 23 | C, and C methods will always return nil, and will throw an 24 | exception when passed anything other than nil. The C method will throw 25 | an exception if given a new path which is nil or not valid for the C 26 | scheme. 27 | 28 | The following additional methods are supported: 29 | 30 | =over 31 | 32 | =item uri:data_bytes(...) 33 | 34 | Get or set the data stored in the URI. The existing data is decoded and 35 | returned. If a new value is supplied it must be a string, and will cause 36 | the path of the URI to be changed to encode the new data. The method will 37 | choose the encoding which will result in the smallest URI, unless the 38 | datafilter module is not installed, in which case it will always use 39 | percent encoding. 40 | 41 | An exception is thrown if the datafilter module is not installed and the data 42 | in the URI is encoded as base64, although a data URI using percent encoding 43 | will not cause an exception. 44 | 45 | The data passed in and returned should not be encoded in any special way, 46 | that is taken care of by the library. 47 | 48 | =item uri:data_media_type(...) 49 | 50 | Get or set the media type (MIME type) stored in the URI's path before the 51 | comma. This should not include the C<;base64> parameter, which will be 52 | included in the path automatically when appropriate. 53 | 54 | If there is no media type given in the URI then the default value of 55 | C will be returned, and if there is no C parameter 56 | given then the default C<;charset=US-ASCII> will be included. 57 | 58 | The media type is encoded and decoded automatically by this method. 59 | 60 | =back 61 | 62 | =head1 References 63 | 64 | This class is based on L. 65 | 66 | =for comment 67 | vi:ts=4 sw=4 expandtab 68 | -------------------------------------------------------------------------------- /doc/lua-uri-file.pod: -------------------------------------------------------------------------------- 1 | =head1 Name 2 | 3 | lua-uri-file - File URI support for Lua URI library 4 | 5 | =head1 Description 6 | 7 | The class C is used for URIs with the C scheme. It inherits 8 | from the L class. 9 | 10 | A file URI without an authority doesn't have a well defined meaning. This 11 | library considers such URIs to be invalid when they have a path which does not 12 | start with '/' (for example C). It is likely that any such URI 13 | should really be a relative URI reference. If the path does start with a slash 14 | then this library will attempt to 'repair' the URI by adding an empty authority 15 | part, so that C will be changed automatically to 16 | C. 17 | 18 | A host value of C is normalized to an empty host, so that 19 | C will become C. An empty path is 20 | normalized to '/'. 21 | 22 | The path part is always considered to be case sensitive, so no case folding 23 | is done even when converting to a filesystem path for Windows. 24 | 25 | Query parts and fragments are left alone by this library, but are not used 26 | in converting URIs to filesystem paths. 27 | 28 | =head1 Converting between URIs and filesystem paths 29 | 30 | A C object can be converted into an absolute path suitable for 31 | use on a particular operating system by calling the C 32 | method: 33 | 34 | =for syntax-highlight lua 35 | 36 | local uri = assert(URI:new("file:///foo/bar")) 37 | print(uri:filesystem_path("unix")) -- /foo/bar 38 | print(uri:filesystem_path("win32")) -- \foo\bar 39 | 40 | This method will throw an exception if the path cannot be converted. 41 | For example, a file URI containing a host name cannot be represented on 42 | a Unix filesystem, but on a Win32 system it will be converted to a UNC path: 43 | 44 | =for syntax-highlight lua 45 | 46 | local uri = assert(URI:new("file://server/path")) 47 | print(uri:filesystem_path("unix")) -- error 48 | print(uri:filesystem_path("win32")) -- \\server\path 49 | 50 | To convert a filesystem path into a URI, call the class method 51 | C: 52 | 53 | =for syntax-highlight lua 54 | 55 | local FileURI = require "uri.file" 56 | local uri = FileURI.make_file_uri("/foo/bar", "unix") 57 | print(uri) -- file:///foo/bar 58 | uri = FileURI.make_file_uri("C:\foo\bar", "win32") 59 | print(uri) -- file:///C:/foo/bar 60 | 61 | To convert a relative URI reference (a L 62 | object) into a filesystem path you should first resolve it against an 63 | appropriate C URI, and then call the C method on that. 64 | 65 | =head1 Methods 66 | 67 | All the methods defined in L are supported. The C, 68 | and C methods will always return nil, and will throw an 69 | exception when passed anything other than nil. The C method will 70 | normalize C to an empty host name, and will throw an exception if 71 | given a new value of nil. The C method will normalize an empty path 72 | or nil value to '/'. 73 | 74 | In addition to the standard methods, file URIs support the C 75 | method, and the C class contains the C function, 76 | both of which are described above. 77 | 78 | =head1 Operating systems supported 79 | 80 | The conversion between a file URI and a path suitable for use on a particular 81 | operating system are defined in additional classes, which are loaded 82 | automatically based on the operating system name supplied to the two conversion 83 | functions. For example, passing the string C to the functions will 84 | invoke the implementation in the class C. An exception will be 85 | thrown if no class exists to support a given operating system. The following 86 | operating system classes are provided: 87 | 88 | =over 89 | 90 | =item C 91 | 92 | A URI containing a host name will cause an exception to be thrown, as there 93 | is no obvious way for these to be represented in Unix paths. If the path 94 | contains an encoded null byte (C<%00>) or encoded slash (C<%2F>) then an 95 | exception will be thrown. 96 | 97 | Attempting to convert a relative path to a URI will cause an exception. 98 | 99 | =item C 100 | 101 | Forward slashes ('/') in URIs will be converted to backslashes ('\') in 102 | paths, and vice versa. 103 | 104 | URIs containing host names will be converted to UNC paths, starting with 105 | a '\\' followed by the hostname and then the path part. If the path part 106 | of a URI appears to begin with a drive letter, then the first slash will 107 | be removed so that the resulting path starts with the letter. Encoded 108 | pipe characters ('%7C') will be recognized as equivalent to colons for the 109 | purpose of identifying drive letters, since they have been historically 110 | used in that way, but I believe they are not allowed to occur in the path 111 | unencoded in a URI nowadays. 112 | 113 | =back 114 | 115 | The operating system names are case insensitive, and are folded to lowercase 116 | before being converted into a Lua module name. 117 | 118 | Currently there is no way for this library to recognise the operating system it 119 | is running on, since Lua has no built-in way of providing that information. 120 | 121 | =head1 References 122 | 123 | The most up to date IETF standard for the C URI scheme is still 124 | L, but this does not specify exactly how to convert 125 | between URIs and filesystem paths on particular platforms. It does however 126 | specify the equivalence between 'localhost' and an empty host. 127 | 128 | The correct form of file URI to represent a Windows filesystem path is 129 | described in a blog article: 130 | L 131 | 132 | There is a standard of sorts describing the conversion between Unix paths 133 | and file URIs: 134 | L 135 | 136 | =for comment 137 | vi:ts=4 sw=4 expandtab 138 | -------------------------------------------------------------------------------- /doc/lua-uri-ftp.3: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 2 | .\" 3 | .\" Standard preamble: 4 | .\" ======================================================================== 5 | .de Sh \" Subsection heading 6 | .br 7 | .if t .Sp 8 | .ne 5 9 | .PP 10 | \fB\\$1\fR 11 | .PP 12 | .. 13 | .de Sp \" Vertical space (when we can't use .PP) 14 | .if t .sp .5v 15 | .if n .sp 16 | .. 17 | .de Vb \" Begin verbatim text 18 | .ft CW 19 | .nf 20 | .ne \\$1 21 | .. 22 | .de Ve \" End verbatim text 23 | .ft R 24 | .fi 25 | .. 26 | .\" Set up some character translations and predefined strings. \*(-- will 27 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left 28 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will 29 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and 30 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, 31 | .\" nothing in troff, for use with C<>. 32 | .tr \(*W- 33 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' 34 | .ie n \{\ 35 | . ds -- \(*W- 36 | . ds PI pi 37 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch 38 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch 39 | . ds L" "" 40 | . ds R" "" 41 | . ds C` "" 42 | . ds C' "" 43 | 'br\} 44 | .el\{\ 45 | . ds -- \|\(em\| 46 | . ds PI \(*p 47 | . ds L" `` 48 | . ds R" '' 49 | 'br\} 50 | .\" 51 | .\" If the F register is turned on, we'll generate index entries on stderr for 52 | .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index 53 | .\" entries marked with X<> in POD. Of course, you'll have to process the 54 | .\" output yourself in some meaningful fashion. 55 | .if \nF \{\ 56 | . de IX 57 | . tm Index:\\$1\t\\n%\t"\\$2" 58 | .. 59 | . nr % 0 60 | . rr F 61 | .\} 62 | .\" 63 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes 64 | .\" way too many mistakes in technical documents. 65 | .hy 0 66 | .if n .na 67 | .\" 68 | .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). 69 | .\" Fear. Run. Save yourself. No user-serviceable parts. 70 | . \" fudge factors for nroff and troff 71 | .if n \{\ 72 | . ds #H 0 73 | . ds #V .8m 74 | . ds #F .3m 75 | . ds #[ \f1 76 | . ds #] \fP 77 | .\} 78 | .if t \{\ 79 | . ds #H ((1u-(\\\\n(.fu%2u))*.13m) 80 | . ds #V .6m 81 | . ds #F 0 82 | . ds #[ \& 83 | . ds #] \& 84 | .\} 85 | . \" simple accents for nroff and troff 86 | .if n \{\ 87 | . ds ' \& 88 | . ds ` \& 89 | . ds ^ \& 90 | . ds , \& 91 | . ds ~ ~ 92 | . ds / 93 | .\} 94 | .if t \{\ 95 | . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" 96 | . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' 97 | . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' 98 | . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' 99 | . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' 100 | . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' 101 | .\} 102 | . \" troff and (daisy-wheel) nroff accents 103 | .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' 104 | .ds 8 \h'\*(#H'\(*b\h'-\*(#H' 105 | .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] 106 | .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' 107 | .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' 108 | .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] 109 | .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] 110 | .ds ae a\h'-(\w'a'u*4/10)'e 111 | .ds Ae A\h'-(\w'A'u*4/10)'E 112 | . \" corrections for vroff 113 | .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' 114 | .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' 115 | . \" for low resolution devices (crt and lpr) 116 | .if \n(.H>23 .if \n(.V>19 \ 117 | \{\ 118 | . ds : e 119 | . ds 8 ss 120 | . ds o a 121 | . ds d- d\h'-1'\(ga 122 | . ds D- D\h'-1'\(hy 123 | . ds th \o'bp' 124 | . ds Th \o'LP' 125 | . ds ae ae 126 | . ds Ae AE 127 | .\} 128 | .rm #[ #] #H #V #F C 129 | .\" ======================================================================== 130 | .\" 131 | .IX Title "LUA-URI-FTP 3" 132 | .TH LUA-URI-FTP 3 "2007-11-02" "1.0" "Lua uri.ftp module" 133 | .SH "Name" 134 | .IX Header "Name" 135 | lua-uri-ftp \- \s-1FTP\s0 \s-1URI\s0 support for Lua \s-1URI\s0 library 136 | .SH "Description" 137 | .IX Header "Description" 138 | The class \f(CW\*(C`uri.ftp\*(C'\fR is used for URIs with the \f(CW\*(C`ftp\*(C'\fR scheme. It inherits from 139 | the uri._login class. 140 | .PP 141 | \&\s-1FTP\s0 URIs with a missing authority part or an empty host part are considered 142 | to be invalid. An empty path is always normalized to '/'. The default port 143 | is\ 21. 144 | .SH "Methods" 145 | .IX Header "Methods" 146 | All the methods defined in \fIlua\-uri\fR\|(3) and \fIlua\-uri\-_login\fR\|(3) are 147 | supported, in addition to the following: 148 | .IP "uri:ftp_typecode(...)" 4 149 | .IX Item "uri:ftp_typecode(...)" 150 | Mutator for the 'type' parameter at the end of the path. If the optional 151 | argument is supplied then a new type is set, replacing the existing one, or 152 | causing the type parameter to be added to the path if it isn't there already. 153 | .Sp 154 | .Vb 3 155 | \& local uri = assert(URI:new("ftp://host/path")) 156 | \& uri:ftp_typecode("a") \-\- ftp://host/path;type=a 157 | \& uri:ftp_typecode(nil) \-\- ftp://host/path 158 | .Ve 159 | .Sp 160 | Passing in an empty string has the same effect as nil, removing the parameter. 161 | An empty type parameter will be returned as nil, the same as if the parameter 162 | was missing. 163 | .SH "References" 164 | .IX Header "References" 165 | This class is based on \*(L"\s-1RFC\s0 1738 section 3.2\*(R". Unfortunately there isn't 166 | currently an \s-1RFC\s0 for \s-1FTP\s0 URIs based on the more up to date \*(L"\s-1RFC\s0 3986\*(R". 167 | -------------------------------------------------------------------------------- /doc/lua-uri-ftp.pod: -------------------------------------------------------------------------------- 1 | =head1 Name 2 | 3 | lua-uri-ftp - FTP URI support for Lua URI library 4 | 5 | =head1 Description 6 | 7 | The class C is used for URIs with the C scheme. It inherits from 8 | the L class. 9 | 10 | FTP URIs with a missing authority part or an empty host part are considered 11 | to be invalid. An empty path is always normalized to '/'. The default port 12 | S. 13 | 14 | =head1 Methods 15 | 16 | All the methods defined in L and L are 17 | supported, in addition to the following: 18 | 19 | =over 20 | 21 | =item uri:ftp_typecode(...) 22 | 23 | Mutator for the 'type' parameter at the end of the path. If the optional 24 | argument is supplied then a new type is set, replacing the existing one, or 25 | causing the type parameter to be added to the path if it isn't there already. 26 | 27 | =for syntax-highlight lua 28 | 29 | local uri = assert(URI:new("ftp://host/path")) 30 | uri:ftp_typecode("a") -- ftp://host/path;type=a 31 | uri:ftp_typecode(nil) -- ftp://host/path 32 | 33 | Passing in an empty string has the same effect as nil, removing the parameter. 34 | An empty type parameter will be returned as nil, the same as if the parameter 35 | was missing. 36 | 37 | =back 38 | 39 | =head1 References 40 | 41 | This class is based on L. Unfortunately there isn't 42 | currently an RFC for FTP URIs based on the more up to date L. 43 | 44 | =for comment 45 | vi:ts=4 sw=4 expandtab 46 | -------------------------------------------------------------------------------- /doc/lua-uri-http.3: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 2 | .\" 3 | .\" Standard preamble: 4 | .\" ======================================================================== 5 | .de Sh \" Subsection heading 6 | .br 7 | .if t .Sp 8 | .ne 5 9 | .PP 10 | \fB\\$1\fR 11 | .PP 12 | .. 13 | .de Sp \" Vertical space (when we can't use .PP) 14 | .if t .sp .5v 15 | .if n .sp 16 | .. 17 | .de Vb \" Begin verbatim text 18 | .ft CW 19 | .nf 20 | .ne \\$1 21 | .. 22 | .de Ve \" End verbatim text 23 | .ft R 24 | .fi 25 | .. 26 | .\" Set up some character translations and predefined strings. \*(-- will 27 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left 28 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will 29 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and 30 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, 31 | .\" nothing in troff, for use with C<>. 32 | .tr \(*W- 33 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' 34 | .ie n \{\ 35 | . ds -- \(*W- 36 | . ds PI pi 37 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch 38 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch 39 | . ds L" "" 40 | . ds R" "" 41 | . ds C` "" 42 | . ds C' "" 43 | 'br\} 44 | .el\{\ 45 | . ds -- \|\(em\| 46 | . ds PI \(*p 47 | . ds L" `` 48 | . ds R" '' 49 | 'br\} 50 | .\" 51 | .\" If the F register is turned on, we'll generate index entries on stderr for 52 | .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index 53 | .\" entries marked with X<> in POD. Of course, you'll have to process the 54 | .\" output yourself in some meaningful fashion. 55 | .if \nF \{\ 56 | . de IX 57 | . tm Index:\\$1\t\\n%\t"\\$2" 58 | .. 59 | . nr % 0 60 | . rr F 61 | .\} 62 | .\" 63 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes 64 | .\" way too many mistakes in technical documents. 65 | .hy 0 66 | .if n .na 67 | .\" 68 | .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). 69 | .\" Fear. Run. Save yourself. No user-serviceable parts. 70 | . \" fudge factors for nroff and troff 71 | .if n \{\ 72 | . ds #H 0 73 | . ds #V .8m 74 | . ds #F .3m 75 | . ds #[ \f1 76 | . ds #] \fP 77 | .\} 78 | .if t \{\ 79 | . ds #H ((1u-(\\\\n(.fu%2u))*.13m) 80 | . ds #V .6m 81 | . ds #F 0 82 | . ds #[ \& 83 | . ds #] \& 84 | .\} 85 | . \" simple accents for nroff and troff 86 | .if n \{\ 87 | . ds ' \& 88 | . ds ` \& 89 | . ds ^ \& 90 | . ds , \& 91 | . ds ~ ~ 92 | . ds / 93 | .\} 94 | .if t \{\ 95 | . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" 96 | . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' 97 | . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' 98 | . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' 99 | . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' 100 | . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' 101 | .\} 102 | . \" troff and (daisy-wheel) nroff accents 103 | .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' 104 | .ds 8 \h'\*(#H'\(*b\h'-\*(#H' 105 | .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] 106 | .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' 107 | .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' 108 | .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] 109 | .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] 110 | .ds ae a\h'-(\w'a'u*4/10)'e 111 | .ds Ae A\h'-(\w'A'u*4/10)'E 112 | . \" corrections for vroff 113 | .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' 114 | .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' 115 | . \" for low resolution devices (crt and lpr) 116 | .if \n(.H>23 .if \n(.V>19 \ 117 | \{\ 118 | . ds : e 119 | . ds 8 ss 120 | . ds o a 121 | . ds d- d\h'-1'\(ga 122 | . ds D- D\h'-1'\(hy 123 | . ds th \o'bp' 124 | . ds Th \o'LP' 125 | . ds ae ae 126 | . ds Ae AE 127 | .\} 128 | .rm #[ #] #H #V #F C 129 | .\" ======================================================================== 130 | .\" 131 | .IX Title "LUA-URI-HTTP 3" 132 | .TH LUA-URI-HTTP 3 "2007-11-02" "1.0" "Lua uri.http module" 133 | .SH "Name" 134 | .IX Header "Name" 135 | lua-uri-http \- \s-1HTTP\s0 \s-1URI\s0 support for Lua \s-1URI\s0 library 136 | .SH "Description" 137 | .IX Header "Description" 138 | The classes \f(CW\*(C`uri.http\*(C'\fR and \f(CW\*(C`uri.https\*(C'\fR are used for URIs with the \f(CW\*(C`http\*(C'\fR and 139 | \&\f(CW\*(C`https\*(C'\fR schemes respectively. \f(CW\*(C`uri.http\*(C'\fR inherits from the generic 140 | uri class, and \f(CW\*(C`uri.https\*(C'\fR inherits from \f(CW\*(C`uri.http\*(C'\fR. 141 | .PP 142 | An \s-1HTTP\s0 or \s-1HTTPS\s0 \s-1URI\s0 containing any userinfo part is considered to be 143 | invalid. An empty path is normalized to '/', since browsers usually do 144 | that, and an empty path cannot be used in an \s-1HTTP\s0 \s-1GET\s0 request. 145 | .PP 146 | The default port for the \f(CW\*(C`http\*(C'\fR scheme is\ 80, and for \f(CW\*(C`https\*(C'\fR 147 | is\ 443. 148 | .PP 149 | There are no extra methods defined for telnet URIs, only those described in 150 | \&\fIlua\-uri\fR\|(3). 151 | .SH "References" 152 | .IX Header "References" 153 | As far as I can tell there is no up to date specification of the syntax of 154 | \&\s-1HTTP\s0 URIs, so this class is based on \*(L"\s-1RFC\s0 1738 section 3.3\*(R" and 155 | \&\*(L"\s-1RFC\s0 2616 section 3.2.2\*(R". 156 | -------------------------------------------------------------------------------- /doc/lua-uri-http.pod: -------------------------------------------------------------------------------- 1 | =head1 Name 2 | 3 | lua-uri-http - HTTP URI support for Lua URI library 4 | 5 | =head1 Description 6 | 7 | The classes C and C are used for URIs with the C and 8 | C schemes respectively. C inherits from the generic 9 | L class, and C inherits from C. 10 | 11 | An HTTP or HTTPS URI containing any userinfo part is considered to be 12 | invalid. An empty path is normalized to '/', since browsers usually do 13 | that, and an empty path cannot be used in an HTTP GET request. 14 | 15 | The default port for the C scheme S, and for C 16 | S. 17 | 18 | There are no extra methods defined for telnet URIs, only those described in 19 | L. 20 | 21 | =head1 References 22 | 23 | As far as I can tell there is no up to date specification of the syntax of 24 | HTTP URIs, so this class is based on L and 25 | L. 26 | 27 | =for comment 28 | vi:ts=4 sw=4 expandtab 29 | -------------------------------------------------------------------------------- /doc/lua-uri-pop.3: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 2 | .\" 3 | .\" Standard preamble: 4 | .\" ======================================================================== 5 | .de Sh \" Subsection heading 6 | .br 7 | .if t .Sp 8 | .ne 5 9 | .PP 10 | \fB\\$1\fR 11 | .PP 12 | .. 13 | .de Sp \" Vertical space (when we can't use .PP) 14 | .if t .sp .5v 15 | .if n .sp 16 | .. 17 | .de Vb \" Begin verbatim text 18 | .ft CW 19 | .nf 20 | .ne \\$1 21 | .. 22 | .de Ve \" End verbatim text 23 | .ft R 24 | .fi 25 | .. 26 | .\" Set up some character translations and predefined strings. \*(-- will 27 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left 28 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will 29 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and 30 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, 31 | .\" nothing in troff, for use with C<>. 32 | .tr \(*W- 33 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' 34 | .ie n \{\ 35 | . ds -- \(*W- 36 | . ds PI pi 37 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch 38 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch 39 | . ds L" "" 40 | . ds R" "" 41 | . ds C` "" 42 | . ds C' "" 43 | 'br\} 44 | .el\{\ 45 | . ds -- \|\(em\| 46 | . ds PI \(*p 47 | . ds L" `` 48 | . ds R" '' 49 | 'br\} 50 | .\" 51 | .\" If the F register is turned on, we'll generate index entries on stderr for 52 | .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index 53 | .\" entries marked with X<> in POD. Of course, you'll have to process the 54 | .\" output yourself in some meaningful fashion. 55 | .if \nF \{\ 56 | . de IX 57 | . tm Index:\\$1\t\\n%\t"\\$2" 58 | .. 59 | . nr % 0 60 | . rr F 61 | .\} 62 | .\" 63 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes 64 | .\" way too many mistakes in technical documents. 65 | .hy 0 66 | .if n .na 67 | .\" 68 | .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). 69 | .\" Fear. Run. Save yourself. No user-serviceable parts. 70 | . \" fudge factors for nroff and troff 71 | .if n \{\ 72 | . ds #H 0 73 | . ds #V .8m 74 | . ds #F .3m 75 | . ds #[ \f1 76 | . ds #] \fP 77 | .\} 78 | .if t \{\ 79 | . ds #H ((1u-(\\\\n(.fu%2u))*.13m) 80 | . ds #V .6m 81 | . ds #F 0 82 | . ds #[ \& 83 | . ds #] \& 84 | .\} 85 | . \" simple accents for nroff and troff 86 | .if n \{\ 87 | . ds ' \& 88 | . ds ` \& 89 | . ds ^ \& 90 | . ds , \& 91 | . ds ~ ~ 92 | . ds / 93 | .\} 94 | .if t \{\ 95 | . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" 96 | . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' 97 | . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' 98 | . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' 99 | . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' 100 | . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' 101 | .\} 102 | . \" troff and (daisy-wheel) nroff accents 103 | .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' 104 | .ds 8 \h'\*(#H'\(*b\h'-\*(#H' 105 | .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] 106 | .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' 107 | .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' 108 | .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] 109 | .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] 110 | .ds ae a\h'-(\w'a'u*4/10)'e 111 | .ds Ae A\h'-(\w'A'u*4/10)'E 112 | . \" corrections for vroff 113 | .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' 114 | .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' 115 | . \" for low resolution devices (crt and lpr) 116 | .if \n(.H>23 .if \n(.V>19 \ 117 | \{\ 118 | . ds : e 119 | . ds 8 ss 120 | . ds o a 121 | . ds d- d\h'-1'\(ga 122 | . ds D- D\h'-1'\(hy 123 | . ds th \o'bp' 124 | . ds Th \o'LP' 125 | . ds ae ae 126 | . ds Ae AE 127 | .\} 128 | .rm #[ #] #H #V #F C 129 | .\" ======================================================================== 130 | .\" 131 | .IX Title "LUA-URI-POP 3" 132 | .TH LUA-URI-POP 3 "2007-11-02" "1.0" "Lua uri.pop module" 133 | .SH "Name" 134 | .IX Header "Name" 135 | lua-uri-pop \- \s-1POP\s0 \s-1URI\s0 support for Lua \s-1URI\s0 library 136 | .SH "Description" 137 | .IX Header "Description" 138 | The class \f(CW\*(C`uri.pop\*(C'\fR is used for URIs with the \f(CW\*(C`pop\*(C'\fR scheme. It inherits 139 | from the uri class. 140 | .PP 141 | \&\s-1POP\s0 URIs with a non-empty path part are considered invalid. There are also 142 | invalid if there is a userinfo part which has an empty \s-1POP\s0 username or an 143 | empty \s-1POP\s0 'auth' type. 144 | .PP 145 | The ';auth=' part of a \s-1POP\s0 \s-1URI\s0 is normalized so that the word 'auth' is in 146 | lowercase, and if the auth type is the default '*' value then it is removed 147 | altogether, leaving just the username. 148 | .PP 149 | The default port is\ 110. 150 | .SH "Methods" 151 | .IX Header "Methods" 152 | All the methods defined in \fIlua\-uri\fR\|(3) are supported. The \f(CW\*(C`userinfo\*(C'\fR 153 | method will throw an exception if the new userinfo would form an invalid 154 | \&\s-1POP\s0 \s-1URI\s0, and will normalize the auth type part if appropriate. The \f(CW\*(C`path\*(C'\fR 155 | method will always return empty strings for \s-1POP\s0 URIs, and will throw an 156 | exception if given a new value which is not the empty string. 157 | .PP 158 | The following additional methods are provided: 159 | .IP "uri:pop_user(...)" 4 160 | .IX Item "uri:pop_user(...)" 161 | Get or set the \s-1POP\s0 username, which is stored in the userinfo part of the 162 | authority. 163 | .Sp 164 | The return value will be nil if there is no user information in the \s-1URI\s0, 165 | or a fully decoded string if there is. 166 | .Sp 167 | If the new value is empty, and exception is thrown. The user can be set to 168 | nil to remove the userinfo part from the \s-1URI\s0, but this will also throw an 169 | exception if there is an 'auth' type specified. 170 | .IP "uri:pop_auth(...)" 4 171 | .IX Item "uri:pop_auth(...)" 172 | Get or set the \s-1POP\s0 authentication type, which is stored in the userinfo 173 | part of the authority after the string ';auth='. 174 | .Sp 175 | The value returned is just the auth type, not the ';auth=' part, and will be 176 | fully decoded. The value returned will never be nil. If there is no auth type 177 | specified then the default value of '*' will be returned. 178 | .Sp 179 | Setting a new value of nil or the empty string will cause an exception 180 | to be thrown. 181 | .SH "References" 182 | .IX Header "References" 183 | This class is based on \*(L"\s-1RFC\s0 2384\*(R". 184 | -------------------------------------------------------------------------------- /doc/lua-uri-pop.pod: -------------------------------------------------------------------------------- 1 | =head1 Name 2 | 3 | lua-uri-pop - POP URI support for Lua URI library 4 | 5 | =head1 Description 6 | 7 | The class C is used for URIs with the C scheme. It inherits 8 | from the L class. 9 | 10 | POP URIs with a non-empty path part are considered invalid. There are also 11 | invalid if there is a userinfo part which has an empty POP username or an 12 | empty POP 'auth' type. 13 | 14 | The ';auth=' part of a POP URI is normalized so that the word 'auth' is in 15 | lowercase, and if the auth type is the default '*' value then it is removed 16 | altogether, leaving just the username. 17 | 18 | The default port S. 19 | 20 | =head1 Methods 21 | 22 | All the methods defined in L are supported. The C 23 | method will throw an exception if the new userinfo would form an invalid 24 | POP URI, and will normalize the auth type part if appropriate. The C 25 | method will always return empty strings for POP URIs, and will throw an 26 | exception if given a new value which is not the empty string. 27 | 28 | The following additional methods are provided: 29 | 30 | =over 31 | 32 | =item uri:pop_user(...) 33 | 34 | Get or set the POP username, which is stored in the userinfo part of the 35 | authority. 36 | 37 | The return value will be nil if there is no user information in the URI, 38 | or a fully decoded string if there is. 39 | 40 | If the new value is empty, and exception is thrown. The user can be set to 41 | nil to remove the userinfo part from the URI, but this will also throw an 42 | exception if there is an 'auth' type specified. 43 | 44 | =item uri:pop_auth(...) 45 | 46 | Get or set the POP authentication type, which is stored in the userinfo 47 | part of the authority after the string ';auth='. 48 | 49 | The value returned is just the auth type, not the ';auth=' part, and will be 50 | fully decoded. The value returned will never be nil. If there is no auth type 51 | specified then the default value of '*' will be returned. 52 | 53 | Setting a new value of nil or the empty string will cause an exception 54 | to be thrown. 55 | 56 | =back 57 | 58 | =head1 References 59 | 60 | This class is based on L. 61 | 62 | =for comment 63 | vi:ts=4 sw=4 expandtab 64 | -------------------------------------------------------------------------------- /doc/lua-uri-rtsp.3: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 2 | .\" 3 | .\" Standard preamble: 4 | .\" ======================================================================== 5 | .de Sh \" Subsection heading 6 | .br 7 | .if t .Sp 8 | .ne 5 9 | .PP 10 | \fB\\$1\fR 11 | .PP 12 | .. 13 | .de Sp \" Vertical space (when we can't use .PP) 14 | .if t .sp .5v 15 | .if n .sp 16 | .. 17 | .de Vb \" Begin verbatim text 18 | .ft CW 19 | .nf 20 | .ne \\$1 21 | .. 22 | .de Ve \" End verbatim text 23 | .ft R 24 | .fi 25 | .. 26 | .\" Set up some character translations and predefined strings. \*(-- will 27 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left 28 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will 29 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and 30 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, 31 | .\" nothing in troff, for use with C<>. 32 | .tr \(*W- 33 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' 34 | .ie n \{\ 35 | . ds -- \(*W- 36 | . ds PI pi 37 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch 38 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch 39 | . ds L" "" 40 | . ds R" "" 41 | . ds C` "" 42 | . ds C' "" 43 | 'br\} 44 | .el\{\ 45 | . ds -- \|\(em\| 46 | . ds PI \(*p 47 | . ds L" `` 48 | . ds R" '' 49 | 'br\} 50 | .\" 51 | .\" If the F register is turned on, we'll generate index entries on stderr for 52 | .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index 53 | .\" entries marked with X<> in POD. Of course, you'll have to process the 54 | .\" output yourself in some meaningful fashion. 55 | .if \nF \{\ 56 | . de IX 57 | . tm Index:\\$1\t\\n%\t"\\$2" 58 | .. 59 | . nr % 0 60 | . rr F 61 | .\} 62 | .\" 63 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes 64 | .\" way too many mistakes in technical documents. 65 | .hy 0 66 | .if n .na 67 | .\" 68 | .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). 69 | .\" Fear. Run. Save yourself. No user-serviceable parts. 70 | . \" fudge factors for nroff and troff 71 | .if n \{\ 72 | . ds #H 0 73 | . ds #V .8m 74 | . ds #F .3m 75 | . ds #[ \f1 76 | . ds #] \fP 77 | .\} 78 | .if t \{\ 79 | . ds #H ((1u-(\\\\n(.fu%2u))*.13m) 80 | . ds #V .6m 81 | . ds #F 0 82 | . ds #[ \& 83 | . ds #] \& 84 | .\} 85 | . \" simple accents for nroff and troff 86 | .if n \{\ 87 | . ds ' \& 88 | . ds ` \& 89 | . ds ^ \& 90 | . ds , \& 91 | . ds ~ ~ 92 | . ds / 93 | .\} 94 | .if t \{\ 95 | . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" 96 | . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' 97 | . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' 98 | . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' 99 | . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' 100 | . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' 101 | .\} 102 | . \" troff and (daisy-wheel) nroff accents 103 | .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' 104 | .ds 8 \h'\*(#H'\(*b\h'-\*(#H' 105 | .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] 106 | .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' 107 | .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' 108 | .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] 109 | .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] 110 | .ds ae a\h'-(\w'a'u*4/10)'e 111 | .ds Ae A\h'-(\w'A'u*4/10)'E 112 | . \" corrections for vroff 113 | .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' 114 | .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' 115 | . \" for low resolution devices (crt and lpr) 116 | .if \n(.H>23 .if \n(.V>19 \ 117 | \{\ 118 | . ds : e 119 | . ds 8 ss 120 | . ds o a 121 | . ds d- d\h'-1'\(ga 122 | . ds D- D\h'-1'\(hy 123 | . ds th \o'bp' 124 | . ds Th \o'LP' 125 | . ds ae ae 126 | . ds Ae AE 127 | .\} 128 | .rm #[ #] #H #V #F C 129 | .\" ======================================================================== 130 | .\" 131 | .IX Title "LUA-URI-RTSP 3" 132 | .TH LUA-URI-RTSP 3 "2007-11-02" "1.0" "Lua uri.rtsp module" 133 | .SH "Name" 134 | .IX Header "Name" 135 | lua-uri-rtsp \- \s-1RTSP\s0 \s-1URI\s0 support for Lua \s-1URI\s0 library 136 | .SH "Description" 137 | .IX Header "Description" 138 | The classes \f(CW\*(C`uri.rtsp\*(C'\fR and \f(CW\*(C`uri.rtspu\*(C'\fR are used for URIs with the \f(CW\*(C`rtsp\*(C'\fR and 139 | \&\f(CW\*(C`rtspu\*(C'\fR schemes respectively. \f(CW\*(C`uri.rtsp\*(C'\fR inherits from the 140 | uri.http class, and \f(CW\*(C`uri.rtspu\*(C'\fR inherits from \f(CW\*(C`uri.rtsp\*(C'\fR. 141 | .PP 142 | There is no special validation or normalization applied to these URIs beyond 143 | that done for \s-1HTTP\s0 URIs. 144 | .PP 145 | The default port for both schemes is\ 554. 146 | .PP 147 | There are no extra methods defined for telnet URIs, only those described in 148 | \&\fIlua\-uri\fR\|(3). 149 | .SH "References" 150 | .IX Header "References" 151 | This class is based on \*(L"\s-1RFC\s0 2326 section 3.2\*(R". 152 | -------------------------------------------------------------------------------- /doc/lua-uri-rtsp.pod: -------------------------------------------------------------------------------- 1 | =head1 Name 2 | 3 | lua-uri-rtsp - RTSP URI support for Lua URI library 4 | 5 | =head1 Description 6 | 7 | The classes C and C are used for URIs with the C and 8 | C schemes respectively. C inherits from the 9 | L class, and C inherits from C. 10 | 11 | There is no special validation or normalization applied to these URIs beyond 12 | that done for HTTP URIs. 13 | 14 | The default port for both schemes S. 15 | 16 | There are no extra methods defined for telnet URIs, only those described in 17 | L. 18 | 19 | =head1 References 20 | 21 | This class is based on L. 22 | 23 | =for comment 24 | vi:ts=4 sw=4 expandtab 25 | -------------------------------------------------------------------------------- /doc/lua-uri-telnet.3: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 2 | .\" 3 | .\" Standard preamble: 4 | .\" ======================================================================== 5 | .de Sh \" Subsection heading 6 | .br 7 | .if t .Sp 8 | .ne 5 9 | .PP 10 | \fB\\$1\fR 11 | .PP 12 | .. 13 | .de Sp \" Vertical space (when we can't use .PP) 14 | .if t .sp .5v 15 | .if n .sp 16 | .. 17 | .de Vb \" Begin verbatim text 18 | .ft CW 19 | .nf 20 | .ne \\$1 21 | .. 22 | .de Ve \" End verbatim text 23 | .ft R 24 | .fi 25 | .. 26 | .\" Set up some character translations and predefined strings. \*(-- will 27 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left 28 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will 29 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and 30 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, 31 | .\" nothing in troff, for use with C<>. 32 | .tr \(*W- 33 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' 34 | .ie n \{\ 35 | . ds -- \(*W- 36 | . ds PI pi 37 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch 38 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch 39 | . ds L" "" 40 | . ds R" "" 41 | . ds C` "" 42 | . ds C' "" 43 | 'br\} 44 | .el\{\ 45 | . ds -- \|\(em\| 46 | . ds PI \(*p 47 | . ds L" `` 48 | . ds R" '' 49 | 'br\} 50 | .\" 51 | .\" If the F register is turned on, we'll generate index entries on stderr for 52 | .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index 53 | .\" entries marked with X<> in POD. Of course, you'll have to process the 54 | .\" output yourself in some meaningful fashion. 55 | .if \nF \{\ 56 | . de IX 57 | . tm Index:\\$1\t\\n%\t"\\$2" 58 | .. 59 | . nr % 0 60 | . rr F 61 | .\} 62 | .\" 63 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes 64 | .\" way too many mistakes in technical documents. 65 | .hy 0 66 | .if n .na 67 | .\" 68 | .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). 69 | .\" Fear. Run. Save yourself. No user-serviceable parts. 70 | . \" fudge factors for nroff and troff 71 | .if n \{\ 72 | . ds #H 0 73 | . ds #V .8m 74 | . ds #F .3m 75 | . ds #[ \f1 76 | . ds #] \fP 77 | .\} 78 | .if t \{\ 79 | . ds #H ((1u-(\\\\n(.fu%2u))*.13m) 80 | . ds #V .6m 81 | . ds #F 0 82 | . ds #[ \& 83 | . ds #] \& 84 | .\} 85 | . \" simple accents for nroff and troff 86 | .if n \{\ 87 | . ds ' \& 88 | . ds ` \& 89 | . ds ^ \& 90 | . ds , \& 91 | . ds ~ ~ 92 | . ds / 93 | .\} 94 | .if t \{\ 95 | . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" 96 | . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' 97 | . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' 98 | . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' 99 | . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' 100 | . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' 101 | .\} 102 | . \" troff and (daisy-wheel) nroff accents 103 | .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' 104 | .ds 8 \h'\*(#H'\(*b\h'-\*(#H' 105 | .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] 106 | .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' 107 | .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' 108 | .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] 109 | .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] 110 | .ds ae a\h'-(\w'a'u*4/10)'e 111 | .ds Ae A\h'-(\w'A'u*4/10)'E 112 | . \" corrections for vroff 113 | .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' 114 | .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' 115 | . \" for low resolution devices (crt and lpr) 116 | .if \n(.H>23 .if \n(.V>19 \ 117 | \{\ 118 | . ds : e 119 | . ds 8 ss 120 | . ds o a 121 | . ds d- d\h'-1'\(ga 122 | . ds D- D\h'-1'\(hy 123 | . ds th \o'bp' 124 | . ds Th \o'LP' 125 | . ds ae ae 126 | . ds Ae AE 127 | .\} 128 | .rm #[ #] #H #V #F C 129 | .\" ======================================================================== 130 | .\" 131 | .IX Title "LUA-URI-TELNET 3" 132 | .TH LUA-URI-TELNET 3 "2007-11-02" "1.0" "Lua uri.telnet module" 133 | .SH "Name" 134 | .IX Header "Name" 135 | lua-uri-telnet \- Telnet \s-1URI\s0 support for Lua \s-1URI\s0 library 136 | .SH "Description" 137 | .IX Header "Description" 138 | The class \f(CW\*(C`uri.telnet\*(C'\fR is used for URIs with the \f(CW\*(C`telnet\*(C'\fR scheme. It 139 | inherits from the uri._login class. 140 | .PP 141 | Telnet URIs are not allowed to have any information in their path part, 142 | because there isn't any specification defining what it would mean. An empty 143 | path or a path of '/' is acceptable, and normalized to '/'. Any other path 144 | is considered invalid. 145 | .PP 146 | The default port for telnet URIs is\ 23. 147 | .PP 148 | There are no extra methods defined for telnet URIs, only those described in 149 | \&\fIlua\-uri\fR\|(3) and \fIlua\-uri\-_login\fR\|(3). 150 | .SH "References" 151 | .IX Header "References" 152 | This class is based on \*(L"\s-1RFC\s0 4248\*(R". 153 | -------------------------------------------------------------------------------- /doc/lua-uri-telnet.pod: -------------------------------------------------------------------------------- 1 | =head1 Name 2 | 3 | lua-uri-telnet - Telnet URI support for Lua URI library 4 | 5 | =head1 Description 6 | 7 | The class C is used for URIs with the C scheme. It 8 | inherits from the L class. 9 | 10 | Telnet URIs are not allowed to have any information in their path part, 11 | because there isn't any specification defining what it would mean. An empty 12 | path or a path of '/' is acceptable, and normalized to '/'. Any other path 13 | is considered invalid. 14 | 15 | The default port for telnet URIs S. 16 | 17 | There are no extra methods defined for telnet URIs, only those described in 18 | L and L. 19 | 20 | =head1 References 21 | 22 | This class is based on L. 23 | 24 | =for comment 25 | vi:ts=4 sw=4 expandtab 26 | -------------------------------------------------------------------------------- /doc/lua-uri-urn-isbn.3: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 2 | .\" 3 | .\" Standard preamble: 4 | .\" ======================================================================== 5 | .de Sh \" Subsection heading 6 | .br 7 | .if t .Sp 8 | .ne 5 9 | .PP 10 | \fB\\$1\fR 11 | .PP 12 | .. 13 | .de Sp \" Vertical space (when we can't use .PP) 14 | .if t .sp .5v 15 | .if n .sp 16 | .. 17 | .de Vb \" Begin verbatim text 18 | .ft CW 19 | .nf 20 | .ne \\$1 21 | .. 22 | .de Ve \" End verbatim text 23 | .ft R 24 | .fi 25 | .. 26 | .\" Set up some character translations and predefined strings. \*(-- will 27 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left 28 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will 29 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and 30 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, 31 | .\" nothing in troff, for use with C<>. 32 | .tr \(*W- 33 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' 34 | .ie n \{\ 35 | . ds -- \(*W- 36 | . ds PI pi 37 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch 38 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch 39 | . ds L" "" 40 | . ds R" "" 41 | . ds C` "" 42 | . ds C' "" 43 | 'br\} 44 | .el\{\ 45 | . ds -- \|\(em\| 46 | . ds PI \(*p 47 | . ds L" `` 48 | . ds R" '' 49 | 'br\} 50 | .\" 51 | .\" If the F register is turned on, we'll generate index entries on stderr for 52 | .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index 53 | .\" entries marked with X<> in POD. Of course, you'll have to process the 54 | .\" output yourself in some meaningful fashion. 55 | .if \nF \{\ 56 | . de IX 57 | . tm Index:\\$1\t\\n%\t"\\$2" 58 | .. 59 | . nr % 0 60 | . rr F 61 | .\} 62 | .\" 63 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes 64 | .\" way too many mistakes in technical documents. 65 | .hy 0 66 | .if n .na 67 | .\" 68 | .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). 69 | .\" Fear. Run. Save yourself. No user-serviceable parts. 70 | . \" fudge factors for nroff and troff 71 | .if n \{\ 72 | . ds #H 0 73 | . ds #V .8m 74 | . ds #F .3m 75 | . ds #[ \f1 76 | . ds #] \fP 77 | .\} 78 | .if t \{\ 79 | . ds #H ((1u-(\\\\n(.fu%2u))*.13m) 80 | . ds #V .6m 81 | . ds #F 0 82 | . ds #[ \& 83 | . ds #] \& 84 | .\} 85 | . \" simple accents for nroff and troff 86 | .if n \{\ 87 | . ds ' \& 88 | . ds ` \& 89 | . ds ^ \& 90 | . ds , \& 91 | . ds ~ ~ 92 | . ds / 93 | .\} 94 | .if t \{\ 95 | . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" 96 | . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' 97 | . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' 98 | . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' 99 | . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' 100 | . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' 101 | .\} 102 | . \" troff and (daisy-wheel) nroff accents 103 | .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' 104 | .ds 8 \h'\*(#H'\(*b\h'-\*(#H' 105 | .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] 106 | .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' 107 | .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' 108 | .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] 109 | .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] 110 | .ds ae a\h'-(\w'a'u*4/10)'e 111 | .ds Ae A\h'-(\w'A'u*4/10)'E 112 | . \" corrections for vroff 113 | .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' 114 | .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' 115 | . \" for low resolution devices (crt and lpr) 116 | .if \n(.H>23 .if \n(.V>19 \ 117 | \{\ 118 | . ds : e 119 | . ds 8 ss 120 | . ds o a 121 | . ds d- d\h'-1'\(ga 122 | . ds D- D\h'-1'\(hy 123 | . ds th \o'bp' 124 | . ds Th \o'LP' 125 | . ds ae ae 126 | . ds Ae AE 127 | .\} 128 | .rm #[ #] #H #V #F C 129 | .\" ======================================================================== 130 | .\" 131 | .IX Title "LUA-URI-URN-ISBN 3" 132 | .TH LUA-URI-URN-ISBN 3 "2007-11-02" "1.0" "Lua uri.urn.isbn module" 133 | .SH "Name" 134 | .IX Header "Name" 135 | lua-uri-urn-isbn \- \s-1ISBN\s0 \s-1URN\s0 support for Lua \s-1URI\s0 library 136 | .SH "Description" 137 | .IX Header "Description" 138 | The class \f(CW\*(C`uri.urn.isbn\*(C'\fR is used for URNs with the \s-1NID\s0 'isbn', that is, URIs 139 | which begin \f(CW\*(C`urn:isbn:\*(C'\fR. It inherits from the uri.urn 140 | class. 141 | .PP 142 | Some of the functionality of this class depends on the \fIlua\-isbn\fR\|(3) module 143 | being installed, although it can be used without that. In particular, if the 144 | module is installed then full checksum validation of the \s-1ISBN\s0 is performed, 145 | whereas without it the \s-1ISBN\s0 is only checked for invalid characters. The \s-1ISBN\s0 146 | value is normalized to include hyphens in the conventional places if the 147 | lua-isbn module is installed (the exact hyphen positions depend on the number), 148 | but without it all hyphens are removed instead. If the \s-1ISBN\s0 ends in a checksum 149 | of 'x', then it folded to uppercase. 150 | .SH "Methods" 151 | .IX Header "Methods" 152 | All the methods defined in \fIlua\-uri\fR\|(3) and \fIlua\-uri\-urn\fR\|(3) are supported, 153 | as well as the following: 154 | .IP "uri:isbn(...)" 4 155 | .IX Item "uri:isbn(...)" 156 | Get or set the \s-1ISBN\s0 value as an object of the type provided by the \f(CW\*(C`isbn\*(C'\fR 157 | class in the \fIlua\-isbn\fR\|(3) library. This method will throw an exception 158 | if this library is not installed, or if the object supplied is not a valid 159 | \&\s-1ISBN\s0 object (it will currently accept a string, but you shouldn't rely on 160 | this). 161 | .IP "uri:isbn_digits(...)" 4 162 | .IX Item "uri:isbn_digits(...)" 163 | Get or set the \s-1ISBN\s0 value as a string containing just the numbers (and 164 | possibly an 'X' as the last digit). There will be no hyphens in this value, 165 | and it should be exactly 10 or 13 characters long. 166 | .Sp 167 | If a new value is provided then it must not be nil, and will be validated in 168 | the normal way, causing an exception if it is invalid. 169 | .SH "References" 170 | .IX Header "References" 171 | This implements the 'isbn' \s-1NID\s0 defined in \*(L"\s-1RFC\s0 3187\*(R", and is consistent 172 | with the same \s-1NID\s0 suggested in \*(L"\s-1RFC\s0 2288\*(R". 173 | -------------------------------------------------------------------------------- /doc/lua-uri-urn-isbn.pod: -------------------------------------------------------------------------------- 1 | =head1 Name 2 | 3 | lua-uri-urn-isbn - ISBN URN support for Lua URI library 4 | 5 | =head1 Description 6 | 7 | The class C is used for URNs with the NID 'isbn', that is, URIs 8 | which begin C. It inherits from the L 9 | class. 10 | 11 | Some of the functionality of this class depends on the L module 12 | being installed, although it can be used without that. In particular, if the 13 | module is installed then full checksum validation of the ISBN is performed, 14 | whereas without it the ISBN is only checked for invalid characters. The ISBN 15 | value is normalized to include hyphens in the conventional places if the 16 | lua-isbn module is installed (the exact hyphen positions depend on the number), 17 | but without it all hyphens are removed instead. If the ISBN ends in a checksum 18 | of 'x', then it folded to uppercase. 19 | 20 | =head1 Methods 21 | 22 | All the methods defined in L and L are supported, 23 | as well as the following: 24 | 25 | =over 26 | 27 | =item uri:isbn(...) 28 | 29 | Get or set the ISBN value as an object of the type provided by the C 30 | class in the L library. This method will throw an exception 31 | if this library is not installed, or if the object supplied is not a valid 32 | ISBN object (it will currently accept a string, but you shouldn't rely on 33 | this). 34 | 35 | =item uri:isbn_digits(...) 36 | 37 | Get or set the ISBN value as a string containing just the numbers (and 38 | possibly an 'X' as the last digit). There will be no hyphens in this value, 39 | and it should be exactly 10 or 13 characters long. 40 | 41 | If a new value is provided then it must not be nil, and will be validated in 42 | the normal way, causing an exception if it is invalid. 43 | 44 | =back 45 | 46 | =head1 References 47 | 48 | This implements the 'isbn' NID defined in L, and is consistent 49 | with the same NID suggested in L. 50 | 51 | =for comment 52 | vi:ts=4 sw=4 expandtab 53 | -------------------------------------------------------------------------------- /doc/lua-uri-urn-issn.3: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 2 | .\" 3 | .\" Standard preamble: 4 | .\" ======================================================================== 5 | .de Sh \" Subsection heading 6 | .br 7 | .if t .Sp 8 | .ne 5 9 | .PP 10 | \fB\\$1\fR 11 | .PP 12 | .. 13 | .de Sp \" Vertical space (when we can't use .PP) 14 | .if t .sp .5v 15 | .if n .sp 16 | .. 17 | .de Vb \" Begin verbatim text 18 | .ft CW 19 | .nf 20 | .ne \\$1 21 | .. 22 | .de Ve \" End verbatim text 23 | .ft R 24 | .fi 25 | .. 26 | .\" Set up some character translations and predefined strings. \*(-- will 27 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left 28 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will 29 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and 30 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, 31 | .\" nothing in troff, for use with C<>. 32 | .tr \(*W- 33 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' 34 | .ie n \{\ 35 | . ds -- \(*W- 36 | . ds PI pi 37 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch 38 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch 39 | . ds L" "" 40 | . ds R" "" 41 | . ds C` "" 42 | . ds C' "" 43 | 'br\} 44 | .el\{\ 45 | . ds -- \|\(em\| 46 | . ds PI \(*p 47 | . ds L" `` 48 | . ds R" '' 49 | 'br\} 50 | .\" 51 | .\" If the F register is turned on, we'll generate index entries on stderr for 52 | .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index 53 | .\" entries marked with X<> in POD. Of course, you'll have to process the 54 | .\" output yourself in some meaningful fashion. 55 | .if \nF \{\ 56 | . de IX 57 | . tm Index:\\$1\t\\n%\t"\\$2" 58 | .. 59 | . nr % 0 60 | . rr F 61 | .\} 62 | .\" 63 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes 64 | .\" way too many mistakes in technical documents. 65 | .hy 0 66 | .if n .na 67 | .\" 68 | .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). 69 | .\" Fear. Run. Save yourself. No user-serviceable parts. 70 | . \" fudge factors for nroff and troff 71 | .if n \{\ 72 | . ds #H 0 73 | . ds #V .8m 74 | . ds #F .3m 75 | . ds #[ \f1 76 | . ds #] \fP 77 | .\} 78 | .if t \{\ 79 | . ds #H ((1u-(\\\\n(.fu%2u))*.13m) 80 | . ds #V .6m 81 | . ds #F 0 82 | . ds #[ \& 83 | . ds #] \& 84 | .\} 85 | . \" simple accents for nroff and troff 86 | .if n \{\ 87 | . ds ' \& 88 | . ds ` \& 89 | . ds ^ \& 90 | . ds , \& 91 | . ds ~ ~ 92 | . ds / 93 | .\} 94 | .if t \{\ 95 | . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" 96 | . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' 97 | . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' 98 | . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' 99 | . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' 100 | . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' 101 | .\} 102 | . \" troff and (daisy-wheel) nroff accents 103 | .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' 104 | .ds 8 \h'\*(#H'\(*b\h'-\*(#H' 105 | .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] 106 | .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' 107 | .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' 108 | .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] 109 | .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] 110 | .ds ae a\h'-(\w'a'u*4/10)'e 111 | .ds Ae A\h'-(\w'A'u*4/10)'E 112 | . \" corrections for vroff 113 | .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' 114 | .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' 115 | . \" for low resolution devices (crt and lpr) 116 | .if \n(.H>23 .if \n(.V>19 \ 117 | \{\ 118 | . ds : e 119 | . ds 8 ss 120 | . ds o a 121 | . ds d- d\h'-1'\(ga 122 | . ds D- D\h'-1'\(hy 123 | . ds th \o'bp' 124 | . ds Th \o'LP' 125 | . ds ae ae 126 | . ds Ae AE 127 | .\} 128 | .rm #[ #] #H #V #F C 129 | .\" ======================================================================== 130 | .\" 131 | .IX Title "LUA-URI-URN-ISSN 3" 132 | .TH LUA-URI-URN-ISSN 3 "2007-11-02" "1.0" "Lua uri.urn.issn module" 133 | .SH "Name" 134 | .IX Header "Name" 135 | lua-uri-urn-issn \- \s-1ISSN\s0 \s-1URN\s0 support for Lua \s-1URI\s0 library 136 | .SH "Description" 137 | .IX Header "Description" 138 | The class \f(CW\*(C`uri.urn.issn\*(C'\fR is used for URNs with the \s-1NID\s0 'issn', that is, URIs 139 | which begin \f(CW\*(C`urn:issn:\*(C'\fR. It inherits from the uri.urn 140 | class. 141 | .PP 142 | The \s-1URI\s0 is considered invalid if it doesn't have 8 digits, if there is 143 | anything extra in the \s-1NSS\s0 other than the digits and optional single hyphen, 144 | or if the checksum digit is wrong. 145 | .PP 146 | As specified, the check digit is canonicalized to uppercase. The canonical 147 | form has a single hyphen in the middle of the digits. 148 | .SH "Methods" 149 | .IX Header "Methods" 150 | All the methods defined in \fIlua\-uri\fR\|(3) and \fIlua\-uri\-urn\fR\|(3) as supported, as 151 | well as the following: 152 | .IP "uri:issn_digits(...)" 4 153 | .IX Item "uri:issn_digits(...)" 154 | Get or set the \s-1ISSN\s0 value as a string containing just the numbers. There 155 | will be no hyphens in this value, and it should be exactly 8 characters long. 156 | .Sp 157 | If a new value is provided then it must not be nil, and will be validated in 158 | the normal way, causing an exception if it is invalid. 159 | .SH "References" 160 | .IX Header "References" 161 | This implements the 'issn' \s-1NID\s0 defined in \*(L"\s-1RFC\s0 3044\*(R", and is consistent 162 | with the same \s-1NID\s0 suggested in \*(L"\s-1RFC\s0 2288\*(R". 163 | -------------------------------------------------------------------------------- /doc/lua-uri-urn-issn.pod: -------------------------------------------------------------------------------- 1 | =head1 Name 2 | 3 | lua-uri-urn-issn - ISSN URN support for Lua URI library 4 | 5 | =head1 Description 6 | 7 | The class C is used for URNs with the NID 'issn', that is, URIs 8 | which begin C. It inherits from the L 9 | class. 10 | 11 | The URI is considered invalid if it doesn't have 8 digits, if there is 12 | anything extra in the NSS other than the digits and optional single hyphen, 13 | or if the checksum digit is wrong. 14 | 15 | As specified, the check digit is canonicalized to uppercase. The canonical 16 | form has a single hyphen in the middle of the digits. 17 | 18 | =head1 Methods 19 | 20 | All the methods defined in L and L as supported, as 21 | well as the following: 22 | 23 | =over 24 | 25 | =item uri:issn_digits(...) 26 | 27 | Get or set the ISSN value as a string containing just the numbers. There 28 | will be no hyphens in this value, and it should be exactly 8 characters long. 29 | 30 | If a new value is provided then it must not be nil, and will be validated in 31 | the normal way, causing an exception if it is invalid. 32 | 33 | =back 34 | 35 | =head1 References 36 | 37 | This implements the 'issn' NID defined in L, and is consistent 38 | with the same NID suggested in L. 39 | 40 | =for comment 41 | vi:ts=4 sw=4 expandtab 42 | -------------------------------------------------------------------------------- /doc/lua-uri-urn-oid.3: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 2 | .\" 3 | .\" Standard preamble: 4 | .\" ======================================================================== 5 | .de Sh \" Subsection heading 6 | .br 7 | .if t .Sp 8 | .ne 5 9 | .PP 10 | \fB\\$1\fR 11 | .PP 12 | .. 13 | .de Sp \" Vertical space (when we can't use .PP) 14 | .if t .sp .5v 15 | .if n .sp 16 | .. 17 | .de Vb \" Begin verbatim text 18 | .ft CW 19 | .nf 20 | .ne \\$1 21 | .. 22 | .de Ve \" End verbatim text 23 | .ft R 24 | .fi 25 | .. 26 | .\" Set up some character translations and predefined strings. \*(-- will 27 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left 28 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will 29 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and 30 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, 31 | .\" nothing in troff, for use with C<>. 32 | .tr \(*W- 33 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' 34 | .ie n \{\ 35 | . ds -- \(*W- 36 | . ds PI pi 37 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch 38 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch 39 | . ds L" "" 40 | . ds R" "" 41 | . ds C` "" 42 | . ds C' "" 43 | 'br\} 44 | .el\{\ 45 | . ds -- \|\(em\| 46 | . ds PI \(*p 47 | . ds L" `` 48 | . ds R" '' 49 | 'br\} 50 | .\" 51 | .\" If the F register is turned on, we'll generate index entries on stderr for 52 | .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index 53 | .\" entries marked with X<> in POD. Of course, you'll have to process the 54 | .\" output yourself in some meaningful fashion. 55 | .if \nF \{\ 56 | . de IX 57 | . tm Index:\\$1\t\\n%\t"\\$2" 58 | .. 59 | . nr % 0 60 | . rr F 61 | .\} 62 | .\" 63 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes 64 | .\" way too many mistakes in technical documents. 65 | .hy 0 66 | .if n .na 67 | .\" 68 | .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). 69 | .\" Fear. Run. Save yourself. No user-serviceable parts. 70 | . \" fudge factors for nroff and troff 71 | .if n \{\ 72 | . ds #H 0 73 | . ds #V .8m 74 | . ds #F .3m 75 | . ds #[ \f1 76 | . ds #] \fP 77 | .\} 78 | .if t \{\ 79 | . ds #H ((1u-(\\\\n(.fu%2u))*.13m) 80 | . ds #V .6m 81 | . ds #F 0 82 | . ds #[ \& 83 | . ds #] \& 84 | .\} 85 | . \" simple accents for nroff and troff 86 | .if n \{\ 87 | . ds ' \& 88 | . ds ` \& 89 | . ds ^ \& 90 | . ds , \& 91 | . ds ~ ~ 92 | . ds / 93 | .\} 94 | .if t \{\ 95 | . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" 96 | . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' 97 | . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' 98 | . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' 99 | . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' 100 | . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' 101 | .\} 102 | . \" troff and (daisy-wheel) nroff accents 103 | .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' 104 | .ds 8 \h'\*(#H'\(*b\h'-\*(#H' 105 | .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] 106 | .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' 107 | .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' 108 | .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] 109 | .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] 110 | .ds ae a\h'-(\w'a'u*4/10)'e 111 | .ds Ae A\h'-(\w'A'u*4/10)'E 112 | . \" corrections for vroff 113 | .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' 114 | .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' 115 | . \" for low resolution devices (crt and lpr) 116 | .if \n(.H>23 .if \n(.V>19 \ 117 | \{\ 118 | . ds : e 119 | . ds 8 ss 120 | . ds o a 121 | . ds d- d\h'-1'\(ga 122 | . ds D- D\h'-1'\(hy 123 | . ds th \o'bp' 124 | . ds Th \o'LP' 125 | . ds ae ae 126 | . ds Ae AE 127 | .\} 128 | .rm #[ #] #H #V #F C 129 | .\" ======================================================================== 130 | .\" 131 | .IX Title "LUA-URI-URN-OID 3" 132 | .TH LUA-URI-URN-OID 3 "2007-11-02" "1.0" "Lua uri.urn.oid module" 133 | .SH "Name" 134 | .IX Header "Name" 135 | lua-uri-urn-oid \- \s-1OID\s0 \s-1URN\s0 support for Lua \s-1URI\s0 library 136 | .SH "Description" 137 | .IX Header "Description" 138 | The class \f(CW\*(C`uri.urn.oid\*(C'\fR is used for URNs with the \s-1NID\s0 'oid', that is, URIs 139 | which begin \f(CW\*(C`urn:oid:\*(C'\fR. It inherits from the uri.urn 140 | class. 141 | .PP 142 | The \s-1URI\s0 is considered invalid if its \s-1NSS\s0 doesn't consist only of non-negative 143 | integers separated by full stop characters. Numbers with leading zeroes 144 | are not allowed (although the number '0' on its own is). There must be at 145 | least one number. 146 | .PP 147 | There is no normalization performed beyound that performed by the \f(CW\*(C`uri.urn\*(C'\fR 148 | class. 149 | .SH "Methods" 150 | .IX Header "Methods" 151 | All the methods defined in \fIlua\-uri\fR\|(3) and \fIlua\-uri\-urn\fR\|(3) as supported, as 152 | well as the following: 153 | .IP "uri:oid_numbers(...)" 4 154 | .IX Item "uri:oid_numbers(...)" 155 | Get or set the \s-1OID\s0 as an array of Lua number values. 156 | .Sp 157 | If a new value is provided then it must be a table containing an array of 158 | at least one number. All the values in the table must be non-negative 159 | numbers. Non-integer numbers are rounded down to an integer value. Strings 160 | containing only decimal digits are also allowed. 161 | .Sp 162 | .Vb 3 163 | \& local uri = assert(URI:new("urn:oid:1.0.23")) 164 | \& local nums = uri:oid_numbers() 165 | \& for i, v in ipairs(nums) do print(i, v) end 166 | .Ve 167 | .Sp 168 | .Vb 2 169 | \& uri:oid_numbers({ 5, 4, 3, 2, 1 }) 170 | \& print(uri) \-\- urn:oid:5.4.3.2.1 171 | .Ve 172 | .SH "References" 173 | .IX Header "References" 174 | This implements the 'oid' \s-1NID\s0 defined in \*(L"\s-1RFC\s0 3061\*(R". 175 | -------------------------------------------------------------------------------- /doc/lua-uri-urn-oid.pod: -------------------------------------------------------------------------------- 1 | =head1 Name 2 | 3 | lua-uri-urn-oid - OID URN support for Lua URI library 4 | 5 | =head1 Description 6 | 7 | The class C is used for URNs with the NID 'oid', that is, URIs 8 | which begin C. It inherits from the L 9 | class. 10 | 11 | The URI is considered invalid if its NSS doesn't consist only of non-negative 12 | integers separated by full stop characters. Numbers with leading zeroes 13 | are not allowed (although the number '0' on its own is). There must be at 14 | least one number. 15 | 16 | There is no normalization performed beyound that performed by the C 17 | class. 18 | 19 | =head1 Methods 20 | 21 | All the methods defined in L and L as supported, as 22 | well as the following: 23 | 24 | =over 25 | 26 | =item uri:oid_numbers(...) 27 | 28 | Get or set the OID as an array of Lua number values. 29 | 30 | If a new value is provided then it must be a table containing an array of 31 | at least one number. All the values in the table must be non-negative 32 | numbers. Non-integer numbers are rounded down to an integer value. Strings 33 | containing only decimal digits are also allowed. 34 | 35 | =for syntax-highlight lua 36 | 37 | local uri = assert(URI:new("urn:oid:1.0.23")) 38 | local nums = uri:oid_numbers() 39 | for i, v in ipairs(nums) do print(i, v) end 40 | 41 | uri:oid_numbers({ 5, 4, 3, 2, 1 }) 42 | print(uri) -- urn:oid:5.4.3.2.1 43 | 44 | =back 45 | 46 | =head1 References 47 | 48 | This implements the 'oid' NID defined in L. 49 | 50 | =for comment 51 | vi:ts=4 sw=4 expandtab 52 | -------------------------------------------------------------------------------- /doc/lua-uri-urn.3: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 2 | .\" 3 | .\" Standard preamble: 4 | .\" ======================================================================== 5 | .de Sh \" Subsection heading 6 | .br 7 | .if t .Sp 8 | .ne 5 9 | .PP 10 | \fB\\$1\fR 11 | .PP 12 | .. 13 | .de Sp \" Vertical space (when we can't use .PP) 14 | .if t .sp .5v 15 | .if n .sp 16 | .. 17 | .de Vb \" Begin verbatim text 18 | .ft CW 19 | .nf 20 | .ne \\$1 21 | .. 22 | .de Ve \" End verbatim text 23 | .ft R 24 | .fi 25 | .. 26 | .\" Set up some character translations and predefined strings. \*(-- will 27 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left 28 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will 29 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and 30 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, 31 | .\" nothing in troff, for use with C<>. 32 | .tr \(*W- 33 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' 34 | .ie n \{\ 35 | . ds -- \(*W- 36 | . ds PI pi 37 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch 38 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch 39 | . ds L" "" 40 | . ds R" "" 41 | . ds C` "" 42 | . ds C' "" 43 | 'br\} 44 | .el\{\ 45 | . ds -- \|\(em\| 46 | . ds PI \(*p 47 | . ds L" `` 48 | . ds R" '' 49 | 'br\} 50 | .\" 51 | .\" If the F register is turned on, we'll generate index entries on stderr for 52 | .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index 53 | .\" entries marked with X<> in POD. Of course, you'll have to process the 54 | .\" output yourself in some meaningful fashion. 55 | .if \nF \{\ 56 | . de IX 57 | . tm Index:\\$1\t\\n%\t"\\$2" 58 | .. 59 | . nr % 0 60 | . rr F 61 | .\} 62 | .\" 63 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes 64 | .\" way too many mistakes in technical documents. 65 | .hy 0 66 | .if n .na 67 | .\" 68 | .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). 69 | .\" Fear. Run. Save yourself. No user-serviceable parts. 70 | . \" fudge factors for nroff and troff 71 | .if n \{\ 72 | . ds #H 0 73 | . ds #V .8m 74 | . ds #F .3m 75 | . ds #[ \f1 76 | . ds #] \fP 77 | .\} 78 | .if t \{\ 79 | . ds #H ((1u-(\\\\n(.fu%2u))*.13m) 80 | . ds #V .6m 81 | . ds #F 0 82 | . ds #[ \& 83 | . ds #] \& 84 | .\} 85 | . \" simple accents for nroff and troff 86 | .if n \{\ 87 | . ds ' \& 88 | . ds ` \& 89 | . ds ^ \& 90 | . ds , \& 91 | . ds ~ ~ 92 | . ds / 93 | .\} 94 | .if t \{\ 95 | . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" 96 | . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' 97 | . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' 98 | . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' 99 | . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' 100 | . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' 101 | .\} 102 | . \" troff and (daisy-wheel) nroff accents 103 | .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' 104 | .ds 8 \h'\*(#H'\(*b\h'-\*(#H' 105 | .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] 106 | .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' 107 | .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' 108 | .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] 109 | .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] 110 | .ds ae a\h'-(\w'a'u*4/10)'e 111 | .ds Ae A\h'-(\w'A'u*4/10)'E 112 | . \" corrections for vroff 113 | .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' 114 | .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' 115 | . \" for low resolution devices (crt and lpr) 116 | .if \n(.H>23 .if \n(.V>19 \ 117 | \{\ 118 | . ds : e 119 | . ds 8 ss 120 | . ds o a 121 | . ds d- d\h'-1'\(ga 122 | . ds D- D\h'-1'\(hy 123 | . ds th \o'bp' 124 | . ds Th \o'LP' 125 | . ds ae ae 126 | . ds Ae AE 127 | .\} 128 | .rm #[ #] #H #V #F C 129 | .\" ======================================================================== 130 | .\" 131 | .IX Title "LUA-URI-URN 3" 132 | .TH LUA-URI-URN 3 "2007-11-02" "1.0" "Lua uri.urn module" 133 | .SH "Name" 134 | .IX Header "Name" 135 | lua-uri-urn \- \s-1URN\s0 support for Lua \s-1URI\s0 library 136 | .SH "Description" 137 | .IX Header "Description" 138 | The class \f(CW\*(C`uri.urn\*(C'\fR is used for URNs, that is, URIs with the \f(CW\*(C`urn\*(C'\fR scheme. 139 | It inherits from the uri class. 140 | .PP 141 | Any \s-1URN\s0 containing an authority part or query part is considered to be invalid, 142 | as is one which does not have a valid \s-1NID\s0. URNs must be of the form 143 | \&\f(CW\*(C`urn:nid:nss\*(C'\fR, where the \s-1NSS\s0 part has a syntax specific to the \s-1NID\s0. The 144 | scheme and \s-1NID\s0 part are both normalized to lowercase. Some NIDs have 145 | subclasses which enforce further syntax constraints, do NID-specific 146 | normalization, or provide additional methods. 147 | .SH "Methods" 148 | .IX Header "Methods" 149 | All the methods defined in \fIlua\-uri\fR\|(3) are supported. The \f(CW\*(C`userinfo\*(C'\fR, 150 | \&\f(CW\*(C`host\*(C'\fR, \f(CW\*(C`port\*(C'\fR, and \f(CW\*(C`query\*(C'\fR methods will always return nil, and will throw 151 | an exception when passed anything other than nil. The \f(CW\*(C`path\*(C'\fR method will 152 | throw an exception if given a new path which is nil or not valid for the \f(CW\*(C`urn\*(C'\fR 153 | scheme. 154 | .PP 155 | The following additional methods are supported: 156 | .IP "uri:nid(...)" 4 157 | .IX Item "uri:nid(...)" 158 | Get or set the \s-1NID\s0 (Namespace Identifier) of the \s-1URN\s0 (the part of the path 159 | before the first colon). If a new value is supplied then the \s-1URI\s0's path will 160 | be changed to have the new \s-1NID\s0 but with the same \s-1NSS\s0 value. 161 | .Sp 162 | An exception will be thrown if the new \s-1NID\s0 is invalid, or if the existing 163 | \&\s-1NSS\s0 value is invalid in the context of the new \s-1NID\s0. Note that the value 164 | \&'urn' is an invalid \s-1NID\s0. 165 | .Sp 166 | This can cause the class of the \s-1URI\s0 object to change, if a different class 167 | is appropriate for the new \s-1NID\s0. 168 | .IP "uri:nss(...)" 4 169 | .IX Item "uri:nss(...)" 170 | Get or set the \s-1NSS\s0 (Namespace Specific String) part of the \s-1URN\s0 (the part of the 171 | path after the first colon). If a new value is supplied then the \s-1URI\s0's path 172 | will be changed to use the new \s-1NSS\s0, but the \s-1NID\s0 will be unchanged. 173 | .Sp 174 | This will throw an exception if the new value is invalid for the current \s-1NID\s0. 175 | .SH "Subclasses" 176 | .IX Header "Subclasses" 177 | The following subclasses are used for URNs with certain NIDs. URNs with 178 | other NIDs just use the generic \f(CW\*(C`uri.urn\*(C'\fR class. 179 | .IP "uri.urn.isbn" 4 180 | .IX Item "uri.urn.isbn" 181 | .PD 0 182 | .IP "uri.urn.issn" 4 183 | .IX Item "uri.urn.issn" 184 | .IP "uri.urn.oid" 4 185 | .IX Item "uri.urn.oid" 186 | .PD 187 | .SH "References" 188 | .IX Header "References" 189 | This class is based on \*(L"\s-1RFC\s0 2141\*(R". 190 | -------------------------------------------------------------------------------- /doc/lua-uri-urn.pod: -------------------------------------------------------------------------------- 1 | =head1 Name 2 | 3 | lua-uri-urn - URN support for Lua URI library 4 | 5 | =head1 Description 6 | 7 | The class C is used for URNs, that is, URIs with the C scheme. 8 | It inherits from the L class. 9 | 10 | Any URN containing an authority part or query part is considered to be invalid, 11 | as is one which does not have a valid NID. URNs must be of the form 12 | C, where the NSS part has a syntax specific to the NID. The 13 | scheme and NID part are both normalized to lowercase. Some NIDs have 14 | subclasses which enforce further syntax constraints, do NID-specific 15 | normalization, or provide additional methods. 16 | 17 | =head1 Methods 18 | 19 | All the methods defined in L are supported. The C, 20 | C, C, and C methods will always return nil, and will throw 21 | an exception when passed anything other than nil. The C method will 22 | throw an exception if given a new path which is nil or not valid for the C 23 | scheme. 24 | 25 | The following additional methods are supported: 26 | 27 | =over 28 | 29 | =item uri:nid(...) 30 | 31 | Get or set the NID (Namespace Identifier) of the URN (the part of the path 32 | before the first colon). If a new value is supplied then the URI's path will 33 | be changed to have the new NID but with the same NSS value. 34 | 35 | An exception will be thrown if the new NID is invalid, or if the existing 36 | NSS value is invalid in the context of the new NID. Note that the value 37 | 'urn' is an invalid NID. 38 | 39 | This can cause the class of the URI object to change, if a different class 40 | is appropriate for the new NID. 41 | 42 | =item uri:nss(...) 43 | 44 | Get or set the NSS (Namespace Specific String) part of the URN (the part of the 45 | path after the first colon). If a new value is supplied then the URI's path 46 | will be changed to use the new NSS, but the NID will be unchanged. 47 | 48 | This will throw an exception if the new value is invalid for the current NID. 49 | 50 | =back 51 | 52 | =head1 Subclasses 53 | 54 | The following subclasses are used for URNs with certain NIDs. URNs with 55 | other NIDs just use the generic C class. 56 | 57 | =over 58 | 59 | =item L 60 | 61 | =item L 62 | 63 | =item L 64 | 65 | =back 66 | 67 | =head1 References 68 | 69 | This class is based on L. 70 | 71 | =for comment 72 | vi:ts=4 sw=4 expandtab 73 | -------------------------------------------------------------------------------- /test/_pristine.lua: -------------------------------------------------------------------------------- 1 | require "lunit" 2 | local testcase = lunit.TestCase("Test library loading doesn't affect globals") 3 | 4 | function testcase:test_no_global_clobbering () 5 | local globals = {} 6 | for key in pairs(_G) do globals[key] = true end 7 | 8 | -- Load all the modules for the different types of URIs, in case any one 9 | -- of those treads on a global. I keep them around in a table to make 10 | -- sure they're all loaded at the same time, just in case that does 11 | -- anything interesting. 12 | local schemes = { 13 | "_login", "_relative", "_util", "data", 14 | "file", "file.unix", "file.win32", 15 | "ftp", "http", "https", 16 | "pop", "rtsp", "rtspu", "telnet", 17 | "urn", "urn.isbn", "urn.issn", "urn.oid" 18 | } 19 | local loaded = {} 20 | local URI = require "uri" 21 | for _, name in ipairs(schemes) do 22 | loaded[name] = require("uri." .. name) 23 | end 24 | 25 | for key in pairs(_G) do 26 | lunit.assert_not_nil(globals[key], 27 | "global '" .. key .. "' created by lib") 28 | end 29 | for key in pairs(globals) do 30 | lunit.assert_not_nil(_G[key], 31 | "global '" .. key .. "' destroyed by lib") 32 | end 33 | end 34 | 35 | lunit.run() 36 | -- vi:ts=4 sw=4 expandtab 37 | -------------------------------------------------------------------------------- /test/_relative.lua: -------------------------------------------------------------------------------- 1 | require "uri-test" 2 | local URI = require "uri" 3 | local testcase = TestCase("Test 'uri._relative' class") 4 | 5 | local function test_rel (input, userinfo, host, port, path, query, frag, 6 | expected) 7 | local uri = assert(URI:new(input)) 8 | assert_true(uri:is_relative()) 9 | is("uri._relative", getmetatable(uri)._NAME) 10 | is(nil, uri:scheme()) 11 | is(userinfo, uri:userinfo()) 12 | is(host, uri:host()) 13 | is(port, uri:port()) 14 | is(path, uri:path()) 15 | is(query, uri:query()) 16 | is(frag, uri:fragment()) 17 | if not expected then expected = input end 18 | is(expected, uri:uri()) 19 | is(expected, tostring(uri)) 20 | end 21 | 22 | function testcase:test_relative () 23 | test_rel("", nil, nil, nil, "", nil, nil) 24 | test_rel("foo/bar", nil, nil, nil, "foo/bar", nil, nil) 25 | test_rel("/foo/bar", nil, nil, nil, "/foo/bar", nil, nil) 26 | test_rel("?query", nil, nil, nil, "", "query", nil) 27 | test_rel("?", nil, nil, nil, "", "", nil) 28 | test_rel("#foo", nil, nil, nil, "", nil, "foo") 29 | test_rel("#", nil, nil, nil, "", nil, "") 30 | test_rel("?q#f", nil, nil, nil, "", "q", "f") 31 | test_rel("?#", nil, nil, nil, "", "", "") 32 | test_rel("foo?q#f", nil, nil, nil, "foo", "q", "f") 33 | test_rel("//host.com", nil, "host.com", nil, "", nil, nil) 34 | test_rel("//host.com/blah?q#f", nil, "host.com", nil, "/blah", "q", "f") 35 | test_rel("//host.com:123/blah?q#f", nil, "host.com", 123, "/blah", "q", "f") 36 | test_rel("//u:p@host.com:123/blah?q#f", 37 | "u:p", "host.com", 123, "/blah", "q", "f") 38 | 39 | -- Paths shouldn't be normalized in a relative reference, only after it 40 | -- has been used to create an absolute one. 41 | test_rel("./foo/bar", nil, nil, nil, "./foo/bar", nil, nil) 42 | test_rel("././foo/./bar", nil, nil, nil, "././foo/./bar", nil, nil) 43 | test_rel("../foo/bar", nil, nil, nil, "../foo/bar", nil, nil) 44 | test_rel("../../foo/../bar", nil, nil, nil, "../../foo/../bar", nil, nil) 45 | end 46 | 47 | function testcase:test_bad_usage () 48 | local uri = assert(URI:new("foo")) 49 | assert_error("set scheme on relative ref", 50 | function () uri:scheme("x-foo") end) 51 | end 52 | 53 | lunit.run() 54 | -- vi:ts=4 sw=4 expandtab 55 | -------------------------------------------------------------------------------- /test/_resolve.lua: -------------------------------------------------------------------------------- 1 | require "uri-test" 2 | local URI = require "uri" 3 | local testcase = TestCase("Test 'resolve' and 'relativize' methods") 4 | 5 | -- Test data from RFC 3986. The 'http' prefix has been changed throughout 6 | -- to 'x-foo' so as not to trigger any scheme-specific normalization. 7 | local resolve_tests = { 8 | -- 5.4.1. Normal Examples 9 | ["g:h"] = "g:h", 10 | ["g"] = "x-foo://a/b/c/g", 11 | ["./g"] = "x-foo://a/b/c/g", 12 | ["g/"] = "x-foo://a/b/c/g/", 13 | ["/g"] = "x-foo://a/g", 14 | ["//g"] = "x-foo://g", 15 | ["?y"] = "x-foo://a/b/c/d;p?y", 16 | ["g?y"] = "x-foo://a/b/c/g?y", 17 | ["#s"] = "x-foo://a/b/c/d;p?q#s", 18 | ["g#s"] = "x-foo://a/b/c/g#s", 19 | ["g?y#s"] = "x-foo://a/b/c/g?y#s", 20 | [";x"] = "x-foo://a/b/c/;x", 21 | ["g;x"] = "x-foo://a/b/c/g;x", 22 | ["g;x?y#s"] = "x-foo://a/b/c/g;x?y#s", 23 | [""] = "x-foo://a/b/c/d;p?q", 24 | ["."] = "x-foo://a/b/c/", 25 | ["./"] = "x-foo://a/b/c/", 26 | [".."] = "x-foo://a/b/", 27 | ["../"] = "x-foo://a/b/", 28 | ["../g"] = "x-foo://a/b/g", 29 | ["../.."] = "x-foo://a/", 30 | ["../../"] = "x-foo://a/", 31 | ["../../g"] = "x-foo://a/g", 32 | 33 | -- 5.4.2. Abnormal Examples 34 | ["../../../g"] = "x-foo://a/g", 35 | ["../../../../g"] = "x-foo://a/g", 36 | ["/./g"] = "x-foo://a/g", 37 | ["/../g"] = "x-foo://a/g", 38 | ["g."] = "x-foo://a/b/c/g.", 39 | [".g"] = "x-foo://a/b/c/.g", 40 | ["g.."] = "x-foo://a/b/c/g..", 41 | ["..g"] = "x-foo://a/b/c/..g", 42 | ["./../g"] = "x-foo://a/b/g", 43 | ["./g/."] = "x-foo://a/b/c/g/", 44 | ["g/./h"] = "x-foo://a/b/c/g/h", 45 | ["g/../h"] = "x-foo://a/b/c/h", 46 | ["g;x=1/./y"] = "x-foo://a/b/c/g;x=1/y", 47 | ["g;x=1/../y"] = "x-foo://a/b/c/y", 48 | ["g?y/./x"] = "x-foo://a/b/c/g?y/./x", 49 | ["g?y/../x"] = "x-foo://a/b/c/g?y/../x", 50 | ["g#s/./x"] = "x-foo://a/b/c/g#s/./x", 51 | ["g#s/../x"] = "x-foo://a/b/c/g#s/../x", 52 | ["x-foo:g"] = "x-foo:g", 53 | 54 | -- Some extra tests for good measure 55 | ["#foo?"] = "x-foo://a/b/c/d;p?q#foo?", 56 | ["?#foo"] = "x-foo://a/b/c/d;p?#foo", 57 | } 58 | 59 | local function test_abs_rel (base, uref, expect) 60 | local bad = false 61 | 62 | -- Test 'resolve' method with object as argument. 63 | local u = assert(URI:new(uref)) 64 | local b = assert(URI:new(base)) 65 | u:resolve(b) 66 | local got = tostring(u) 67 | if got ~= expect then 68 | bad = true 69 | print("URI:new(" .. uref .. "):resolve(URI:new(" .. base .. ") ===> " .. 70 | expect .. " (not " .. got .. ")") 71 | end 72 | 73 | -- Test 'resolve' method with string as argument. 74 | u = assert(URI:new(uref)) 75 | u:resolve(base) 76 | local got = tostring(u) 77 | if got ~= expect then 78 | bad = true 79 | print("URI:new(" .. uref .. "):resolve(URI:new(" .. base .. ") ===> " .. 80 | expect .. " (not " .. got .. ")") 81 | end 82 | 83 | -- Test resolving relative URI using the constructor. 84 | local u = assert(URI:new(uref, base)) 85 | local got = tostring(u) 86 | if got ~= expect then 87 | bad = true 88 | print("URI:new(" .. uref .. ", " .. base .. ") ==> " .. expect .. 89 | " (not " .. got .. ")") 90 | end 91 | 92 | return bad 93 | end 94 | 95 | function testcase:test_resolve () 96 | local base = "x-foo://a/b/c/d;p?q" 97 | local testno = 1 98 | local bad = false 99 | 100 | for rel, abs in pairs(resolve_tests) do 101 | if test_abs_rel(base, rel, abs) then bad = true end 102 | end 103 | 104 | if bad then assert_fail("one of the checks went wrong") end 105 | end 106 | 107 | function testcase:test_resolve_error () 108 | local base = assert(URI:new("urn:oid:1.2.3")) 109 | local uri = assert(URI:new("not-valid-path-for-urn")) 110 | 111 | -- The 'resolve' method should throw an exception if the absolute URI 112 | -- that results from the resolution would be invalid. 113 | assert_error("calling resolve() creates invalid URI", 114 | function () uri:resolve(base) end) 115 | assert_true(uri:is_relative()) 116 | is("not-valid-path-for-urn", tostring(uri)) 117 | 118 | -- But the constructor should return an error in its normal fashion. 119 | local ok, err = URI:new(uri, base) 120 | assert_nil(ok) 121 | assert_string(err) 122 | end 123 | 124 | local relativize_tests = { 125 | -- Empty path if the path is the same as the base URI's. 126 | { "http://ex/", "http://ex/", "" }, 127 | { "http://ex/a/b", "http://ex/a/b", "" }, 128 | { "http://ex/a/b/", "http://ex/a/b/", "" }, 129 | -- Absolute path if the base URI's path doesn't help. 130 | { "http://ex/", "http://ex/a/b", "/" }, 131 | { "http://ex/", "http://ex/a/b/", "/" }, 132 | { "http://ex/x/y", "http://ex/", "/x/y" }, 133 | { "http://ex/x/y/", "http://ex/", "/x/y/" }, 134 | { "http://ex/x", "http://ex/a", "/x" }, 135 | { "http://ex/x", "http://ex/a/", "/x" }, 136 | { "http://ex/x/", "http://ex/a", "/x/" }, 137 | { "http://ex/x/", "http://ex/a/", "/x/" }, 138 | { "http://ex/x/y", "http://ex/a/b", "/x/y" }, 139 | { "http://ex/x/y", "http://ex/a/b/", "/x/y" }, 140 | { "http://ex/x/y/", "http://ex/a/b", "/x/y/" }, 141 | { "http://ex/x/y/", "http://ex/a/b/", "/x/y/" }, 142 | -- Add to the end of the base path. 143 | { "x-a://ex/a/b/c", "x-a://ex/a/b/", "c" }, 144 | { "x-a://ex/a/b/c/", "x-a://ex/a/b/", "c/" }, 145 | { "x-a://ex/a/b/c/d", "x-a://ex/a/b/", "c/d" }, 146 | { "x-a://ex/a/b/c/d/", "x-a://ex/a/b/", "c/d/" }, 147 | { "x-a://ex/a/b/c/d/e", "x-a://ex/a/b/", "c/d/e" }, 148 | { "x-a://ex/a/b/c:foo/d/e", "x-a://ex/a/b/", "./c:foo/d/e" }, 149 | -- Change last segment in base path, and add to it. 150 | { "x-a://ex/a/b/", "x-a://ex/a/b/c", "./" }, 151 | { "x-a://ex/a/b/x", "x-a://ex/a/b/c", "x" }, 152 | { "x-a://ex/a/b/x/", "x-a://ex/a/b/c", "x/" }, 153 | { "x-a://ex/a/b/x/y", "x-a://ex/a/b/c", "x/y" }, 154 | { "x-a://ex/a/b/x:foo/y", "x-a://ex/a/b/c", "./x:foo/y" }, 155 | -- Use '..' segments. 156 | { "x-a://ex/a/b/c", "x-a://ex/a/b/c/d", "../c" }, 157 | { "x-a://ex/a/b/c", "x-a://ex/a/b/c/", "../c" }, 158 | { "x-a://ex/a/b/", "x-a://ex/a/b/c/", "../" }, 159 | { "x-a://ex/a/b/", "x-a://ex/a/b/c/d", "../" }, 160 | { "x-a://ex/a/b", "x-a://ex/a/b/c/", "../../b" }, 161 | { "x-a://ex/a/b", "x-a://ex/a/b/c/d", "../../b" }, 162 | { "x-a://ex/a/", "x-a://ex/a/b/c/", "../../" }, 163 | { "x-a://ex/a/", "x-a://ex/a/b/c/d", "../../" }, 164 | -- Preserve query and fragment parts. 165 | { "http://ex/a/b", "http://ex/a/b?baseq#basef", "b" }, 166 | { "http://ex/a/b:c", "http://ex/a/b:c?baseq#basef", "./b:c" }, 167 | { "http://ex/a/b?", "http://ex/a/b?baseq#basef", "?" }, 168 | { "http://ex/a/b?foo", "http://ex/a/b?baseq#basef", "?foo" }, 169 | { "http://ex/a/b?foo#", "http://ex/a/b?baseq#basef", "?foo#" }, 170 | { "http://ex/a/b?foo#bar", "http://ex/a/b?baseq#basef", "?foo#bar" }, 171 | { "http://ex/a/b#bar", "http://ex/a/b?baseq#basef", "b#bar" }, 172 | { "http://ex/a/b:foo#bar", "http://ex/a/b:foo?baseq#basef", "./b:foo#bar" }, 173 | { "http://ex/a/b:foo#bar", "http://ex/a/b:foo#basef", "#bar" }, 174 | } 175 | 176 | function testcase:test_relativize () 177 | for _, test in ipairs(relativize_tests) do 178 | local uri = assert(URI:new(test[1])) 179 | uri:relativize(test[2]) 180 | is(test[3], tostring(uri)) 181 | 182 | -- Make sure it will resolve back to the original value. 183 | uri:resolve(test[2]) 184 | is(test[1], tostring(uri)) 185 | end 186 | end 187 | 188 | function testcase:test_relativize_already_is () 189 | local uri = assert(URI:new("../foo")) 190 | uri:relativize("http://host/") 191 | is("../foo", tostring(uri)) 192 | end 193 | 194 | function testcase:test_relativize_urn () 195 | local uri = assert(URI:new("urn:oid:1.2.3")) 196 | uri:relativize("urn:oid:1") 197 | is("urn:oid:1.2.3", tostring(uri)) 198 | end 199 | 200 | lunit.run() 201 | -- vi:ts=4 sw=4 expandtab 202 | -------------------------------------------------------------------------------- /test/_util.lua: -------------------------------------------------------------------------------- 1 | require "uri-test" 2 | local Util = require "uri._util" 3 | local testcase = TestCase("Test utility functions in 'uri._util' module") 4 | 5 | function testcase:test_metadata () 6 | is("uri._util", Util._NAME) 7 | end 8 | 9 | function testcase:test_uri_encode () 10 | is("%7Cabc%E5", Util.uri_encode("|abc\229")) 11 | is("a%62%63", Util.uri_encode("abc", "b-d")) 12 | assert_nil(Util.uri_encode(nil)) 13 | end 14 | 15 | function testcase:test_uri_decode () 16 | is("|abc\229", Util.uri_decode("%7Cabc%e5")) 17 | is("@AB", Util.uri_decode("%40A%42")) 18 | is("CDE", Util.uri_decode("CDE")) 19 | end 20 | 21 | function testcase:test_uri_decode () 22 | is("/%2F%25/..!%A1", Util.uri_decode("/%2F%25/%2e.%21%A1", "%-.!")) 23 | end 24 | 25 | function testcase:test_remove_dot_segments () 26 | is("/", Util.remove_dot_segments("/foo/../")) 27 | is("/bar", Util.remove_dot_segments("/foo/./../bar")) 28 | end 29 | 30 | function testcase:test_split () 31 | local list 32 | list = Util.split(";", "") 33 | assert_array_shallow_equal({}, list) 34 | list = Util.split(";", "foo") 35 | assert_array_shallow_equal({"foo"}, list) 36 | list = Util.split(";", "foo;bar") 37 | assert_array_shallow_equal({"foo","bar"}, list) 38 | list = Util.split(";", "foo;bar;baz") 39 | assert_array_shallow_equal({"foo","bar","baz"}, list) 40 | list = Util.split(";", ";") 41 | assert_array_shallow_equal({"",""}, list) 42 | list = Util.split(";", "foo;") 43 | assert_array_shallow_equal({"foo",""}, list) 44 | list = Util.split(";", ";foo") 45 | assert_array_shallow_equal({"","foo"}, list) 46 | -- TODO test with multi-char and more complex patterns 47 | end 48 | 49 | function testcase:test_split_with_max () 50 | local list 51 | list = Util.split(";", "foo;bar;baz", 4) 52 | assert_array_shallow_equal({"foo","bar","baz"}, list) 53 | list = Util.split(";", "foo;bar;baz", 3) 54 | assert_array_shallow_equal({"foo","bar","baz"}, list) 55 | list = Util.split(";", "foo;bar;baz", 2) 56 | assert_array_shallow_equal({"foo","bar;baz"}, list) 57 | list = Util.split(";", "foo;bar;baz", 1) 58 | assert_array_shallow_equal({"foo;bar;baz"}, list) 59 | end 60 | 61 | function testcase:test_attempt_require () 62 | local mod = Util.attempt_require("string") 63 | assert_table(mod) 64 | mod = Util.attempt_require("lua-module-which-doesn't-exist") 65 | assert_nil(mod) 66 | end 67 | 68 | function testcase:test_subclass_of () 69 | local baseclass = {} 70 | baseclass.__index = baseclass 71 | baseclass.overridden = function () return "baseclass" end 72 | baseclass.inherited = function () return "inherited" end 73 | 74 | local subclass = {} 75 | Util.subclass_of(subclass, baseclass) 76 | subclass.overridden = function () return "subclass" end 77 | 78 | assert(getmetatable(subclass) == baseclass) 79 | assert(subclass._SUPER == baseclass) 80 | 81 | local baseobject, subobject = {}, {} 82 | setmetatable(baseobject, baseclass) 83 | setmetatable(subobject, subclass) 84 | 85 | is("baseclass", baseobject:overridden()) 86 | is("subclass", subobject:overridden()) 87 | is("inherited", baseobject:inherited()) 88 | is("inherited", subobject:inherited()) 89 | end 90 | 91 | lunit.run() 92 | -- vi:ts=4 sw=4 expandtab 93 | -------------------------------------------------------------------------------- /test/data.lua: -------------------------------------------------------------------------------- 1 | require "uri-test" 2 | local URI = require "uri" 3 | local Util = require "uri._util" 4 | local testcase = TestCase("Test uri.data") 5 | 6 | local Filter = Util.attempt_require("datafilter") 7 | 8 | function testcase:test_data_uri_encoded () 9 | local uri = assert(URI:new("data:,A%20brief%20note")) 10 | is("uri.data", uri._NAME) 11 | is(",A%20brief%20note", uri:path()) 12 | is("data", uri:scheme()) 13 | 14 | is("text/plain;charset=US-ASCII", uri:data_media_type()) 15 | is("A brief note", uri:data_bytes()) 16 | 17 | local old = uri:data_bytes("F\229r-i-k\229l er tingen!") 18 | is("A brief note", old) 19 | is("data:,F%E5r-i-k%E5l%20er%20tingen!", tostring(uri)) 20 | 21 | old = uri:data_media_type("text/plain;charset=iso-8859-1") 22 | is("text/plain;charset=US-ASCII", old) 23 | is("data:text/plain;charset=iso-8859-1,F%E5r-i-k%E5l%20er%20tingen!", 24 | tostring(uri)) 25 | end 26 | 27 | function testcase:test_data_big_base64_chunk () 28 | local imgdata = "R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7" 29 | local uri = assert(URI:new("data:image/gif;base64," .. imgdata)) 30 | is("image/gif", uri:data_media_type()) 31 | 32 | if Filter then 33 | local gotdata = uri:data_bytes() 34 | is(273, gotdata:len()) 35 | is(imgdata, Filter.base64_encode(gotdata)) 36 | end 37 | end 38 | 39 | function testcase:test_data_containing_commas () 40 | local uri = assert(URI:new("data:application/vnd-xxx-query,select_vcount,fcol_from_fieldtable/local")) 41 | is("application/vnd-xxx-query", uri:data_media_type()) 42 | is("select_vcount,fcol_from_fieldtable/local", uri:data_bytes()) 43 | uri:data_bytes("") 44 | is("data:application/vnd-xxx-query,", tostring(uri)) 45 | 46 | uri:data_bytes("a,b") 47 | uri:data_media_type(nil) 48 | is("data:,a,b", tostring(uri)) 49 | 50 | is("a,b", uri:data_bytes(nil)) 51 | is("", uri:data_bytes()) 52 | end 53 | 54 | function testcase:test_automatic_selection_of_uri_or_base64_encoding () 55 | local uri = assert(URI:new("data:,")) 56 | uri:data_bytes("") 57 | is("data:,", tostring(uri)) 58 | 59 | uri:data_bytes(">") 60 | is("data:,%3E", tostring(uri)) 61 | is(">", uri:data_bytes()) 62 | 63 | uri:data_bytes(">>>>>") 64 | is("data:,%3E%3E%3E%3E%3E", tostring(uri)) 65 | 66 | if Filter then 67 | uri:data_bytes(">>>>>>") 68 | is("data:;base64,Pj4+Pj4+", tostring(uri)) 69 | 70 | uri:data_media_type("text/plain;foo=bar") 71 | is("data:text/plain;foo=bar;base64,Pj4+Pj4+", tostring(uri)) 72 | 73 | uri:data_media_type("foo") 74 | is("data:foo;base64,Pj4+Pj4+", tostring(uri)) 75 | 76 | uri:data_bytes((">"):rep(3000)) 77 | is("data:foo;base64," .. ("Pj4+"):rep(1000), tostring(uri)) 78 | is((">"):rep(3000), uri:data_bytes()) 79 | else 80 | uri:data_bytes(">>>>>>") 81 | is("data:,%3E%3E%3E%3E%3E%3E", tostring(uri)) 82 | uri:data_media_type("foo") 83 | is("data:foo,%3E%3E%3E%3E%3E%3E", tostring(uri)) 84 | end 85 | 86 | uri:data_media_type(nil) 87 | uri:data_bytes(nil) 88 | is("data:,", tostring(uri)) 89 | end 90 | 91 | function testcase:test_bad_uri () 92 | is_bad_uri("missing comma", "data:foo") 93 | is_bad_uri("no path at all", "data:") 94 | is_bad_uri("has host", "data://host/,") 95 | end 96 | 97 | function testcase:test_set_path () 98 | local uri = assert(URI:new("data:image/gif,foobar")) 99 | is("image/gif,foobar", uri:path("image/jpeg;foo=bar,x y,?")) 100 | is("image/jpeg;foo=bar,x%20y,%3F", uri:path(",blah")) 101 | is(",blah", uri:path(",")) 102 | is(",", uri:path()) 103 | is("data:,", tostring(uri)) 104 | end 105 | 106 | function testcase:test_set_path_bad () 107 | local uri = assert(URI:new("data:image/gif,foobar")) 108 | assert_error("no path", function () uri:path(nil) end) 109 | assert_error("empty path", function () uri:path("") end) 110 | assert_error("no comma", function () uri:path("foo;bar") end) 111 | assert_error("bad base64 encoding", function () uri:path(";base64,x_0") end) 112 | is("image/gif,foobar", uri:path()) 113 | is("data:image/gif,foobar", tostring(uri)) 114 | end 115 | 116 | function testcase:test_set_disallowed_stuff () 117 | local uri = assert(URI:new("data:,")) 118 | assert_error("can't set userinfo", function () uri:userinfo("x") end) 119 | assert_error("can't set host", function () uri:host("x") end) 120 | assert_error("can't set port", function () uri:port(23) end) 121 | is("data:,", tostring(uri)) 122 | end 123 | 124 | lunit.run() 125 | -- vi:ts=4 sw=4 expandtab 126 | -------------------------------------------------------------------------------- /test/file.lua: -------------------------------------------------------------------------------- 1 | require "uri-test" 2 | local URI = require "uri" 3 | local URIFile = require "uri.file" 4 | local testcase = TestCase("Test uri.file") 5 | 6 | function testcase:test_normalize () 7 | test_norm("file:///foo", "file://LocalHost/foo") 8 | test_norm("file:///", "file://localhost/") 9 | test_norm("file:///", "file://localhost") 10 | test_norm("file:///", "file://") 11 | test_norm("file:///", "file:/") 12 | test_norm("file:///foo", "file:/foo") 13 | test_norm("file://foo/", "file://foo") 14 | end 15 | 16 | function testcase:test_invalid () 17 | is_bad_uri("just scheme", "file:") 18 | is_bad_uri("scheme with relative path", "file:foo/bar") 19 | end 20 | 21 | function testcase:test_set_host () 22 | local uri = assert(URI:new("file:///foo")) 23 | is("", uri:host()) 24 | is("", uri:host("LocalHost")) 25 | is("file:///foo", tostring(uri)) 26 | is("", uri:host("host.name")) 27 | is("file://host.name/foo", tostring(uri)) 28 | is("host.name", uri:host("")) 29 | is("file:///foo", tostring(uri)) 30 | end 31 | 32 | function testcase:test_set_path () 33 | local uri = assert(URI:new("file:///foo")) 34 | is("/foo", uri:path()) 35 | is("/foo", uri:path(nil)) 36 | is("file:///", tostring(uri)) 37 | is("/", uri:path("")) 38 | is("file:///", tostring(uri)) 39 | is("/", uri:path("/bar/frob")) 40 | is("file:///bar/frob", tostring(uri)) 41 | is("/bar/frob", uri:path("/")) 42 | is("file:///", tostring(uri)) 43 | end 44 | 45 | function testcase:test_bad_usage () 46 | local uri = assert(URI:new("file:///foo")) 47 | assert_error("nil host", function () uri:host(nil) end) 48 | assert_error("set userinfo", function () uri:userinfo("foo") end) 49 | assert_error("set port", function () uri:userinfo(23) end) 50 | assert_error("set relative path", function () uri:userinfo("foo/") end) 51 | end 52 | 53 | local function uri_to_fs (os, uristr, expected) 54 | local uri = assert(URI:new(uristr)) 55 | is(expected, uri:filesystem_path(os)) 56 | end 57 | 58 | local function fs_to_uri (os, path, expected) 59 | is(expected, tostring(URIFile.make_file_uri(path, os))) 60 | end 61 | 62 | function testcase:test_uri_to_fs_unix () 63 | uri_to_fs("unix", "file:///", "/") 64 | uri_to_fs("unix", "file:///c:", "/c:") 65 | uri_to_fs("unix", "file:///C:/", "/C:/") 66 | uri_to_fs("unix", "file:///C:/Program%20Files", "/C:/Program Files") 67 | uri_to_fs("unix", "file:///C:/Program%20Files/", "/C:/Program Files/") 68 | uri_to_fs("unix", "file:///Program%20Files/", "/Program Files/") 69 | end 70 | 71 | function testcase:test_uri_to_fs_unix_bad () 72 | -- On Unix platforms, there's no equivalent of UNC paths. 73 | local uri = assert(URI:new("file://laptop/My%20Documents/FileSchemeURIs.doc")) 74 | assert_error("Unix path with host name", 75 | function () uri:filesystem_path("unix") end) 76 | -- Unix paths can't contain null bytes or encoded slashes. 77 | uri = assert(URI:new("file:///frob/foo%00bar/quux")) 78 | assert_error("Unix path with null byte", 79 | function () uri:filesystem_path("unix") end) 80 | uri = assert(URI:new("file:///frob/foo%2Fbar/quux")) 81 | assert_error("Unix path with encoded slash", 82 | function () uri:filesystem_path("unix") end) 83 | end 84 | 85 | function testcase:test_fs_to_uri_unix () 86 | fs_to_uri("unix", "/", "file:///") 87 | fs_to_uri("unix", "//", "file:///") 88 | fs_to_uri("unix", "///", "file:///") 89 | fs_to_uri("unix", "/foo/bar", "file:///foo/bar") 90 | fs_to_uri("unix", "/foo/bar/", "file:///foo/bar/") 91 | fs_to_uri("unix", "//foo///bar//", "file:///foo/bar/") 92 | fs_to_uri("unix", "/foo bar/%2F", "file:///foo%20bar/%252F") 93 | end 94 | 95 | function testcase:test_fs_to_uri_unix_bad () 96 | -- Relative paths can't be converted to URIs, because URIs are inherently 97 | -- absolute. 98 | assert_error("relative Unix path", 99 | function () FileURI.make_file_uri("foo/bar", "unix") end) 100 | assert_error("relative empty Unix path", 101 | function () FileURI.make_file_uri("", "unix") end) 102 | end 103 | 104 | function testcase:test_uri_to_fs_win32 () 105 | uri_to_fs("win32", "file:///", "\\") 106 | uri_to_fs("win32", "file:///c:", "c:\\") 107 | uri_to_fs("win32", "file:///C:/", "C:\\") 108 | uri_to_fs("win32", "file:///C:/Program%20Files", "C:\\Program Files") 109 | uri_to_fs("win32", "file:///C:/Program%20Files/", "C:\\Program Files\\") 110 | uri_to_fs("win32", "file:///Program%20Files/", "\\Program Files\\") 111 | -- http://blogs.msdn.com/ie/archive/2006/12/06/file-uris-in-windows.aspx 112 | uri_to_fs("win32", "file://laptop/My%20Documents/FileSchemeURIs.doc", 113 | "\\\\laptop\\My Documents\\FileSchemeURIs.doc") 114 | uri_to_fs("win32", 115 | "file:///C:/Documents%20and%20Settings/davris/FileSchemeURIs.doc", 116 | "C:\\Documents and Settings\\davris\\FileSchemeURIs.doc") 117 | -- For backwards compatibility with deprecated way of indicating drives. 118 | uri_to_fs("win32", "file:///c%7C", "c:\\") 119 | uri_to_fs("win32", "file:///c%7C/", "c:\\") 120 | uri_to_fs("win32", "file:///C%7C/foo/", "C:\\foo\\") 121 | end 122 | 123 | function testcase:test_fs_to_uri_win32 () 124 | fs_to_uri("win32", "", "file:///") 125 | fs_to_uri("win32", "\\", "file:///") 126 | fs_to_uri("win32", "c:", "file:///c:/") 127 | fs_to_uri("win32", "C:\\", "file:///C:/") 128 | fs_to_uri("win32", "C:/", "file:///C:/") 129 | fs_to_uri("win32", "C:\\Program Files", "file:///C:/Program%20Files") 130 | fs_to_uri("win32", "C:\\Program Files\\", "file:///C:/Program%20Files/") 131 | fs_to_uri("win32", "C:/Program Files/", "file:///C:/Program%20Files/") 132 | fs_to_uri("win32", "\\Program Files\\", "file:///Program%20Files/") 133 | fs_to_uri("win32", "\\\\laptop\\My Documents\\FileSchemeURIs.doc", 134 | "file://laptop/My%20Documents/FileSchemeURIs.doc") 135 | fs_to_uri("win32", "c:\\foo bar\\%2F", "file:///c:/foo%20bar/%252F") 136 | end 137 | 138 | function testcase:test_convert_on_unknown_os () 139 | local uri = assert(URI:new("file:///foo")) 140 | assert_error("filesystem_path, unknown os", 141 | function () uri:filesystem_path("NonExistent") end) 142 | assert_error("make_file_uri, unknown os", 143 | function () URIFile.make_file_uri("/foo", "NonExistent") end) 144 | end 145 | 146 | lunit.run() 147 | -- vi:ts=4 sw=4 expandtab 148 | -------------------------------------------------------------------------------- /test/ftp.lua: -------------------------------------------------------------------------------- 1 | require "uri-test" 2 | local URI = require "uri" 3 | local testcase = TestCase("Test uri.ftp") 4 | 5 | function testcase:test_ftp () 6 | local uri = assert(URI:new("ftp://ftp.example.com/path")) 7 | is("ftp", uri:scheme()) 8 | is("ftp.example.com", uri:host()) 9 | is(21, uri:port()) 10 | is(nil, uri:userinfo()) 11 | is(nil, uri:username()) 12 | is(nil, uri:password()) 13 | end 14 | 15 | function testcase:test_ftp_typecode () 16 | local uri = assert(URI:new("ftp://host/path")) 17 | is(nil, uri:ftp_typecode()) 18 | is(nil, uri:ftp_typecode("d")) 19 | is("/path;type=d", uri:path()) 20 | is("ftp://host/path;type=d", tostring(uri)) 21 | is("d", uri:ftp_typecode("a")) 22 | is("/path;type=a", uri:path()) 23 | is("ftp://host/path;type=a", tostring(uri)) 24 | is("a", uri:ftp_typecode("")) 25 | is("/path", uri:path()) 26 | is("ftp://host/path", tostring(uri)) 27 | 28 | local uri = assert(URI:new("ftp://host/path;type=xyzzy")) 29 | is("/path;type=xyzzy", uri:path()) 30 | is("ftp://host/path;type=xyzzy", tostring(uri)) 31 | is("xyzzy", uri:ftp_typecode()) 32 | is("xyzzy", uri:ftp_typecode(nil)) 33 | is(nil, uri:ftp_typecode()) 34 | is("/path", uri:path()) 35 | is("ftp://host/path", tostring(uri)) 36 | end 37 | 38 | function testcase:test_normalize_path () 39 | local uri = assert(URI:new("ftp://host")) 40 | is("ftp://host/", tostring(uri)) 41 | is("/", uri:path("/foo")) 42 | is("/foo", uri:path("")) 43 | is("/", uri:path("/foo")) 44 | is("/foo", uri:path(nil)) 45 | is("/", uri:path()) 46 | end 47 | 48 | function testcase:test_bad_host () 49 | is_bad_uri("missing authority, just scheme", "ftp:") 50 | is_bad_uri("missing authority, just scheme and path", "ftp:/foo") 51 | is_bad_uri("empty host", "ftp:///foo") 52 | end 53 | 54 | lunit.run() 55 | -- vi:ts=4 sw=4 expandtab 56 | -------------------------------------------------------------------------------- /test/http.lua: -------------------------------------------------------------------------------- 1 | require "uri-test" 2 | local URI = require "uri" 3 | local testcase = TestCase("Test uri.http and uri.https") 4 | 5 | function testcase:test_http () 6 | local uri = assert(URI:new("HTtp://FOo/Blah?Search#Id")) 7 | is("uri.http", uri._NAME) 8 | is("http://foo/Blah?Search#Id", uri:uri()) 9 | is("http://foo/Blah?Search#Id", tostring(uri)) 10 | is("http", uri:scheme()) 11 | is("foo", uri:host()) 12 | is(80, uri:port()) 13 | is("/Blah", uri:path()) 14 | is(nil, uri:userinfo()) 15 | is("Search", uri:query()) 16 | is("Id", uri:fragment()) 17 | end 18 | 19 | function testcase:test_https () 20 | local uri = assert(URI:new("HTtpS://FOo/Blah?Search#Id")) 21 | is("uri.https", uri._NAME) 22 | is("https://foo/Blah?Search#Id", uri:uri()) 23 | is("https://foo/Blah?Search#Id", tostring(uri)) 24 | is("https", uri:scheme()) 25 | is("foo", uri:host()) 26 | is(443, uri:port()) 27 | is("/Blah", uri:path()) 28 | is(nil, uri:userinfo()) 29 | is("Search", uri:query()) 30 | is("Id", uri:fragment()) 31 | end 32 | 33 | function testcase:test_http_port () 34 | local uri = assert(URI:new("http://example.com:8080/foo")) 35 | is(8080, uri:port()) 36 | local old = uri:port(1234) 37 | is(8080, old) 38 | is(1234, uri:port()) 39 | is("http://example.com:1234/foo", tostring(uri)) 40 | old = uri:port(80) 41 | is(1234, old) 42 | is(80, uri:port()) 43 | is("http://example.com/foo", tostring(uri)) 44 | end 45 | 46 | function testcase:test_normalize_port () 47 | local uri = assert(URI:new("http://foo:80/")) 48 | is("http://foo/", tostring(uri)) 49 | is(80, uri:port()) 50 | uri = assert(URI:new("http://foo:443/")) 51 | is("http://foo:443/", tostring(uri)) 52 | is(443, uri:port()) 53 | uri = assert(URI:new("https://foo:443/")) 54 | is("https://foo/", tostring(uri)) 55 | is(443, uri:port()) 56 | uri = assert(URI:new("https://foo:80/")) 57 | is("https://foo:80/", tostring(uri)) 58 | is(80, uri:port()) 59 | end 60 | 61 | function testcase:test_set_userinfo () 62 | local uri = assert(URI:new("http://host/path")) 63 | assert_error("can't set userinfo", function () uri:userinfo("x") end) 64 | end 65 | 66 | lunit.run() 67 | -- vi:ts=4 sw=4 expandtab 68 | -------------------------------------------------------------------------------- /test/pop.lua: -------------------------------------------------------------------------------- 1 | require "uri-test" 2 | local URI = require "uri" 3 | local testcase = TestCase("Test uri.pop") 4 | 5 | function testcase:test_pop_parse_1 () 6 | local uri = assert(URI:new("Pop://rg@MAILSRV.qualcomm.COM")) 7 | is("pop://rg@mailsrv.qualcomm.com", tostring(uri)) 8 | is("pop", uri:scheme()) 9 | is("rg", uri:userinfo()) 10 | is("mailsrv.qualcomm.com", uri:host()) 11 | is(110, uri:port()) 12 | is("rg", uri:pop_user()) 13 | is("*", uri:pop_auth()) 14 | end 15 | 16 | function testcase:test_pop_parse_2 () 17 | local uri = assert(URI:new("pop://rg;AUTH=+APOP@mail.eudora.com:8110")) 18 | is("pop://rg;auth=+APOP@mail.eudora.com:8110", tostring(uri)) 19 | is("rg;auth=+APOP", uri:userinfo()) 20 | is("mail.eudora.com", uri:host()) 21 | is(8110, uri:port()) 22 | is("rg", uri:pop_user()) 23 | is("+APOP", uri:pop_auth()) 24 | end 25 | 26 | function testcase:test_pop_parse_3 () 27 | local uri = assert(URI:new("pop://baz;AUTH=SCRAM-MD5@foo.bar")) 28 | is("pop://baz;auth=SCRAM-MD5@foo.bar", tostring(uri)) 29 | is("baz;auth=SCRAM-MD5", uri:userinfo()) 30 | is("foo.bar", uri:host()) 31 | is(110, uri:port()) 32 | is("baz", uri:pop_user()) 33 | is("SCRAM-MD5", uri:pop_auth()) 34 | end 35 | 36 | function testcase:test_pop_normalize () 37 | local uri = assert(URI:new("Pop://Baz;Auth=*@Foo.Bar:110")) 38 | is("pop://Baz@foo.bar", tostring(uri)) 39 | is("Baz", uri:userinfo()) 40 | is("foo.bar", uri:host()) 41 | is(110, uri:port()) 42 | is("Baz", uri:pop_user()) 43 | is("*", uri:pop_auth()) 44 | end 45 | 46 | function testcase:test_pop_set_user () 47 | local uri = assert(URI:new("pop://host")) 48 | is(nil, uri:pop_user("foo ;bar")) 49 | is("pop://foo%20%3Bbar@host", tostring(uri)) 50 | assert_error("empty user not allowed", function () uri:pop_user("") end) 51 | is("foo ;bar", uri:pop_user(nil)) 52 | is(nil, uri:pop_user()) 53 | is("pop://host", tostring(uri)) 54 | end 55 | 56 | function testcase:test_pop_set_user_bad () 57 | local uri = assert(URI:new("pop://foo@host")) 58 | assert_error("empty user not allowed", function () uri:pop_user("") end) 59 | is("foo", uri:pop_user()) 60 | is("pop://foo@host", tostring(uri)) 61 | uri = assert(URI:new("pop://foo;auth=+APOP@host")) 62 | assert_error("user required when auth specified", 63 | function () uri:pop_user(nil) end) 64 | is("foo", uri:pop_user()) 65 | is("+APOP", uri:pop_auth()) 66 | is("pop://foo;auth=+APOP@host", tostring(uri)) 67 | end 68 | 69 | function testcase:test_pop_set_auth () 70 | local uri = assert(URI:new("pop://user@host")) 71 | is("*", uri:pop_auth("foo ;bar")) 72 | is("pop://user;auth=foo%20%3Bbar@host", tostring(uri)) 73 | is("foo ;bar", uri:pop_auth("*")) 74 | is("*", uri:pop_auth()) 75 | is("pop://user@host", tostring(uri)) 76 | end 77 | 78 | function testcase:test_pop_set_auth_bad () 79 | local uri = assert(URI:new("pop://host")) 80 | assert_error("auth not allowed without user", 81 | function () uri:pop_auth("+APOP") end) 82 | uri:pop_user("user") 83 | assert_error("empty auth not allowed", function () uri:pop_auth("") end) 84 | assert_error("nil auth not allowed", function () uri:pop_auth(nil) end) 85 | is("pop://user@host", tostring(uri)) 86 | end 87 | 88 | function testcase:test_pop_bad_syntax () 89 | is_bad_uri("path not empty", "pop://foo@host/") 90 | is_bad_uri("user empty", "pop://@host") 91 | is_bad_uri("user empty with auth", "pop://;auth=+APOP@host") 92 | is_bad_uri("auth empty", "pop://user;auth=@host") 93 | end 94 | 95 | function testcase:test_set_userinfo () 96 | local uri = assert(URI:new("pop://host")) 97 | is(nil, uri:userinfo("foo ;bar")) 98 | is("pop://foo%20%3Bbar@host", tostring(uri)) 99 | is("foo%20%3Bbar", uri:userinfo("foo;auth=+APOP")) 100 | is("pop://foo;auth=+APOP@host", tostring(uri)) 101 | is("foo;auth=+APOP", uri:userinfo("foo;AUTH=+APOP")) 102 | is("pop://foo;auth=+APOP@host", tostring(uri)) 103 | is("foo;auth=+APOP", uri:userinfo("bar;auth=*")) 104 | is("pop://bar@host", tostring(uri)) 105 | is("bar", uri:userinfo(nil)) 106 | is("pop://host", tostring(uri)) 107 | end 108 | 109 | function testcase:test_set_userinfo_bad () 110 | local uri = assert(URI:new("pop://host")) 111 | assert_error("empty userinfo", function () uri:userinfo("") end) 112 | assert_error("empty user with auth", 113 | function () uri:userinfo(";auth=*") end) 114 | assert_error("empty auth on its own", 115 | function () uri:userinfo(";auth=") end) 116 | assert_error("empty auth with user", 117 | function () uri:userinfo("foo;auth=") end) 118 | end 119 | 120 | function testcase:test_set_path () 121 | local uri = assert(URI:new("pop://host")) 122 | is("", uri:path("")) 123 | is("", uri:path(nil)) 124 | is("", uri:path()) 125 | assert_error("non-empty path", function () uri:path("/") end) 126 | end 127 | 128 | lunit.run() 129 | -- vi:ts=4 sw=4 expandtab 130 | -------------------------------------------------------------------------------- /test/rtsp.lua: -------------------------------------------------------------------------------- 1 | require "uri-test" 2 | local URI = require "uri" 3 | local testcase = TestCase("Test uri.rtsp and uri.rtspu") 4 | 5 | function testcase:test_rtsp () 6 | local u = assert(URI:new("RTSP://MEDIA.EXAMPLE.COM:554/twister/audiotrack")) 7 | is("rtsp://media.example.com/twister/audiotrack", tostring(u)) 8 | is("media.example.com", u:host()) 9 | is("/twister/audiotrack", u:path()) 10 | end 11 | 12 | function testcase:test_rtspu () 13 | local uri = assert(URI:new("rtspu://media.perl.com/f%C3%B4o.smi/")) 14 | is("rtspu://media.perl.com/f%C3%B4o.smi/", tostring(uri)) 15 | is("media.perl.com", uri:host()) 16 | is("/f%C3%B4o.smi/", uri:path()) 17 | end 18 | 19 | function testcase:test_switch_scheme () 20 | -- Should be no problem switching between TCP and UDP URIs, because they 21 | -- have the same syntax. 22 | local uri = assert(URI:new("rtsp://media.example.com/twister/audiotrack")) 23 | is("rtsp://media.example.com/twister/audiotrack", tostring(uri)) 24 | is("rtsp", uri:scheme("rtspu")) 25 | is("rtspu://media.example.com/twister/audiotrack", tostring(uri)) 26 | is("rtspu", uri:scheme("rtsp")) 27 | is("rtsp://media.example.com/twister/audiotrack", tostring(uri)) 28 | is("rtsp", uri:scheme()) 29 | end 30 | 31 | function testcase:test_rtsp_default_port () 32 | local uri = assert(URI:new("rtsp://host/path/")) 33 | is(554, uri:port()) 34 | uri = assert(URI:new("rtspu://host/path/")) 35 | is(554, uri:port()) 36 | 37 | is(554, uri:port(8554)) 38 | is("rtspu://host:8554/path/", tostring(uri)) 39 | is(8554, uri:port(554)) 40 | is("rtspu://host/path/", tostring(uri)) 41 | end 42 | 43 | lunit.run() 44 | -- vi:ts=4 sw=4 expandtab 45 | -------------------------------------------------------------------------------- /test/telnet.lua: -------------------------------------------------------------------------------- 1 | require "uri-test" 2 | local URI = require "uri" 3 | local testcase = TestCase("Test uri.telnet and uri._login") 4 | 5 | -- This tests the generic login stuff ('username' and 'password' methods, and 6 | -- additional userinfo validation), as well as the stuff specific to telnet. 7 | 8 | function testcase:test_telnet () 9 | local uri = assert(URI:new("telnet://telnet.example.com/")) 10 | is("telnet://telnet.example.com/", uri:uri()) 11 | is("telnet://telnet.example.com/", tostring(uri)) 12 | is("uri.telnet", uri._NAME) 13 | is("telnet", uri:scheme()) 14 | is("telnet.example.com", uri:host()) 15 | is("/", uri:path()) 16 | end 17 | 18 | function testcase:test_telnet_normalize () 19 | local uri = assert(URI:new("telnet://user:password@host.com")) 20 | is("telnet://user:password@host.com/", tostring(uri)) 21 | is("/", uri:path()) 22 | is(23, uri:port()) 23 | uri = assert(URI:new("telnet://user:password@host.com:23/")) 24 | is("telnet://user:password@host.com/", tostring(uri)) 25 | is("/", uri:path()) 26 | is(23, uri:port()) 27 | end 28 | 29 | function testcase:test_telnet_invalid () 30 | is_bad_uri("no authority, empty path", "telnet:") 31 | is_bad_uri("no authority, normal path", "telnet:/") 32 | is_bad_uri("empty authority, empty path", "telnet://") 33 | is_bad_uri("empty authority, normal path", "telnet:///") 34 | is_bad_uri("bad path /x", "telnet://host/x") 35 | is_bad_uri("bad path //", "telnet://host//") 36 | end 37 | 38 | function testcase:test_telnet_set_path () 39 | local uri = assert(URI:new("telnet://foo/")) 40 | is("/", uri:path("/")) 41 | is("/", uri:path("")) 42 | is("/", uri:path(nil)) 43 | is("/", uri:path()) 44 | end 45 | 46 | function testcase:test_telnet_set_bad_path () 47 | local uri = assert(URI:new("telnet://foo/")) 48 | assert_error("bad path x", function () uri:path("x") end) 49 | assert_error("bad path /x", function () uri:path("/x") end) 50 | assert_error("bad path //", function () uri:path("//") end) 51 | end 52 | 53 | -- These test the generic stuff in uri._login. Some of the examples are 54 | -- directly from RFC 1738 section 3.1, but substituting 'telnet' for 'ftp'. 55 | function testcase:test_telnet_userinfo () 56 | local uri = assert(URI:new("telnet://host.com/")) 57 | is(nil, uri:userinfo()) 58 | is(nil, uri:username()) 59 | is(nil, uri:password()) 60 | uri = assert(URI:new("telnet://foo:bar@host.com/")) 61 | is("foo:bar", uri:userinfo()) 62 | is("foo", uri:username()) 63 | is("bar", uri:password()) 64 | uri = assert(URI:new("telnet://%3a%40:%3a%40@host.com/")) 65 | is("%3A%40:%3A%40", uri:userinfo()) 66 | is(":@", uri:username()) 67 | is(":@", uri:password()) 68 | uri = assert(URI:new("telnet://foo:@host.com/")) 69 | is("foo:", uri:userinfo()) 70 | is("foo", uri:username()) 71 | is("", uri:password()) 72 | uri = assert(URI:new("telnet://@host.com/")) 73 | is("", uri:userinfo()) 74 | is("", uri:username()) 75 | is(nil, uri:password()) 76 | uri = assert(URI:new("telnet://:@host.com/")) 77 | is(":", uri:userinfo()) 78 | is("", uri:username()) 79 | is("", uri:password()) 80 | end 81 | 82 | function testcase:test_telnet_set_userinfo () 83 | local uri = assert(URI:new("telnet://host.com/")) 84 | is(nil, uri:userinfo("")) 85 | is("telnet://@host.com/", tostring(uri)) 86 | is("", uri:userinfo(":")) 87 | is("telnet://:@host.com/", tostring(uri)) 88 | is(":", uri:userinfo("foo:")) 89 | is("telnet://foo:@host.com/", tostring(uri)) 90 | is("foo:", uri:userinfo(":bar")) 91 | is("telnet://:bar@host.com/", tostring(uri)) 92 | is(":bar", uri:userinfo("foo:bar")) 93 | is("telnet://foo:bar@host.com/", tostring(uri)) 94 | is("foo:bar", uri:userinfo()) 95 | end 96 | 97 | function testcase:test_telnet_set_bad_userinfo () 98 | local uri = assert(URI:new("telnet://host.com/")) 99 | assert_error("more than one colon", function () uri:userinfo("x::y") end) 100 | assert_error("invalid character", function () uri:userinfo("x/y") end) 101 | end 102 | 103 | function testcase:test_telnet_set_username () 104 | local uri = assert(URI:new("telnet://host.com/")) 105 | is(nil, uri:username("foo")) 106 | is(nil, uri:password()) 107 | is("telnet://foo@host.com/", tostring(uri)) 108 | is("foo", uri:username("x:y@z%")) 109 | is(nil, uri:password()) 110 | is("telnet://x%3Ay%40z%25@host.com/", tostring(uri)) 111 | is("x:y@z%", uri:username("")) 112 | is(nil, uri:password()) 113 | is("telnet://@host.com/", tostring(uri)) 114 | is("", uri:username(nil)) 115 | is(nil, uri:password()) 116 | is("telnet://host.com/", tostring(uri)) 117 | is(nil, uri:username()) 118 | end 119 | 120 | function testcase:test_telnet_set_password () 121 | local uri = assert(URI:new("telnet://host.com/")) 122 | is(nil, uri:password("foo")) 123 | is("", uri:username()) 124 | is("telnet://:foo@host.com/", tostring(uri)) 125 | is("foo", uri:password("x:y@z%")) 126 | is("", uri:username()) 127 | is("telnet://:x%3Ay%40z%25@host.com/", tostring(uri)) 128 | is("x:y@z%", uri:password("")) 129 | is("", uri:username()) 130 | is("telnet://:@host.com/", tostring(uri)) 131 | is("", uri:password(nil)) 132 | is("", uri:username()) 133 | is("telnet://@host.com/", tostring(uri)) 134 | is("", uri:username(nil)) 135 | is(nil, uri:password(nil)) 136 | is("telnet://host.com/", tostring(uri)) 137 | is(nil, uri:password()) 138 | end 139 | 140 | lunit.run() 141 | -- vi:ts=4 sw=4 expandtab 142 | -------------------------------------------------------------------------------- /test/urn-isbn.lua: -------------------------------------------------------------------------------- 1 | require "uri-test" 2 | local URI = require "uri" 3 | local Util = require "uri._util" 4 | local testcase = TestCase("Test uri.urn.isbn") 5 | 6 | local have_isbn_module = Util.attempt_require("isbn") 7 | 8 | function testcase:test_isbn () 9 | -- Example from RFC 2288 10 | local u = URI:new("URN:ISBN:0-395-36341-1") 11 | is(have_isbn_module and "urn:isbn:0-395-36341-1" or "urn:isbn:0395363411", 12 | u:uri()) 13 | is("urn", u:scheme()) 14 | is("isbn", u:nid()) 15 | is(have_isbn_module and "0-395-36341-1" or "0395363411", u:nss()) 16 | is("0395363411", u:isbn_digits()) 17 | 18 | u = URI:new("URN:ISBN:0395363411") 19 | is(have_isbn_module and "urn:isbn:0-395-36341-1" or "urn:isbn:0395363411", 20 | u:uri()) 21 | is("urn", u:scheme()) 22 | is("isbn", u:nid()) 23 | is(have_isbn_module and "0-395-36341-1" or "0395363411", u:nss()) 24 | is("0395363411", u:isbn_digits()) 25 | 26 | if have_isbn_module then 27 | local isbn = u:isbn() 28 | assert_table(isbn) 29 | is("0-395-36341-1", tostring(isbn)) 30 | is("0", isbn:group_code()) 31 | is("395", isbn:publisher_code()) 32 | is("978-0-395-36341-6", tostring(isbn:as_isbn13())) 33 | end 34 | 35 | assert_true(URI.eq("urn:isbn:088730866x", "URN:ISBN:0-88-73-08-66-X")) 36 | end 37 | 38 | function testcase:test_set_nss () 39 | local uri = assert(URI:new("urn:isbn:039-53-63411")) 40 | is(have_isbn_module and "0-395-36341-1" or "0395363411", 41 | uri:nss("088-7308-66x")) 42 | is(have_isbn_module and "urn:isbn:0-88730-866-X" or "urn:isbn:088730866X", 43 | tostring(uri)) 44 | is(have_isbn_module and "0-88730-866-X" or "088730866X", uri:nss()) 45 | end 46 | 47 | function testcase:test_set_bad_nss () 48 | local uri = assert(URI:new("urn:ISBN:039-53-63411")) 49 | assert_error("set NSS to non-string value", function () uri:nss({}) end) 50 | assert_error("set NSS to empty", function () uri:nss("") end) 51 | assert_error("set NSS to wrong length", function () uri:nss("123") end) 52 | 53 | -- None of that should have had any affect 54 | is(have_isbn_module and "urn:isbn:0-395-36341-1" or "urn:isbn:0395363411", 55 | tostring(uri)) 56 | is(have_isbn_module and "0-395-36341-1" or "0395363411", uri:nss()) 57 | is("0395363411", uri:isbn_digits()) 58 | is("uri.urn.isbn", uri._NAME) 59 | end 60 | 61 | function testcase:test_set_path () 62 | local uri = assert(URI:new("urn:ISBN:039-53-63411")) 63 | is(have_isbn_module and "isbn:0-395-36341-1" or "isbn:0395363411", 64 | uri:path("ISbn:088-73-0866x")) 65 | is(have_isbn_module and "urn:isbn:0-88730-866-X" or "urn:isbn:088730866X", 66 | tostring(uri)) 67 | 68 | assert_error("bad path", function () uri:path("isbn:1234567") end) 69 | is(have_isbn_module and "urn:isbn:0-88730-866-X" or "urn:isbn:088730866X", 70 | tostring(uri)) 71 | is(have_isbn_module and "isbn:0-88730-866-X" or "isbn:088730866X", 72 | uri:path()) 73 | end 74 | 75 | function testcase:test_isbn_setting_digits () 76 | local u = assert(URI:new("URN:ISBN:0395363411")) 77 | local old = u:isbn_digits("0-88730-866-x") 78 | is("0395363411", old) 79 | is("088730866X", u:isbn_digits()) 80 | is(have_isbn_module and "0-88730-866-X" or "088730866X", u:nss()) 81 | if have_isbn_module then 82 | is("0-88730-866-X", tostring(u:isbn())) 83 | end 84 | end 85 | 86 | function testcase:test_isbn_setting_object () 87 | if have_isbn_module then 88 | local ISBN = require "isbn" 89 | local u = assert(URI:new("URN:ISBN:0395363411")) 90 | local old = u:isbn(ISBN:new("0-88730-866-x")) 91 | assert_table(old) 92 | is("0-395-36341-1", tostring(old)) 93 | is("088730866X", u:isbn_digits()) 94 | is("0-88730-866-X", u:nss()) 95 | local new = u:isbn() 96 | assert_table(new) 97 | is("0-88730-866-X", tostring(new)) 98 | end 99 | end 100 | 101 | function testcase:test_illegal_isbn () 102 | is_bad_uri("invalid characters", "urn:ISBN:abc") 103 | if have_isbn_module then 104 | is_bad_uri("bad checksum", "urn:isbn:0395363412") 105 | is_bad_uri("wrong length", "urn:isbn:03953634101") 106 | end 107 | end 108 | 109 | lunit.run() 110 | -- vi:ts=4 sw=4 expandtab 111 | -------------------------------------------------------------------------------- /test/urn-issn.lua: -------------------------------------------------------------------------------- 1 | require "uri-test" 2 | local URI = require "uri" 3 | local testcase = TestCase("Test uri.urn.issn") 4 | 5 | local good_issn_digits = { 6 | "02613077", -- The Guardian 7 | "14734966", -- Photography Monthly 8 | 9 | -- From the Wikipedia article on ISSN. 10 | "03178471", 11 | "15340481", 12 | 13 | -- From RFC 3044 section 5. 14 | "0259000X", 15 | "15601560", 16 | } 17 | 18 | function testcase:test_parse_and_normalize () 19 | local uri = assert(URI:new("urn:ISSN:1560-1560")) 20 | is("uri.urn.issn", uri._NAME) 21 | is("urn:issn:1560-1560", uri:uri()) 22 | is("15601560", uri:issn_digits()) 23 | uri = assert(URI:new("URN:Issn:0259-000X")) 24 | is("urn:issn:0259-000X", uri:uri()) 25 | is("0259000X", uri:issn_digits()) 26 | uri = assert(URI:new("urn:issn:0259000x")) 27 | is("urn:issn:0259-000X", uri:uri()) 28 | is("0259000X", uri:issn_digits()) 29 | end 30 | 31 | function testcase:test_bad_syntax () 32 | is_bad_uri("too many digits", "urn:issn:026130707") 33 | is_bad_uri("not enough digits", "urn:issn:0261377") 34 | is_bad_uri("too many hyphens in middle", "urn:issn:0261--3077") 35 | is_bad_uri("hyphen in wrong place", "urn:issn:026-13077") 36 | is_bad_uri("X digit in wrong place", "urn:issn:025900X0") 37 | end 38 | 39 | -- Try all the known-good sequences of digits with all possible checksums 40 | -- other than the right one, to make sure they're all detected as errors. 41 | function testcase:test_bad_checksum () 42 | for _, issn in ipairs(good_issn_digits) do 43 | local digits, good_checksum = issn:sub(1, 7), issn:sub(8, 8) 44 | good_checksum = (good_checksum == "X") and 10 or tonumber(good_checksum) 45 | for i = 0, 10 do 46 | if i ~= good_checksum then 47 | local urn = "urn:issn:" .. digits .. (i == 10 and "X" or i) 48 | is_bad_uri("bad checksum in " .. urn, urn) 49 | end 50 | end 51 | end 52 | end 53 | 54 | function testcase:test_set_nss () 55 | local uri = assert(URI:new("urn:issn:0261-3077")) 56 | is("0261-3077", uri:nss("14734966")) 57 | is("urn:issn:1473-4966", tostring(uri)) 58 | is("1473-4966", uri:nss("0259-000x")) 59 | is("urn:issn:0259-000X", tostring(uri)) 60 | is("0259-000X", uri:nss()) 61 | end 62 | 63 | function testcase:test_set_bad_nss () 64 | local uri = assert(URI:new("urn:ISSN:02613077")) 65 | assert_error("set NSS to non-string value", function () uri:nss({}) end) 66 | assert_error("set NSS to empty", function () uri:nss("") end) 67 | assert_error("set NSS to bad char", function () uri:nss("x") end) 68 | 69 | -- None of that should have had any affect 70 | is("urn:issn:0261-3077", tostring(uri)) 71 | is("0261-3077", uri:nss()) 72 | is("02613077", uri:issn_digits()) 73 | is("uri.urn.issn", uri._NAME) 74 | end 75 | 76 | function testcase:test_set_path () 77 | local uri = assert(URI:new("urn:ISSN:02613077")) 78 | is("issn:0261-3077", uri:path("ISsn:14734966")) 79 | is("urn:issn:1473-4966", tostring(uri)) 80 | 81 | assert_error("bad path", function () uri:path("issn:1234567") end) 82 | is("urn:issn:1473-4966", tostring(uri)) 83 | is("issn:1473-4966", uri:path()) 84 | end 85 | 86 | function testcase:test_set_issn_digits () 87 | local uri = assert(URI:new("urn:ISSN:0261-3077")) 88 | is("02613077", uri:issn_digits(nil)) 89 | local old = uri:issn_digits("14734966") 90 | is("02613077", old) 91 | is("14734966", uri:issn_digits()) 92 | is("urn:issn:1473-4966", uri:uri()) 93 | old = uri:issn_digits("0259-000x") 94 | is("14734966", old) 95 | is("0259000X", uri:issn_digits()) 96 | is("urn:issn:0259-000X", uri:uri()) 97 | end 98 | 99 | function testcase:test_set_bad_issn_digits () 100 | local uri = assert(URI:new("urn:ISSN:0261-3077")) 101 | assert_error("set ISSN with bad char", 102 | function () uri:issn_digits("0261-3077Y") end) 103 | assert_error("set ISSN with too many digits", 104 | function () uri:issn_digits("0261-30770") end) 105 | assert_error("set ISSN of empty string", 106 | function () uri:issn_digits("") end) 107 | end 108 | 109 | lunit.run() 110 | -- vi:ts=4 sw=4 expandtab 111 | -------------------------------------------------------------------------------- /test/urn-oid.lua: -------------------------------------------------------------------------------- 1 | require "uri-test" 2 | local URI = require "uri" 3 | local testcase = TestCase("Test uri.urn.oid") 4 | 5 | function testcase:test_parse_and_normalize () 6 | local uri = assert(URI:new("urn:OId:1.3.50403060.0.23")) 7 | is("uri.urn.oid", uri._NAME) 8 | is("urn:oid:1.3.50403060.0.23", uri:uri()) 9 | is("urn:oid:1.3.50403060.0.23", tostring(uri)) 10 | is("oid", uri:nid()) 11 | is("1.3.50403060.0.23", uri:nss()) 12 | is("oid:1.3.50403060.0.23", uri:path()) 13 | assert_array_shallow_equal({ 1, 3, 50403060, 0, 23 }, uri:oid_numbers()) 14 | 15 | -- Examples from RFC 3061 section 3 16 | uri = assert(URI:new("urn:oid:1.3.6.1")) 17 | is("urn:oid:1.3.6.1", tostring(uri)) 18 | assert_array_shallow_equal({ 1, 3, 6, 1 }, uri:oid_numbers()) 19 | uri = assert(URI:new("urn:oid:1.3.6.1.4.1")) 20 | is("urn:oid:1.3.6.1.4.1", tostring(uri)) 21 | assert_array_shallow_equal({ 1, 3, 6, 1, 4, 1 }, uri:oid_numbers()) 22 | uri = assert(URI:new("urn:oid:1.3.6.1.2.1.27")) 23 | is("urn:oid:1.3.6.1.2.1.27", tostring(uri)) 24 | assert_array_shallow_equal({ 1, 3, 6, 1, 2, 1, 27 }, uri:oid_numbers()) 25 | uri = assert(URI:new("URN:OID:0.9.2342.19200300.100.4")) 26 | is("urn:oid:0.9.2342.19200300.100.4", tostring(uri)) 27 | assert_array_shallow_equal({ 0, 9, 2342, 19200300, 100, 4 }, 28 | uri:oid_numbers()) 29 | end 30 | 31 | function testcase:test_bad_syntax () 32 | is_bad_uri("empty nss", "urn:oid:") 33 | is_bad_uri("bad character", "urn:oid:1.2.x.3") 34 | is_bad_uri("missing number", "urn:oid:1.2..3") 35 | is_bad_uri("leading zero", "urn:oid:1.2.03.3") 36 | is_bad_uri("leading zero at start", "urn:oid:01.2.3.3") 37 | end 38 | 39 | function testcase:test_set_nss () 40 | local uri = assert(URI:new("urn:oid:0.1.23")) 41 | is("0.1.23", uri:nss("1")) 42 | is("urn:oid:1", tostring(uri)) 43 | is("1", uri:nss("234252345.340.4.0")) 44 | is("urn:oid:234252345.340.4.0", tostring(uri)) 45 | is("234252345.340.4.0", uri:nss()) 46 | end 47 | 48 | function testcase:test_set_bad_nss () 49 | local uri = assert(URI:new("urn:OID:0.1.23")) 50 | assert_error("set NSS to non-string value", function () uri:nss({}) end) 51 | assert_error("set NSS to empty", function () uri:nss("") end) 52 | assert_error("set NSS to bad char", function () uri:nss("x") end) 53 | 54 | -- None of that should have had any affect 55 | is("urn:oid:0.1.23", tostring(uri)) 56 | is("0.1.23", uri:nss()) 57 | assert_array_shallow_equal({ 0, 1, 23 }, uri:oid_numbers()) 58 | is("uri.urn.oid", uri._NAME) 59 | end 60 | 61 | function testcase:test_set_path () 62 | local uri = assert(URI:new("urn:OID:0.1.23")) 63 | is("oid:0.1.23", uri:path("OId:23.1.0")) 64 | is("urn:oid:23.1.0", tostring(uri)) 65 | 66 | assert_error("bad path", function () uri:path("oid:1.02") end) 67 | is("urn:oid:23.1.0", tostring(uri)) 68 | is("oid:23.1.0", uri:path()) 69 | end 70 | 71 | function testcase:test_set_oid_numbers () 72 | local uri = assert(URI:new("urn:oid:0.1.23")) 73 | assert_array_shallow_equal({ 0, 1, 23 }, uri:oid_numbers({ 1 })) 74 | is("urn:oid:1", tostring(uri)) 75 | assert_array_shallow_equal({ 1 }, uri:oid_numbers({ 234252345, 340, 4, 0 })) 76 | is("urn:oid:234252345.340.4.0", tostring(uri)) 77 | assert_array_shallow_equal({ 234252345, 340, 4, 0 }, 78 | uri:oid_numbers({ 23.42 })) 79 | is("urn:oid:23", tostring(uri)) 80 | assert_array_shallow_equal({ 23 }, uri:oid_numbers()) 81 | end 82 | 83 | function testcase:test_set_bad_oid_numbers () 84 | local uri = assert(URI:new("urn:OID:0.1.23")) 85 | assert_error("set OID numbers to non-table value", 86 | function () uri:oid_numbers("1") end) 87 | assert_error("set OID to empty list of numbers", 88 | function () uri:oid_numbers({}) end) 89 | assert_error("set OID number to negative number", 90 | function () uri:oid_numbers({ -23 }) end) 91 | assert_error("set OID number array containing bad type", 92 | function () uri:oid_numbers({ "x" }) end) 93 | 94 | -- None of that should have had any affect 95 | is("urn:oid:0.1.23", tostring(uri)) 96 | assert_array_shallow_equal({ 0, 1, 23 }, uri:oid_numbers()) 97 | is("uri.urn.oid", uri._NAME) 98 | end 99 | 100 | lunit.run() 101 | -- vi:ts=4 sw=4 expandtab 102 | -------------------------------------------------------------------------------- /test/urn.lua: -------------------------------------------------------------------------------- 1 | require "uri-test" 2 | local URI = require "uri" 3 | local testcase = TestCase("Test uri.urn") 4 | 5 | function testcase:test_urn_parsing () 6 | local uri = assert(URI:new("urn:x-FOO-01239-:Nss")) 7 | is("urn:x-foo-01239-:Nss", uri:uri()) 8 | is("urn", uri:scheme()) 9 | is("x-foo-01239-:Nss", uri:path()) 10 | is("x-foo-01239-", uri:nid()) 11 | is("Nss", uri:nss()) 12 | is(nil, uri:userinfo()) 13 | is(nil, uri:host()) 14 | is(nil, uri:port()) 15 | is(nil, uri:query()) 16 | is(nil, uri:fragment()) 17 | end 18 | 19 | function testcase:test_set_nss () 20 | local uri = assert(URI:new("urn:x-FOO-01239-:Nss")) 21 | is("Nss", uri:nss("FooBar")) 22 | is("urn:x-foo-01239-:FooBar", tostring(uri)) 23 | assert_error("bad NSS, empty", function () uri:nss("") end) 24 | assert_error("bad NSS, illegal character", function () uri:nss('x"y') end) 25 | is("urn:x-foo-01239-:FooBar", tostring(uri)) 26 | end 27 | 28 | function testcase:test_bad_urn_syntax () 29 | is_bad_uri("missing nid", "urn::bar") 30 | is_bad_uri("hyphen at start of nid", "urn:-x-foo:bar") 31 | is_bad_uri("plus in middle of nid", "urn:x+foo:bar") 32 | is_bad_uri("underscore in middle of nid", "urn:x_foo:bar") 33 | is_bad_uri("dot in middle of nid", "urn:x.foo:bar") 34 | is_bad_uri("nid too long", "urn:x-012345678901234567890123456789x:bar") 35 | is_bad_uri("reserved 'urn' nid", "urn:urn:bar") 36 | is_bad_uri("missing nss", "urn:x-foo:") 37 | is_bad_uri("bad char in nss", "urn:x-foo:bar&") 38 | is_bad_uri("shoudn't have host part", "urn://foo.com/x-foo:bar") 39 | is_bad_uri("shoudn't have query part", "urn:x-foo:bar?baz") 40 | end 41 | 42 | function testcase:test_change_nid () 43 | local urn = assert(URI:new("urn:x-foo:14734966")) 44 | is("urn:x-foo:14734966", tostring(urn)) 45 | is("x-foo", urn:nid()) 46 | is("uri.urn", urn._NAME) 47 | 48 | -- x-foo -> x-bar 49 | is("x-foo", urn:nid("X-BAR")) 50 | is("x-bar", urn:nid()) 51 | is("urn:x-bar:14734966", tostring(urn)) 52 | is("uri.urn", urn._NAME) 53 | 54 | -- x-bar -> issn 55 | is("x-bar", urn:nid("issn")) 56 | is("issn", urn:nid()) 57 | is("urn:issn:1473-4966", tostring(urn)) 58 | is("uri.urn.issn", urn._NAME) 59 | 60 | -- issn -> x-foo 61 | is("issn", urn:nid("x-foo")) 62 | is("x-foo", urn:nid()) 63 | is("urn:x-foo:1473-4966", tostring(urn)) 64 | is("uri.urn", urn._NAME) 65 | end 66 | 67 | function testcase:test_change_nid_bad () 68 | local urn = assert(URI:new("urn:x-foo:frob")) 69 | 70 | -- Try changing the NID to something invalid 71 | assert_error("bad NID 'urn'", function () urn:nid("urn") end) 72 | assert_error("bad NID '-x-foo'", function () urn:nid("-x-foo") end) 73 | assert_error("bad NID 'x+foo'", function () urn:nid("x+foo") end) 74 | 75 | -- Change to valid NID, but where the NSS is not valid for it 76 | assert_error("bad NSS for ISSN URN", function () urn:nid("issn") end) 77 | 78 | -- Original URN should be left unchanged 79 | is("urn:x-foo:frob", tostring(urn)) 80 | is("x-foo", urn:nid()) 81 | is("uri.urn", urn._NAME) 82 | end 83 | 84 | function testcase:test_change_path () 85 | local urn = assert(URI:new("urn:x-foo:foopath")) 86 | is("x-foo:foopath", urn:path()) 87 | 88 | -- x-foo -> x-bar 89 | is("x-foo:foopath", urn:path("X-BAR:barpath")) 90 | is("x-bar:barpath", urn:path()) 91 | is("urn:x-bar:barpath", tostring(urn)) 92 | is("uri.urn", urn._NAME) 93 | 94 | -- x-bar -> issn 95 | is("x-bar:barpath", urn:path("issn:14734966")) 96 | is("issn:1473-4966", urn:path()) 97 | is("urn:issn:1473-4966", tostring(urn)) 98 | is("uri.urn.issn", urn._NAME) 99 | 100 | -- issn -> x-foo 101 | is("issn:1473-4966", urn:path("x-foo:foopath2")) 102 | is("x-foo:foopath2", urn:path()) 103 | is("urn:x-foo:foopath2", tostring(urn)) 104 | is("uri.urn", urn._NAME) 105 | end 106 | 107 | function testcase:test_change_path_bad () 108 | local urn = assert(URI:new("urn:x-foo:frob")) 109 | 110 | -- Try changing the NID to something invalid 111 | assert_error("bad NID 'urn'", function () urn:path("urn:frob") end) 112 | assert_error("bad NID '-x-foo'", function () urn:path("-x-foo:frob") end) 113 | assert_error("bad NID 'x+foo'", function () urn:path("x+foo:frob") end) 114 | assert_error("bad NSS, empty", function () urn:path("x-foo:") end) 115 | assert_error("bad NSS, bad char", function () urn:path('x-foo:x"y') end) 116 | 117 | -- Change to valid NID, but where the NSS is not valid for it 118 | assert_error("bad NSS for ISSN URN", function () urn:path("issn:frob") end) 119 | 120 | -- Original URN should be left unchanged 121 | is("urn:x-foo:frob", tostring(urn)) 122 | is("x-foo:frob", urn:path()) 123 | is("x-foo", urn:nid()) 124 | is("frob", urn:nss()) 125 | is("uri.urn", urn._NAME) 126 | end 127 | 128 | function testcase:test_set_disallowed_stuff () 129 | local urn = assert(URI:new("urn:x-foo:frob")) 130 | assert_error("can't set userinfo", function () urn:userinfo("x") end) 131 | assert_error("can't set host", function () urn:host("x") end) 132 | assert_error("can't set port", function () urn:port(23) end) 133 | assert_error("can't set query", function () urn:query("x") end) 134 | end 135 | 136 | lunit.run() 137 | -- vi:ts=4 sw=4 expandtab 138 | -------------------------------------------------------------------------------- /uri-test.lua: -------------------------------------------------------------------------------- 1 | require "lunit" 2 | lunit.import "all" 3 | local URI = require "uri" 4 | 5 | is = assert_equal 6 | 7 | function is_one_of (expecteds, actual, msg) 8 | for _, v in ipairs(expecteds) do 9 | if actual == v then return end 10 | end 11 | 12 | -- Not any of the expected answers matched. In order to report the error 13 | -- usefully, we have to list the alternatives in the error message. 14 | local err = "expected one of {" 15 | for i, v in ipairs(expecteds) do 16 | if i > 1 then err = err .. ", " end 17 | err = err .. "'" .. tostring(v) .. "'" 18 | end 19 | err = err .. "}, but was '" .. tostring(actual) .. "'" 20 | if msg then err = err .. ": " .. msg end 21 | assert_fail(err) 22 | end 23 | 24 | function assert_isa(actual, class) 25 | assert_table(actual) 26 | assert_table(class) 27 | local mt = actual 28 | while true do 29 | mt = getmetatable(mt) 30 | if not mt then error"class not found as metatable at any level" end 31 | if mt == actual then error"circular metatables" end 32 | if mt == class then return nil end 33 | end 34 | end 35 | 36 | function assert_array_shallow_equal (expected, actual, msg) 37 | if not msg then msg = "assert_array_shallow_equal" end 38 | assert_table(actual, msg .. ", is table") 39 | is(#expected, #actual, msg .. ", same size") 40 | if #expected == #actual then 41 | for i = 1, #expected do 42 | is(expected[i], actual[i], msg .. ", element " .. i) 43 | end 44 | end 45 | for key in pairs(actual) do 46 | assert_number(key, msg .. ", non-number key in array") 47 | end 48 | end 49 | 50 | local function _count_hash_pairs (hash) 51 | local count = 0 52 | for _, _ in pairs(hash) do count = count + 1 end 53 | return count 54 | end 55 | 56 | function assert_hash_shallow_equal (expected, actual, msg) 57 | if not msg then msg = "assert_hash_shallow_equal" end 58 | assert_table(actual, msg .. ", is table") 59 | local expsize, actualsize = _count_hash_pairs(expected), 60 | _count_hash_pairs(actual) 61 | is(expsize, actualsize, msg .. ", same size") 62 | if expsize == actualsize then 63 | for k, v in pairs(expected) do 64 | is(expected[k], actual[k], msg .. ", element " .. tostring(k)) 65 | end 66 | end 67 | end 68 | 69 | function is_bad_uri (msg, uri) 70 | local ok, err = URI:new(uri) 71 | assert_nil(ok, msg) 72 | assert_string(err, msg) 73 | end 74 | 75 | function test_norm (expected, input) 76 | local uri = assert(URI:new(input)) 77 | is(expected, uri:uri()) 78 | is(expected, tostring(uri)) 79 | assert_false(uri:is_relative()) 80 | end 81 | 82 | function test_norm_already (input) 83 | test_norm(input, input) 84 | end 85 | 86 | -- vi:ts=4 sw=4 expandtab 87 | -------------------------------------------------------------------------------- /uri/_login.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri._login" } 2 | local Util = require "uri._util" 3 | local URI = require "uri" 4 | Util.subclass_of(M, URI) 5 | 6 | -- Generic terminal logins. This is used as a base class for 'telnet' and 7 | -- 'ftp' URL schemes. 8 | 9 | local function _valid_userinfo (userinfo) 10 | if userinfo then 11 | local colon = userinfo:find(":") 12 | if colon and userinfo:find(":", colon + 1) then 13 | return nil, "only one colon allowed in userinfo" 14 | end 15 | end 16 | return true 17 | end 18 | 19 | -- TODO - this is a bit of a hack because currently subclasses are required 20 | -- to know whether their superclass has one of these that needs calling. 21 | -- It should be called from 'init' before anything more specific is done, 22 | -- and it has the same calling convention. 23 | -- According to RFC 1738 there should be at most one colon in the userinfo. 24 | -- I apply that restriction for schemes where it's used for a username/password 25 | -- pair. 26 | function M.init_base (self) 27 | local host = self:host() 28 | if not host or host == "" then 29 | return nil, "host missing from login URI" 30 | end 31 | 32 | local ok, err = _valid_userinfo(self:userinfo()) 33 | if not ok then return nil, err end 34 | 35 | return self 36 | end 37 | 38 | function M.userinfo (self, ...) 39 | if select("#", ...) > 0 then 40 | local ok, err = _valid_userinfo(...) 41 | if not ok then error("invalid userinfo value (" .. err .. ")") end 42 | end 43 | return M._SUPER.userinfo(self, ...) 44 | end 45 | 46 | function M.username (self, ...) 47 | local info = M._SUPER.userinfo(self) 48 | local old, colon 49 | if info then 50 | local colon = info and info:find(":") 51 | old = colon and info:sub(1, colon - 1) or info 52 | old = Util.uri_decode(old) 53 | end 54 | 55 | if select('#', ...) > 0 then 56 | local pass = colon and info:sub(colon) or "" -- includes colon 57 | local new = ... 58 | if not new then 59 | M._SUPER.userinfo(self, nil) 60 | else 61 | -- Escape anything that's not allowed in a userinfo, and also 62 | -- colon, because that indicates the end of the username. 63 | new = Util.uri_encode(new, "^A-Za-z0-9%-._~!$&'()*+,;=") 64 | M._SUPER.userinfo(self, new .. pass) 65 | end 66 | end 67 | 68 | return old 69 | end 70 | 71 | function M.password (self, ...) 72 | local info = M._SUPER.userinfo(self) 73 | local old, colon 74 | if info then 75 | colon = info and info:find(":") 76 | old = colon and info:sub(colon + 1) or nil 77 | if old then old = Util.uri_decode(old) end 78 | end 79 | 80 | if select('#', ...) > 0 then 81 | local new = ... 82 | local user = colon and info:sub(1, colon - 1) or info 83 | if not new then 84 | M._SUPER.userinfo(self, user) 85 | else 86 | if not user then user = "" end 87 | new = Util.uri_encode(new, "^A-Za-z0-9%-._~!$&'()*+,;=") 88 | M._SUPER.userinfo(self, user .. ":" .. new) 89 | end 90 | end 91 | 92 | return old 93 | end 94 | 95 | return M 96 | -- vi:ts=4 sw=4 expandtab 97 | -------------------------------------------------------------------------------- /uri/_relative.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri._relative" } 2 | local Util = require "uri._util" 3 | local URI = require "uri" 4 | Util.subclass_of(M, URI) 5 | 6 | -- There needs to be an 'init' method in this class, to because the base-class 7 | -- one expects there to be a 'scheme' value. 8 | function M.init (self) 9 | return self 10 | end 11 | 12 | function M.scheme (self, ...) 13 | if select("#", ...) > 0 then 14 | error("relative URI references can't have a scheme, perhaps you" .. 15 | " need to resolve this against an absolute URI instead") 16 | end 17 | return nil 18 | end 19 | 20 | function M.is_relative () return true end 21 | 22 | -- This implements the algorithm from RFC 3986 section 5.2.3 23 | -- Note that this takes an additional argument which appears to be required 24 | -- by the algorithm, but isn't shown when it is used in the RFC. 25 | local function _merge_paths (base, r, base_has_auth) 26 | if base_has_auth and base == "" then 27 | return "/" .. r 28 | end 29 | 30 | return base:gsub("[^/]+$", "", 1) .. r 31 | end 32 | 33 | local function _do_resolve (self, base) 34 | if type(base) == "string" then base = assert(URI:new(base)) end 35 | setmetatable(self, URI) 36 | 37 | if self:host() or self:userinfo() or self:port() then 38 | -- network path reference, just needs a scheme 39 | self:path(Util.remove_dot_segments(self:path())) 40 | self:scheme(base:scheme()) 41 | return 42 | end 43 | 44 | local path = self:path() 45 | if path == "" then 46 | self:path(base:path()) 47 | if not self:query() then self:query(base:query()) end 48 | else 49 | if path:find("^/") then 50 | self:path(Util.remove_dot_segments(path)) 51 | else 52 | local base_has_auth = base:host() or base:userinfo() or base:port() 53 | local merged = _merge_paths(base:path(), path, base_has_auth) 54 | self:path(Util.remove_dot_segments(merged)) 55 | end 56 | end 57 | self:host(base:host()) 58 | self:userinfo(base:userinfo()) 59 | self:port(base:port()) 60 | self:scheme(base:scheme()) 61 | end 62 | 63 | function M.resolve (self, base) 64 | local orig = tostring(self) 65 | local ok, result = pcall(_do_resolve, self, base) 66 | if ok then return end 67 | 68 | -- If the resolving causes an exception, it means that the resulting URI 69 | -- would be invalid, so we restore self to its original state and rethrow 70 | -- the exception. 71 | local restored = assert(URI:new(orig)) 72 | for k in pairs(self) do self[k] = nil end 73 | for k, v in pairs(restored) do self[k] = v end 74 | setmetatable(self, getmetatable(restored)) 75 | error("resolved URI reference would be invalid: " .. result) 76 | end 77 | 78 | function M.relativize (self, base) end -- already relative 79 | 80 | return M 81 | -- vi:ts=4 sw=4 expandtab 82 | -------------------------------------------------------------------------------- /uri/_util.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri._util" } 2 | 3 | -- Build a char->hex map 4 | local escapes = {} 5 | for i = 0, 255 do 6 | escapes[string.char(i)] = string.format("%%%02X", i) 7 | end 8 | 9 | function M.uri_encode (text, patn) 10 | if not text then return end 11 | if not patn then 12 | -- Default unsafe characters. RFC 2732 ^(uric - reserved) 13 | -- TODO - this should be updated to the latest RFC. 14 | patn = "^A-Za-z0-9%-_.!~*'()" 15 | end 16 | return (text:gsub("([" .. patn .. "])", 17 | function (chr) return escapes[chr] end)) 18 | end 19 | 20 | function M.uri_decode (str, patn) 21 | -- Note from RFC1630: "Sequences which start with a percent sign 22 | -- but are not followed by two hexadecimal characters are reserved 23 | -- for future extension" 24 | if not str then return end 25 | if patn then patn = "[" .. patn .. "]" end 26 | return (str:gsub("%%(%x%x)", function (hex) 27 | local char = string.char(tonumber(hex, 16)) 28 | return (patn and not char:find(patn)) and "%" .. hex or char 29 | end)) 30 | end 31 | 32 | -- This is the remove_dot_segments algorithm from RFC 3986 section 5.2.4. 33 | -- The input buffer is 's', the output buffer 'path'. 34 | function M.remove_dot_segments (s) 35 | local path = "" 36 | 37 | while s ~= "" do 38 | if s:find("^%.%.?/") then -- A 39 | s = s:gsub("^%.%.?/", "", 1) 40 | elseif s:find("^/%./") or s == "/." then -- B 41 | s = s:gsub("^/%./?", "/", 1) 42 | elseif s:find("^/%.%./") or s == "/.." then -- C 43 | s = s:gsub("^/%.%./?", "/", 1) 44 | if path:find("/") then 45 | path = path:gsub("/[^/]*$", "", 1) 46 | else 47 | path = "" 48 | end 49 | elseif s == "." or s == ".." then -- D 50 | s = "" 51 | else -- E 52 | local _, p, seg = s:find("^(/?[^/]*)") 53 | s = s:sub(p + 1) 54 | path = path .. seg 55 | end 56 | end 57 | 58 | return path 59 | end 60 | 61 | -- TODO - wouldn't this be better as a method on string? s:split(patn) 62 | function M.split (patn, s, max) 63 | if s == "" then return {} end 64 | 65 | local i, j = 1, string.find(s, patn) 66 | if not j then return { s } end 67 | 68 | local list = {} 69 | while true do 70 | if #list + 1 == max then list[max] = s:sub(i); return list end 71 | list[#list + 1] = s:sub(i, j - 1) 72 | i = j + 1 73 | j = string.find(s, patn, i) 74 | if not j then 75 | list[#list + 1] = s:sub(i) 76 | break 77 | end 78 | end 79 | return list 80 | end 81 | 82 | function M.attempt_require (modname) 83 | local ok, result = pcall(require, modname) 84 | if ok then 85 | return result 86 | elseif type(result) == "string" and 87 | result:find("module '.*' not found") then 88 | return nil 89 | else 90 | error(result) 91 | end 92 | end 93 | 94 | function M.subclass_of (class, baseclass) 95 | class.__index = class 96 | class.__tostring = baseclass.__tostring 97 | class._SUPER = baseclass 98 | setmetatable(class, baseclass) 99 | end 100 | 101 | function M.do_class_changing_change (uri, baseclass, changedesc, newvalue, 102 | changefunc) 103 | local tmpuri = {} 104 | setmetatable(tmpuri, baseclass) 105 | for k, v in pairs(uri) do tmpuri[k] = v end 106 | changefunc(tmpuri, newvalue) 107 | tmpuri._uri = nil 108 | 109 | local foo, err = tmpuri:init() 110 | if not foo then 111 | error("URI not valid after " .. changedesc .. " changed to '" .. 112 | newvalue .. "': " .. err) 113 | end 114 | 115 | setmetatable(uri, getmetatable(tmpuri)) 116 | for k in pairs(uri) do uri[k] = nil end 117 | for k, v in pairs(tmpuri) do uri[k] = v end 118 | end 119 | 120 | function M.uri_part_not_allowed (class, method) 121 | class[method] = function (self, new) 122 | if new then error(method .. " not allowed on this kind of URI") end 123 | return self["_" .. method] 124 | end 125 | end 126 | 127 | return M 128 | -- vi:ts=4 sw=4 expandtab 129 | -------------------------------------------------------------------------------- /uri/data.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.data" } 2 | local Util = require "uri._util" 3 | local URI = require "uri" 4 | Util.subclass_of(M, URI) 5 | 6 | -- This implements the 'data' scheme defined in RFC 2397. 7 | 8 | local Filter = Util.attempt_require("datafilter") 9 | 10 | local function _valid_base64 (data) return data:find("^[0-9a-zA-Z/+]*$") end 11 | 12 | local function _split_path (path) 13 | local _, _, mediatype, data = path:find("^([^,]*),(.*)") 14 | if not mediatype then return "must have comma in path" end 15 | local base64 = false 16 | if mediatype:find(";base64$") then 17 | base64 = true 18 | mediatype = mediatype:sub(1, -8) 19 | end 20 | if base64 and not _valid_base64(data) then 21 | return "illegal character in base64 encoding" 22 | end 23 | return nil, mediatype, base64, data 24 | end 25 | 26 | function M.init (self) 27 | if M._SUPER.host(self) then 28 | return nil, "data URIs may not have authority parts" 29 | end 30 | local err, mediatype, base64, data = _split_path(M._SUPER.path(self)) 31 | if err then return nil, "invalid data URI (" .. err .. ")" end 32 | return self 33 | end 34 | 35 | function M.data_media_type (self, ...) 36 | local _, old, base64, data = _split_path(M._SUPER.path(self)) 37 | 38 | if select('#', ...) > 0 then 39 | local new = ... or "" 40 | new = Util.uri_encode(new, "^A-Za-z0-9%-._~!$&'()*+;=:@/") 41 | if base64 then new = new .. ";base64" end 42 | M._SUPER.path(self, new .. "," .. data) 43 | end 44 | 45 | if old ~= "" then 46 | if old:find("^;") then old = "text/plain" .. old end 47 | return Util.uri_decode(old) 48 | else 49 | return "text/plain;charset=US-ASCII" -- default type 50 | end 51 | end 52 | 53 | local function _urienc_len (s) 54 | local num_unsafe_chars = s:gsub("[A-Za-z0-9%-._~!$&'()*+,;=:@/]", ""):len() 55 | local num_safe_chars = s:len() - num_unsafe_chars 56 | return num_safe_chars + num_unsafe_chars * 3 57 | end 58 | 59 | local function _base64_len (s) 60 | local num_blocks = (s:len() + 2) / 3 61 | num_blocks = num_blocks - num_blocks % 1 62 | return num_blocks * 4 63 | + 7 -- because of ";base64" marker 64 | end 65 | 66 | local function _do_filter (algorithm, input) 67 | return Filter[algorithm](input) 68 | end 69 | 70 | function M.data_bytes (self, ...) 71 | local _, mediatype, base64, old = _split_path(M._SUPER.path(self)) 72 | if base64 then 73 | if not Filter then 74 | error("'datafilter' Lua module required to decode base64 data") 75 | end 76 | old = _do_filter("base64_decode", old) 77 | else 78 | old = Util.uri_decode(old) 79 | end 80 | 81 | if select('#', ...) > 0 then 82 | local new = ... or "" 83 | local urienc_len = _urienc_len(new) 84 | local base64_len = _base64_len(new) 85 | if base64_len < urienc_len and Filter then 86 | mediatype = mediatype .. ";base64" 87 | new = _do_filter("base64_encode", new) 88 | else 89 | new = new:gsub("%%", "%%25") 90 | end 91 | M._SUPER.path(self, mediatype .. "," .. new) 92 | end 93 | 94 | return old 95 | end 96 | 97 | function M.path (self, ...) 98 | local old = M._SUPER.path(self) 99 | 100 | if select('#', ...) > 0 then 101 | local new = ... 102 | if not new then error("there must be a path in a data URI") end 103 | local err = _split_path(new) 104 | if err then error("invalid data URI (" .. err .. ")") end 105 | M._SUPER.path(self, new) 106 | end 107 | 108 | return old 109 | end 110 | 111 | Util.uri_part_not_allowed(M, "userinfo") 112 | Util.uri_part_not_allowed(M, "host") 113 | Util.uri_part_not_allowed(M, "port") 114 | 115 | return M 116 | -- vi:ts=4 sw=4 expandtab 117 | -------------------------------------------------------------------------------- /uri/file.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.file" } 2 | local Util = require "uri._util" 3 | local URI = require "uri" 4 | Util.subclass_of(M, URI) 5 | 6 | function M.init (self) 7 | if self:userinfo() or self:port() then 8 | return nil, "usernames and passwords are not allowed in HTTP URIs" 9 | end 10 | 11 | local host = self:host() 12 | local path = self:path() 13 | if host then 14 | if host:lower() == "localhost" then self:host("") end 15 | else 16 | if not path:find("^/") then 17 | return nil, "file URIs must contain a host, even if it's empty" 18 | end 19 | self:host("") 20 | end 21 | 22 | if path == "" then self:path("/") end 23 | 24 | return self 25 | end 26 | 27 | function M.host (self, ...) 28 | local old = M._SUPER.host(self) 29 | 30 | if select('#', ...) > 0 then 31 | local new = ... 32 | if not new then error("file URIs must have an authority part") end 33 | if new:lower() == "localhost" then new = "" end 34 | M._SUPER.host(self, new) 35 | end 36 | 37 | return old 38 | end 39 | 40 | function M.path (self, ...) 41 | local old = M._SUPER.path(self) 42 | 43 | if select('#', ...) > 0 then 44 | local new = ... 45 | if not new or new == "" then new = "/" end 46 | M._SUPER.path(self, new) 47 | end 48 | 49 | return old 50 | end 51 | 52 | local function _os_implementation (os) 53 | local FileImpl = Util.attempt_require("uri.file." .. os:lower()) 54 | if not FileImpl then 55 | error("no file URI implementation for operating system " .. os) 56 | end 57 | return FileImpl 58 | end 59 | 60 | function M.filesystem_path (self, os) 61 | return _os_implementation(os).filesystem_path(self) 62 | end 63 | 64 | function M.make_file_uri (path, os) 65 | return _os_implementation(os).make_file_uri(path) 66 | end 67 | 68 | Util.uri_part_not_allowed(M, "userinfo") 69 | Util.uri_part_not_allowed(M, "port") 70 | 71 | return M 72 | -- vi:ts=4 sw=4 expandtab 73 | -------------------------------------------------------------------------------- /uri/file/unix.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.file.unix" } 2 | local URI = require "uri" 3 | local Util = require "uri._util" 4 | 5 | function M.filesystem_path (uri) 6 | if uri:host() ~= "" then 7 | error("a file URI with a host name can't be converted to a Unix path") 8 | end 9 | local path = uri:path() 10 | if path:find("%%00") or path:find("%%2F") then 11 | error("Unix paths cannot contain encoded null bytes or slashes") 12 | end 13 | return Util.uri_decode(path) 14 | end 15 | 16 | function M.make_file_uri (path) 17 | if not path:find("^/") then 18 | error("Unix relative paths can't be converted to file URIs") 19 | end 20 | path = path:gsub("//+", "/") 21 | path = Util.uri_encode(path, "^A-Za-z0-9%-._~!$&'()*+,;=:@/") 22 | return assert(URI:new("file://" .. path)) 23 | end 24 | 25 | return M 26 | -- vi:ts=4 sw=4 expandtab 27 | -------------------------------------------------------------------------------- /uri/file/win32.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.file.win32" } 2 | local URI = require "uri" 3 | local Util = require "uri._util" 4 | 5 | function M.filesystem_path (uri) 6 | local host = uri:host() 7 | local path = Util.uri_decode(uri:path()) 8 | if host ~= "" then path = "//" .. host .. path end 9 | if path:find("^/[A-Za-z]|/") or path:find("^/[A-Za-z]|$") then 10 | path = path:gsub("|", ":", 1) 11 | end 12 | if path:find("^/[A-Za-z]:/") then 13 | path = path:sub(2) 14 | elseif path:find("^/[A-Za-z]:$") then 15 | path = path:sub(2) .. "/" 16 | end 17 | path = path:gsub("/", "\\") 18 | return path 19 | end 20 | 21 | function M.make_file_uri (path) 22 | if path:find("^[A-Za-z]:$") then path = path .. "\\" end 23 | local _, _, host, hostpath = path:find("^\\\\([A-Za-z.]+)\\(.*)$") 24 | host = host or "" 25 | hostpath = hostpath or path 26 | hostpath = hostpath:gsub("\\", "/") 27 | :gsub("//+", "/") 28 | hostpath = Util.uri_encode(hostpath, "^A-Za-z0-9%-._~!$&'()*+,;=:@/") 29 | if not hostpath:find("^/") then hostpath = "/" .. hostpath end 30 | return assert(URI:new("file://" .. host .. hostpath)) 31 | end 32 | 33 | return M 34 | -- vi:ts=4 sw=4 expandtab 35 | -------------------------------------------------------------------------------- /uri/ftp.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.ftp" } 2 | local Util = require "uri._util" 3 | local LoginURI = require "uri._login" 4 | Util.subclass_of(M, LoginURI) 5 | 6 | function M.default_port () return 21 end 7 | 8 | function M.init (self) 9 | self, err = M._SUPER.init_base(self) 10 | if not self then return nil, err end 11 | 12 | local host = self:host() 13 | if not host or host == "" then 14 | return nil, "FTP URIs must have a hostname" 15 | end 16 | 17 | -- I don't think there's any distinction in FTP URIs between empty path 18 | -- and the root directory, so probably best to normalize as we do for HTTP. 19 | if self:path() == "" then self:path("/") end 20 | 21 | return self 22 | end 23 | 24 | function M.path (self, ...) 25 | local old = M._SUPER.path(self) 26 | 27 | if select("#", ...) > 0 then 28 | local new = ... 29 | if not new or new == "" then new = "/" end 30 | M._SUPER.path(self, new) 31 | end 32 | 33 | return old 34 | end 35 | 36 | function M.ftp_typecode (self, ...) 37 | local path = M._SUPER.path(self) 38 | local _, _, withouttype, old = path:find("^(.*);type=(.*)$") 39 | if not withouttype then withouttype = path end 40 | if old == "" then old = nil end 41 | 42 | if select("#", ...) > 0 then 43 | local new = ... 44 | if not new then new = "" end 45 | if new ~= "" then new = ";type=" .. new end 46 | M._SUPER.path(self, withouttype .. new) 47 | end 48 | 49 | return old 50 | end 51 | 52 | return M 53 | -- vi:ts=4 sw=4 expandtab 54 | -------------------------------------------------------------------------------- /uri/http.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.http" } 2 | local Util = require "uri._util" 3 | local URI = require "uri" 4 | Util.subclass_of(M, URI) 5 | 6 | -- This implementation is based on RFC 2616 section 3.2 and RFC 1738 7 | -- section 3.3. 8 | -- 9 | -- An HTTP URI with a 'userinfo' field is considered invalid, because it isn't 10 | -- shown in the syntax given in RFC 2616, and is explicitly disallowed by 11 | -- RFC 1738. 12 | 13 | function M.default_port () return 80 end 14 | 15 | function M.init (self) 16 | if self:userinfo() then 17 | return nil, "usernames and passwords are not allowed in HTTP URIs" 18 | end 19 | 20 | -- RFC 2616 section 3.2.3 says that this is OK, but not that using the 21 | -- redundant slash is canonical. I'm adding it because browsers tend to 22 | -- treat the version with the extra slash as the normalized form, and 23 | -- the initial slash is always present in an HTTP GET request. 24 | if self:path() == "" then self:path("/") end 25 | 26 | return self 27 | end 28 | 29 | Util.uri_part_not_allowed(M, "userinfo") 30 | 31 | return M 32 | -- vi:ts=4 sw=4 expandtab 33 | -------------------------------------------------------------------------------- /uri/https.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.https" } 2 | local Util = require "uri._util" 3 | local Http = require "uri.http" 4 | Util.subclass_of(M, Http) 5 | 6 | function M.default_port () return 443 end 7 | 8 | return M 9 | -- vi:ts=4 sw=4 expandtab 10 | -------------------------------------------------------------------------------- /uri/pop.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.pop" } 2 | local URI = require "uri" 3 | local Util = require "uri._util" 4 | Util.subclass_of(M, URI) 5 | 6 | -- This is the set of characters must be encoded in a POP userinfo, which 7 | -- unlike for other schemes includes the ';' character. 8 | local _POP_USERINFO_ENCODE = "^A-Za-z0-9%-._~%%!$&'()*+,=:" 9 | 10 | function M.default_port () return 110 end 11 | 12 | local function _update_userinfo (self, old, new) 13 | if new then 14 | local _, _, user, auth = new:find("^(.*);[Aa][Uu][Tt][Hh]=(.*)$") 15 | if not user then user = new end 16 | if user == "" then return "pop user name must not be empty" end 17 | user = Util.uri_encode(user, _POP_USERINFO_ENCODE) 18 | if auth then 19 | if auth == "" then return "pop auth type must not be empty" end 20 | if auth == "*" then auth = nil end 21 | auth = Util.uri_encode(auth, _POP_USERINFO_ENCODE) 22 | end 23 | new = user .. (auth and ";auth=" .. auth or "") 24 | end 25 | 26 | if new ~= old then M._SUPER.userinfo(self, new) end 27 | return nil 28 | end 29 | 30 | function M.init (self) 31 | if M._SUPER.path(self) ~= "" then 32 | return nil, "pop URIs must have an empty path" 33 | end 34 | 35 | local userinfo = M._SUPER.userinfo(self) 36 | local err = _update_userinfo(self, userinfo, userinfo) 37 | if err then return nil, err end 38 | 39 | return self 40 | end 41 | 42 | function M.userinfo (self, ...) 43 | local old = M._SUPER.userinfo(self) 44 | 45 | if select('#', ...) > 0 then 46 | local new = ... 47 | local err = _update_userinfo(self, old, new) 48 | if err then error(err) end 49 | end 50 | 51 | return old 52 | end 53 | 54 | function M.path (self, new) 55 | if new and new ~= "" then error("POP URIs must have an empty path") end 56 | return "" 57 | end 58 | 59 | local function _decode_userinfo (self) 60 | local old = M._SUPER.userinfo(self) 61 | if not old then return nil, nil end 62 | local _, _, old_user, old_auth = old:find("^(.*);auth=(.*)$") 63 | if not old_user then old_user = old end 64 | return old_user, old_auth 65 | end 66 | 67 | function M.pop_user (self, ...) 68 | local old_user, old_auth = _decode_userinfo(self) 69 | 70 | if select('#', ...) > 0 then 71 | local new = ... 72 | if new == "" then error("pop user name must not be empty") end 73 | if not new and old_auth then 74 | error("pop user name required when an auth type is specified") 75 | end 76 | if new then 77 | new = Util.uri_encode(new, _POP_USERINFO_ENCODE) 78 | if old_auth then new = new .. ";auth=" .. old_auth end 79 | end 80 | M._SUPER.userinfo(self, new) 81 | end 82 | 83 | return Util.uri_decode(old_user) 84 | end 85 | 86 | function M.pop_auth (self, ...) 87 | local old_user, old_auth = _decode_userinfo(self) 88 | 89 | if select('#', ...) > 0 then 90 | local new = ... 91 | if not new or new == "" 92 | then error("pop auth type must not be empty") 93 | end 94 | if new == "*" then new = nil end 95 | if new and not old_user then 96 | error("pop auth type can't be specified without user name") 97 | end 98 | if new then 99 | new = old_user .. ";auth=" .. 100 | Util.uri_encode(new, _POP_USERINFO_ENCODE) 101 | else 102 | new = old_user 103 | end 104 | M._SUPER.userinfo(self, new) 105 | end 106 | 107 | return old_auth and Util.uri_decode(old_auth) or "*" 108 | end 109 | 110 | return M 111 | -- vi:ts=4 sw=4 expandtab 112 | -------------------------------------------------------------------------------- /uri/rtsp.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.rtsp" } 2 | local Util = require "uri._util" 3 | local HttpURI = require "uri.http" 4 | Util.subclass_of(M, HttpURI) 5 | 6 | function M.default_port () return 554 end 7 | 8 | return M 9 | -- vi:ts=4 sw=4 expandtab 10 | -------------------------------------------------------------------------------- /uri/rtspu.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.rtspu" } 2 | local Util = require "uri._util" 3 | local RtspURI = require "uri.rtsp" 4 | Util.subclass_of(M, RtspURI) 5 | 6 | return M 7 | -- vi:ts=4 sw=4 expandtab 8 | -------------------------------------------------------------------------------- /uri/telnet.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.telnet" } 2 | local Util = require "uri._util" 3 | local LoginURI = require "uri._login" 4 | Util.subclass_of(M, LoginURI) 5 | 6 | function M.default_port () return 23 end 7 | 8 | function M.init (self) 9 | self, err = M._SUPER.init_base(self) 10 | if not self then return nil, err end 11 | 12 | -- RFC 4248 does not discuss what a path longer than '/' might mean, and 13 | -- there are no examples with anything significant in the path, so I'm 14 | -- assuming that extra information in the path is not allowed. 15 | local path = M._SUPER.path(self) 16 | if path ~= "" and path ~= "/" then 17 | return nil, "superfluous information in path of telnet URI" 18 | end 19 | 20 | -- RFC 4248 section 2 says that the '/' can be omitted. I chose to 21 | -- normalize to having it there, since the example shown in the RFC has 22 | -- it, and this is consistent with the way I treat HTTP URIs. 23 | if path == "" then self:path("/") end 24 | 25 | return self 26 | end 27 | 28 | -- The path is always '/', so setting it won't do anything, but we do throw 29 | -- an exception on an attempt to set it to anything invalid. 30 | function M.path (self, new) 31 | if new and new ~= "" and new ~= "/" then 32 | error("invalid path for telnet URI") 33 | end 34 | return "/" 35 | end 36 | 37 | return M 38 | -- vi:ts=4 sw=4 expandtab 39 | -------------------------------------------------------------------------------- /uri/urn.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.urn" } 2 | local Util = require "uri._util" 3 | local URI = require "uri" 4 | Util.subclass_of(M, URI) 5 | 6 | -- This implements RFC 2141, and attempts to change the class of the URI object 7 | -- to one of its subclasses for further validation and normalization of the 8 | -- namespace-specific string. 9 | 10 | -- Check NID syntax matches RFC 2141 section 2.1. 11 | local function _valid_nid (nid) 12 | if nid == "" then return nil, "missing completely" end 13 | if nid:len() > 32 then return nil, "too long" end 14 | if not nid:find("^[A-Za-z0-9][-A-Za-z0-9]*$") then 15 | return nil, "contains illegal character" 16 | end 17 | if nid:lower() == "urn" then return nil, "'urn' is reserved" end 18 | return true 19 | end 20 | 21 | -- Check NSS syntax matches RFC 2141 section 2.2. 22 | local function _valid_nss (nss) 23 | if nss == "" then return nil, "can't be empty" end 24 | if nss:find("[^A-Za-z0-9()+,%-.:=@;$_!*'/%%]") then 25 | return nil, "contains illegal character" 26 | end 27 | return true 28 | end 29 | 30 | local function _validate_and_normalize_path (path) 31 | local _, _, nid, nss = path:find("^([^:]+):(.*)$") 32 | if not nid then return nil, "illegal path syntax for URN" end 33 | 34 | local ok, msg = _valid_nid(nid) 35 | if not ok then 36 | return nil, "invalid namespace identifier (" .. msg .. ")" 37 | end 38 | ok, msg = _valid_nss(nss) 39 | if not ok then 40 | return nil, "invalid namespace specific string (" .. msg .. ")" 41 | end 42 | 43 | return nid:lower() .. ":" .. nss 44 | end 45 | 46 | -- TODO - this should check that percent-encoded bytes are valid UTF-8 47 | function M.init (self) 48 | if M._SUPER.query(self) then 49 | return nil, "URNs may not have query parts" 50 | end 51 | if M._SUPER.host(self) then 52 | return nil, "URNs may not have authority parts" 53 | end 54 | 55 | local path, msg = _validate_and_normalize_path(self:path()) 56 | if not path then return nil, msg end 57 | M._SUPER.path(self, path) 58 | 59 | local nid_class 60 | = Util.attempt_require("uri.urn." .. self:nid():gsub("%-", "_")) 61 | if nid_class then 62 | setmetatable(self, nid_class) 63 | if self.init ~= M.init then return self:init() end 64 | end 65 | 66 | return self 67 | end 68 | 69 | function M.nid (self, new) 70 | local _, _, old = self:path():find("^([^:]+)") 71 | 72 | if new then 73 | new = new:lower() 74 | if new ~= old then 75 | local ok, msg = _valid_nid(new) 76 | if not ok then 77 | error("invalid namespace identifier (" .. msg .. ")") 78 | end 79 | end 80 | Util.do_class_changing_change(self, M, "NID", new, function (uri, new) 81 | M._SUPER.path(uri, new .. ":" .. uri:nss()) 82 | end) 83 | end 84 | 85 | return old 86 | end 87 | 88 | function M.nss (self, new) 89 | local _, _, old = self:path():find(":(.*)") 90 | 91 | if new and new ~= old then 92 | local ok, msg = _valid_nss(new) 93 | if not ok then 94 | error("invalid namespace specific string (" .. msg .. ")") 95 | end 96 | M._SUPER.path(self, self:nid() .. ":" .. new) 97 | end 98 | 99 | return old 100 | end 101 | 102 | function M.path (self, new) 103 | local old = M._SUPER.path(self) 104 | 105 | if new and new ~= old then 106 | local path, msg = _validate_and_normalize_path(new) 107 | if not path then 108 | error("invalid path for URN '" .. new .. "' (" ..msg .. ")") 109 | end 110 | local _, _, newnid, newnss = path:find("^([^:]+):(.*)") 111 | if not newnid then error("bad path for URN, no NID part found") end 112 | local ok, msg = _valid_nid(newnid) 113 | if not ok then error("invalid namespace identifier (" .. msg .. ")") end 114 | if newnid:lower() == self:nid() then 115 | self:nss(newnss) 116 | else 117 | Util.do_class_changing_change(self, M, "path", path, 118 | function (uri, new) M._SUPER.path(uri, new) end) 119 | end 120 | end 121 | 122 | return old 123 | end 124 | 125 | Util.uri_part_not_allowed(M, "userinfo") 126 | Util.uri_part_not_allowed(M, "host") 127 | Util.uri_part_not_allowed(M, "port") 128 | Util.uri_part_not_allowed(M, "query") 129 | 130 | return M 131 | -- vi:ts=4 sw=4 expandtab 132 | -------------------------------------------------------------------------------- /uri/urn/isbn.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.urn.isbn" } 2 | local Util = require "uri._util" 3 | local URN = require "uri.urn" 4 | Util.subclass_of(M, URN) 5 | 6 | -- This implements the 'isbn' NID defined in RFC 3187, and is consistent 7 | -- with the same NID suggested in RFC 2288. 8 | 9 | local function _valid_isbn (isbn) 10 | if not isbn:find("^[-%d]+[%dXx]$") then return nil, "invalid character" end 11 | local ISBN = Util.attempt_require("isbn") 12 | if ISBN then return ISBN:new(isbn) end 13 | return isbn 14 | end 15 | 16 | local function _normalize_isbn (isbn) 17 | isbn = isbn:gsub("%-", ""):upper() 18 | local ISBN = Util.attempt_require("isbn") 19 | if ISBN then return tostring(ISBN:new(isbn)) end 20 | return isbn 21 | end 22 | 23 | function M.init (self) 24 | local nss = self:nss() 25 | local ok, msg = _valid_isbn(nss) 26 | if not ok then return nil, "invalid ISBN value (" .. msg .. ")" end 27 | self:nss(_normalize_isbn(nss)) 28 | return self 29 | end 30 | 31 | function M.nss (self, new) 32 | local old = M._SUPER.nss(self) 33 | 34 | if new then 35 | local ok, msg = _valid_isbn(new) 36 | if not ok then 37 | error("bad ISBN value '" .. new .. "' (" .. msg .. ")") 38 | end 39 | M._SUPER.nss(self, _normalize_isbn(new)) 40 | end 41 | 42 | return old 43 | end 44 | 45 | function M.isbn_digits (self, new) 46 | local old = self:nss():gsub("%-", "") 47 | 48 | if new then 49 | local ok, msg = _valid_isbn(new) 50 | if not ok then 51 | error("bad ISBN value '" .. new .. "' (" .. msg .. ")") 52 | end 53 | self._SUPER.nss(self, _normalize_isbn(new)) 54 | end 55 | 56 | return old 57 | end 58 | 59 | function M.isbn (self, new) 60 | local ISBN = require "isbn" 61 | local old = ISBN:new(self:nss()) 62 | if new then self:nss(tostring(new)) end 63 | return old 64 | end 65 | 66 | return M 67 | -- vi:ts=4 sw=4 expandtab 68 | -------------------------------------------------------------------------------- /uri/urn/issn.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.urn.issn" } 2 | local Util = require "uri._util" 3 | local URN = require "uri.urn" 4 | Util.subclass_of(M, URN) 5 | 6 | local function _parse_issn (issn) 7 | local _, _, nums1, nums2, checksum 8 | = issn:find("^(%d%d%d%d)-?(%d%d%d)([%dxX])$") 9 | if checksum == "x" then checksum = "X" end 10 | return nums1, nums2, checksum 11 | end 12 | 13 | local function _valid_issn (issn) 14 | local nums1, nums2, actual_checksum = _parse_issn(issn) 15 | if not nums1 then return nil, "invalid ISSN syntax" end 16 | local nums = nums1 .. nums2 17 | 18 | local expected_checksum = 0 19 | for i = 1, 7 do 20 | expected_checksum = expected_checksum + tonumber(nums:sub(i, i)) * (9 - i) 21 | end 22 | expected_checksum = (11 - expected_checksum % 11) % 11 23 | expected_checksum = (expected_checksum == 10) and "X" 24 | or tostring(expected_checksum) 25 | if actual_checksum ~= expected_checksum then 26 | return nil, "wrong checksum, expected " .. expected_checksum 27 | end 28 | 29 | return true 30 | end 31 | 32 | local function _normalize_issn (issn) 33 | local nums1, nums2, checksum = _parse_issn(issn) 34 | return nums1 .. "-" .. nums2 .. checksum 35 | end 36 | 37 | function M.init (self) 38 | local nss = self:nss() 39 | local ok, msg = _valid_issn(nss) 40 | if not ok then return nil, "bad NSS value for ISSN URI (" .. msg .. ")" end 41 | M._SUPER.nss(self, _normalize_issn(nss)) 42 | return self 43 | end 44 | 45 | function M.nss (self, new) 46 | local old = M._SUPER.nss(self) 47 | 48 | if new then 49 | local ok, msg = _valid_issn(new) 50 | if not ok then 51 | error("bad ISSN value '" .. new .. "' (" .. msg .. ")") 52 | end 53 | M._SUPER.nss(self, _normalize_issn(new)) 54 | end 55 | 56 | return old 57 | end 58 | 59 | function M.issn_digits (self, new) 60 | local old = self:nss(new) 61 | return old:sub(1, 4) .. old:sub(6, 9) 62 | end 63 | 64 | return M 65 | -- vi:ts=4 sw=4 expandtab 66 | -------------------------------------------------------------------------------- /uri/urn/oid.lua: -------------------------------------------------------------------------------- 1 | local M = { _NAME = "uri.urn.oid" } 2 | local Util = require "uri._util" 3 | local URN = require "uri.urn" 4 | Util.subclass_of(M, URN) 5 | 6 | -- This implements RFC 3061. 7 | 8 | local function _valid_oid (oid) 9 | if oid == "" then return nil, "OID can't be zero-length" end 10 | if not oid:find("^[.0-9]*$") then return nil, "bad character in OID" end 11 | if oid:find("%.%.") then return nil, "missing number in OID" end 12 | if oid:find("^0[^.]") or oid:find("%.0[^.]") then 13 | return nil, "OID numbers shouldn't have leading zeros" 14 | end 15 | return true 16 | end 17 | 18 | function M.init (self) 19 | local nss = self:nss() 20 | local ok, msg = _valid_oid(nss) 21 | if not ok then return nil, "bad NSS value for OID URI (" .. msg .. ")" end 22 | return self 23 | end 24 | 25 | function M.nss (self, new) 26 | local old = M._SUPER.nss(self) 27 | 28 | if new then 29 | local ok, msg = _valid_oid(new) 30 | if not ok then 31 | error("bad OID value '" .. new .. "' (" .. msg .. ")") 32 | end 33 | M._SUPER.nss(self, new) 34 | end 35 | 36 | return old 37 | end 38 | 39 | function M.oid_numbers (self, new) 40 | local old = Util.split("%.", self:nss()) 41 | for i = 1, #old do old[i] = tonumber(old[i]) end 42 | 43 | if new then 44 | if type(new) ~= "table" then error("expected array of numbers") end 45 | local nss = "" 46 | for _, n in ipairs(new) do 47 | if type(n) == "string" and n:find("^%d+$") then n = tonumber(n) end 48 | if type(n) ~= "number" then error("bad type for number in OID") end 49 | n = n - n % 1 50 | if n < 0 then error("negative numbers not allowed in OID") end 51 | if nss ~= "" then nss = nss .. "." end 52 | nss = nss .. n 53 | end 54 | if nss == "" then error("no numbers in new OID value") end 55 | self:nss(nss) 56 | end 57 | 58 | return old 59 | end 60 | 61 | return M 62 | -- vi:ts=4 sw=4 expandtab 63 | --------------------------------------------------------------------------------