diff --git a/.travis.yml b/.travis.yml index f88669a7e42d9b0804c784e76d838210ad1350c7..e828daa083980d5f49d9a8351f3228c9369adfb7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,6 @@ install: script: - mkdir ./build && cd ./build && cmake .. -DCMAKE_BUILD_TYPE=RelWithDebugInfo - make -j8 - - make test-force notifications: irc: diff --git a/CMakeLists.txt b/CMakeLists.txt index 2056946f9a33f6fe8f9725a448106207db48fb65..f6281b7ad41999e58516a66f3d8f59bdb4b32fe5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -319,7 +319,6 @@ add_dependencies(build_bundled_libs misc) include(BuildSophia) sophia_build() -set (sophia_lib "${PROJECT_BINARY_DIR}/third_party/sophia/env/libsophia.a") option(ENABLE_RPM "Enable install of a RPM specific files" OFF) diff --git a/cmake/BuildSophia.cmake b/cmake/BuildSophia.cmake index d2af2e5f60e7db5c680ec68a1872a5d3fba54797..65eaccf5dc2c4598b33df838ba5e76e4fcb2c6eb 100644 --- a/cmake/BuildSophia.cmake +++ b/cmake/BuildSophia.cmake @@ -1,13 +1,13 @@ # A macro to build the bundled sophia library # macro(sophia_build) - set(SOPHIA_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/third_party/sophia/env) + set(SOPHIA_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/third_party/sophia/sophia) set(SOPHIA_OPTS CFLAGS="${CMAKE_C_FLAGS}" LDFLAGS="${CMAKE_SHARED_LINKER_FLAGS}") separate_arguments(SOPHIA_OPTS) if (${PROJECT_BINARY_DIR} STREQUAL ${PROJECT_SOURCE_DIR}) - add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/third_party/sophia/env/libsophia.a + add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/third_party/sophia/sophia/libsophia.a WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/sophia COMMAND $(MAKE) ${SOPHIA_OPTS} clean COMMAND $(MAKE) ${SOPHIA_OPTS} static @@ -17,7 +17,7 @@ macro(sophia_build) add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/sophia COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/third_party/sophia ) - add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/sophia/env/libsophia.a + add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/sophia/sophia/libsophia.a WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/third_party/sophia COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/third_party/sophia ${PROJECT_BINARY_DIR}/third_party/sophia COMMAND $(MAKE) ${SOPHIA_OPTS} clean @@ -26,7 +26,8 @@ macro(sophia_build) ) endif() add_custom_target(libsophia ALL - DEPENDS ${PROJECT_BINARY_DIR}/third_party/sophia/env/libsophia.a + DEPENDS ${PROJECT_BINARY_DIR}/third_party/sophia/sophia/libsophia.a ) - message(STATUS "Use bundled sophia: ${SOPHIA_INCLUDE_DIR}") + message(STATUS "Use bundled Sophia: ${SOPHIA_INCLUDE_DIR}") + set (sophia_lib "${PROJECT_BINARY_DIR}/third_party/sophia/sophia/libsophia.a") endmacro(sophia_build) diff --git a/debian/rules b/debian/rules index de1f870a3af838d4533a5536142a36ec6712db20..1ba99320c456dc2632fdd825aa78fb905c23bbc5 100755 --- a/debian/rules +++ b/debian/rules @@ -58,23 +58,11 @@ clean:: rm -f doc/tnt.ent rm -f www-data.in/download -# install/tarantool-dbg:: -# rm -fr debian/tarantool-dbg/usr/share/doc/tarantool-dbg - install/tarantool:: -# pod2man -c 'tarantar' \ -# debian/tarantar.pod > build-area/tarantar.1 -# make -C build-area test-force || /bin/true -# install/tarantool-common:: -# pod2man -c 'tarantool instances control' \ -# debian/tarantool_instance.pod > build-area/tarantool_instance.1 -# pod2man -c 'tarantool log rotation' \ -# debian/scripts/tarantool_logrotate \ -# > build-area/tarantool_logrotate.1 -# pod2man -c 'snapshot rotate' \ -# debian/scripts/tarantool_snapshot_rotate \ -# > build-area/tarantool_snapshot_rotate.1 -# install -m0755 extra/logger.pl \ -# debian/tarantool-common/usr/lib/tarantool/logger +install/tarantool-common:: + sed 's/dist.lua/tarantoolctl/g' extra/dist/dist.lua \ + > ${DEB_BUILDDIR}/tarantoolctl + pod2man -c 'tarantoolctl instances control' \ + ${DEB_BUILDDIR}/tarantoolctl > ${DEB_BUILDDIR}/tarantoolctl.1 diff --git a/debian/tarantool-common.logrotate b/debian/tarantool-common.logrotate index 4fc10a52c0ddaa3f83751666ea5d07e32010e237..7d08ce3cf59ea1e7a7a255be0f3b802e2cef550d 100644 --- a/debian/tarantool-common.logrotate +++ b/debian/tarantool-common.logrotate @@ -7,7 +7,7 @@ delaycompress create 0640 tarantool adm postrotate - /usr/bin/tarantool /usr/lib/tarantool/dist.lua logrotate `basename $1 .log` + /usr/bin/tarantool /usr/bin/tarantoolctl logrotate `basename $1 .log` endscript } diff --git a/debian/tarantool-common.manpages b/debian/tarantool-common.manpages index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..58d0e39064e5094d2d4d4ef45b793c76ffea7dc9 100644 --- a/debian/tarantool-common.manpages +++ b/debian/tarantool-common.manpages @@ -0,0 +1 @@ +build-area/tarantoolctl.1 diff --git a/doc/user/configuration-reference.xml b/doc/user/configuration-reference.xml index 4398484ac8b8b66644556aeec236ee0953a728d7..5a39f48fa1255fdbcbf04c93867626947aa98a3e 100644 --- a/doc/user/configuration-reference.xml +++ b/doc/user/configuration-reference.xml @@ -338,6 +338,65 @@ tarantool: primary pri: 3301 adm: 3313</programlisting> </tbody> </tgroup> </table> + + + <table frame='all' pgwide='1'> + <title>Snapshot daemon</title> + <tgroup cols='5' colsep='1' rowsep='1'> + <colspec colnum="1" colname="col1" colwidth="2*"/> + <colspec colnum="5" colname="col4" colwidth="6*"/> + + <thead> + <row> + <entry>Name</entry> + <entry>Type</entry> + <entry>Default</entry> + <entry>Dynamic?</entry> + <entry>Description</entry> + </row> + </thead> + + <tbody> + + <row> + <entry>snapshot_period</entry> + <entry>float</entry> + <entry>0</entry> + <entry>yes</entry> + <entry> + The interval between actions by the snapshot daemon, in seconds. + The snapshot daemon is a fiber which is constantly running. + If snapshot_period is set to a value greater than zero, + then the snapshot daemon + will call <olink targetptr="box.snapshot"/> every snapshot_period seconds, creating + a new snapshot file each time. + For example, <code>box.cfg{snapshot_period=3600}</code> + will cause the snapshot daemon to create a new database + snapshot once per hour. + </entry> + </row> + + <row> + <entry>snapshot_count</entry> + <entry>float</entry> + <entry>6</entry> + <entry>yes</entry> + <entry> + <para> + The maximum number of snapshots that the snapshot daemon maintains. + For example, <code>box.cfg{snapshot_period=3600, snapshot_count=10}</code> + will cause the snapshot daemon + to create a new snapshot each hour until it has created + ten snapshots. After that, it will remove the oldest + snapshot (and any associated write-ahead-log files) after creating + a new one. If snapshot_count equals zero, then the snapshot + daemon does not remove old snapshots. + </para> + </entry> + </row> + </tbody> + </tgroup> + </table> <table frame='all' pgwide='1'> <title>Binary logging and snapshots</title> @@ -362,7 +421,7 @@ tarantool: primary pri: 3301 adm: 3313</programlisting> <entry>boolean</entry> <entry>true</entry> <entry>no</entry> - <entry>If there is an error reading the snapshot file (at + <entry>If there is an error while reading the snapshot file (at server start), abort.</entry> </row> @@ -371,7 +430,7 @@ tarantool: primary pri: 3301 adm: 3313</programlisting> <entry>boolean</entry> <entry>false</entry> <entry>no</entry> - <entry>If there is an error reading a write-ahead + <entry>If there is an error while reading a write-ahead log file (at server start), abort.</entry> </row> @@ -456,11 +515,17 @@ tarantool: primary pri: 3301 adm: 3313</programlisting> <entry>If replication_source is not an empty string, the server is considered to be a Tarantool replica. The replica server will try to connect to the master - which replication_source specifies with format ip:port. - For example, if replication_source = "1.2.3.4:55555" then - the replica server tries to connect to 1.2.3.4 port 55555. - A replica server does not accept updates - on <olink targetptr="primary_port">listen</olink>. This parameter is + which replication_source specifies with a URI. + The string format is similar to the + <link + xlink:href="http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax">generic syntax for a URI schema</link> + So it may be a user name and password and ip:port address such as 'guest:password@127.0.0.1:3301', + or just ip:port address such as '127.0.0.1:3301', + or just port such as '3301'. + The default user name is 'guest'. + A replica server does not accept data-change requests + on the <olink targetptr="primary_port">listen</olink> port. + The replication_source parameter is dynamic, that is, to enter master mode, simply set replication_source to an empty string and issue "box.cfg{replication_source=new-value}".</entry> @@ -542,7 +607,7 @@ tarantool: primary pri: 3301 adm: 3313</programlisting> <tbody> <row> - <entry>log_level</entry> + <entry xml:id="log_level" xreflabel="log_level">log_level</entry> <entry>integer</entry> <entry>5</entry> <entry><emphasis role="strong">yes</emphasis></entry> @@ -557,18 +622,16 @@ tarantool: primary pri: 3301 adm: 3313</programlisting> </row> <row> - <entry>logger</entry> + <entry xml:id="logger" xreflabel="logger">logger</entry> <entry>string</entry> <entry>null</entry> <entry>no</entry> <entry>By default, the log is sent to the standard error stream (<filename>stderr</filename>). If logger - is given a value, Tarantool creates a child process, - executes the command indicated by the value, and pipes its standard - output to the standard input of the created process. - Example setting: <command>tee -a - tarantool.log</command> (this will duplicate log output - to <filename>stdout</filename> and a log file). + is specified, the log is sent to the file named in the string. + Example setting: logger = 'tarantool.log' + (this will open tarantool.log for output on the + server's default directory). </entry> </row> diff --git a/doc/user/databases.xml b/doc/user/databases.xml index d3055c8976cc7bf269ac8ce99e644bab1d664ec2..cc92af0d232b553a19d9eb3f08959a40246e098d 100644 --- a/doc/user/databases.xml +++ b/doc/user/databases.xml @@ -638,7 +638,7 @@ tarantool> <userinput>box.space.space55.index.primary:rename('secondary')</useri <varlistentry> <term> <emphasis role="lua" xml:id="box.update"> - box.space.<replaceable>space-name</replaceable>:update{<replaceable>key, format, {field_no, value}...</replaceable>) + box.space.<replaceable>space-name</replaceable>:update({<replaceable>key {, operator, field_no, value}...</replaceable>}) </emphasis> </term> <listitem> @@ -647,46 +647,37 @@ tarantool> <userinput>box.space.space55.index.primary:rename('secondary')</useri </para> <para> The <code>update</code> function supports operations on fields — - assignment, arithmetic operations (the field must be numeric), - cutting and pasting fragments of a field, — as well as - operations on a tuple: push and pop of a field at the tail of - a tuple, deletion and insertion of a field. Multiple - operations can be combined into a single update, and in this - case they are performed atomically. Each operation expects - field number as its first argument. When a sequence of changes - is present, field identifier in each operation is assumed to - be relative to the most recent state of the tuple, i.e. as if + assignment, arithmetic (if the field is unsigned numeric), + cutting and pasting fragments of a field, + deletng or inserting a field. Multiple + operations can be combined in a single update request, and in this + case they are performed atomically and sequentially. Each operation requires + specification of a field number. When multiple operations + are present, the field number for each operation is assumed to + be relative to the most recent state of the tuple, that is, as if all previous operations in a multi-operation update have - already been applied. In other words, it's always safe to + already been applied. In other words, it is always safe to merge multiple <code>update</code> invocations into a single invocation, with no change in semantics. </para> <para> Parameters: <code>space-name</code>, <code>key</code> = primary-key field values, must be passed as a Lua table if key is multi-part, - <code>format</code> = a sequence of - pairs of characters, where the first character in each pair - is the operation specifier, and the second character in - each pair is the operation argument. - The <code>{field_no, value}</code> arguments are the - field numbers of affected fields and applicable values. + <code>{operator, field_no, value}</code> = a group of arguments + for each operation, indicating what the operation is, what field + the operation will apply to, and what value will be applied. For some operations the field number can be -1, meaning the last field in the tuple. - There must be a pair of {field_no, value} arguments - for each character pair in the format argument. - The format and {field_no, value} arguments are passed to - <code>pickle.pack()</code> and the result is sent - to <code>box.process()</code>. - Possible operation specifiers are: <quote>+</quote> + Possible operators are: <quote>+</quote> for addition, <quote>-</quote> for subtraction, <quote>&</quote> for bitwise AND, <quote>|</quote> for bitwise OR, <quote>^</quote> for bitwise exclusive OR (XOR), <quote>:</quote> - for string splice, <quote>!</quote> for insertion. - Possible operation arguments are: <quote>p</quote>. - Thus in the instruction <code>s:update{44,, {{'+p,1,55},{=p',3,'x'}})</code> + for string splice, <quote>!</quote> for insert, + <quote>#</quote> for delete. + Thus in the instruction <code>s:update{44,, {{'+,1,55},{=',3,'x'}})</code> the primary-key value is 44, - the formats are '+p' and '=p' + the operators are '+' and '=' meaning "add a value to a field and then assign a value to a field", the first affected field is field 1 and the value which will be added to it is 55, the second affected field @@ -764,11 +755,11 @@ box.space.tester:update({999}, {{'=', 2, 'XYZ'}}) #In the following update ... # The third argument is ':', that is, this is the example of splice. # The fourth argument is 2 because the change will occur in field[2]. -# The fifth argument is 1 because deletion will begin with the second byte. +# The fifth argument is 2 because deletion will begin with the second byte. # The sixth argument is 1 because the number of bytes to delete is 1. # The seventh argument is '!!' because '!!' is to be added at this position. # Therefore, after the following update, field[1] = 999, field[2] = 'X!!Z'. -box.space.tester:update({999}, {{':', 2, 1, 1, '!!'}}) +box.space.tester:update({999}, {{':', 2, 2, 1, '!!'}}) </programlisting> </para> @@ -1871,7 +1862,7 @@ tarantool> <userinput>#t</userinput> </varlistentry> <varlistentry> <term> - <emphasis role="lua"> <replaceable>tuple-value</replaceable> : bsize()</emphasis> + <emphasis role="lua"> <replaceable>tuple-value</replaceable>:bsize()</emphasis> </term> <listitem> <para> @@ -1904,7 +1895,7 @@ tarantool> <userinput>t:bsize()</userinput> </varlistentry> <varlistentry> <term> - <emphasis role="lua">[ <replaceable>field-number</replaceable> ]</emphasis> + <emphasis role="lua"><replaceable>tuple-value</replaceable> [ <replaceable>field-number</replaceable> ]</emphasis> </term> <listitem> <para> @@ -1932,7 +1923,7 @@ tarantool> <userinput>t[2]</userinput> <varlistentry> <term> - <emphasis role="lua">find(<replaceable>[field-number,] field-value) or findall([field-number,] field-value</replaceable>)</emphasis> + <emphasis role="lua"><replaceable>tuple-value</replaceable>:find(<replaceable>[field-number,] field-value</replaceable>) or <replaceable>tuple-value</replaceable>:findall(<replaceable>[field-number,] field-value</replaceable>)</emphasis> </term> <listitem> <para> @@ -1974,7 +1965,7 @@ tarantool> <userinput>t:findall(2, 'a')</userinput> </varlistentry> <varlistentry> <term> - <emphasis role="lua">transform(<replaceable>start-field-number, fields-to-remove [, field-value ...]</replaceable>)</emphasis> + <emphasis role="lua"><replaceable>tuple-value</replaceable>:transform(<replaceable>start-field-number, fields-to-remove [, field-value ...]</replaceable>)</emphasis> </term> <listitem> <para> @@ -2007,7 +1998,7 @@ tarantool> <userinput>t:transform(2,2,'x')</userinput> <varlistentry> <term> - <emphasis role="lua">slice(<replaceable>start-field-number [, end-field-number]</replaceable>)</emphasis> + <emphasis role="lua"><replaceable>tuple-value</replaceable>:slice(<replaceable>start-field-number [, end-field-number]</replaceable>)</emphasis> </term> <listitem> <para> @@ -2039,7 +2030,7 @@ tarantool> <userinput>t:slice(2, 4)</userinput> </varlistentry> <varlistentry> <term> - <emphasis role="lua">unpack()</emphasis> + <emphasis role="lua"><replaceable>tuple-value</replaceable>:unpack()</emphasis> </term> <listitem> <para> @@ -2070,7 +2061,7 @@ tarantool> <userinput>t:unpack()</userinput> </varlistentry> <varlistentry> <term> - <emphasis role="lua">pairs()</emphasis> + <emphasis role="lua"><replaceable>tuple-value</replaceable>:pairs()</emphasis> </term> <listitem> <para> @@ -2096,6 +2087,46 @@ tarantool> <userinput>tmp = ''; for k, v in t:pairs() do tmp = tmp .. v end</ tarantool> <userinput>tmp</userinput> --- - Fld#1Fld#2Fld#3Fld#4Fld#5 +...</programlisting> + </listitem> + </varlistentry> + + <varlistentry> + <term> + <emphasis role="lua"><replaceable>tuple-value</replaceable>:update(<replaceable>{{format, field_no, value}...}</replaceable>)</emphasis> + </term> + <listitem> + <para> + Update a tuple. + </para> + <para> + This function updates a tuple which is not in a space. + Compare the function + <code>box.space.<replaceable>space-name</replaceable>:update{<replaceable>key, format, {field_no, value}...</replaceable>)</code>, + which updates a tuple in a space. + </para> + <para> + Parameters: briefly: + <code>format</code> indicates the type of update operation such as '=' for 'assign new value', + <code>field_no</code> indicates the field number to change such as 2 for field number 2, + <code>value</code> indicates the string which operates on the field such as 'B' for a new assignable value = 'B'. + For details: see the description for <code>format</code>, <code>field_no</code>, and <code>value</code> + in the section <olink targetptr="box.update"><code>box.space.<replaceable>space-name</replaceable>:update{<replaceable>key, format, {field_no, value}...</replaceable>)</code></olink>. + </para> + <para> + Returns: (type = tuple) the new tuple. + </para> + <para> + In the following example, a tuple named t is created + and then its second field is updated to equal 'B'. + </para> + <bridgehead renderas="sect4">Example</bridgehead> +<programlisting>tarantool> <userinput>t = box.tuple.new({'Fld#1','Fld#2','Fld#3','Fld#4','Fld#5'})</userinput> +--- +... +tarantool> <userinput>t:update({{'=',2,'B'}})</userinput> +--- +- ['Fld#1', 'B', 'Fld#3', 'Fld#4', 'Fld#5'] ...</programlisting> </listitem> </varlistentry> @@ -2487,7 +2518,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp <varlistentry> <term><emphasis role="lua" xml:id="net.box.ping"> - conn:ping()</emphasis></term> + <replaceable>conn</replaceable>:ping()</emphasis></term> <listitem> <para> Execute a PING command. @@ -2501,7 +2532,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp <varlistentry> <term><emphasis role="lua" xml:id="net.box.close"> - conn:close()</emphasis></term> + <replaceable>conn</replaceable>:close()</emphasis></term> <listitem> <para> Close a connection. @@ -2522,7 +2553,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp <varlistentry> <term><emphasis role="lua" xml:id="net.box.select"> - conn.space.<replaceable>space-name</replaceable>:select{<replaceable>field-value</replaceable>, ...}</emphasis></term> + <replaceable>conn</replaceable>.space.<replaceable>space-name</replaceable>:select{<replaceable>field-value</replaceable>, ...}</emphasis></term> <listitem> <para> <code>conn.space.<replaceable>space-name</replaceable>:select{...}</code> is the remote-call equivalent of the local call @@ -2536,7 +2567,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp <varlistentry> <term><emphasis role="lua" xml:id="net.box.insert"> - conn.space.<replaceable>space-name</replaceable>:insert{field-value, ...}</emphasis></term> + <replaceable>conn</replaceable>.space.<replaceable>space-name</replaceable>:insert{field-value, ...}</emphasis></term> <listitem> <para> <code>conn.space.<replaceable>space-name</replaceable>:insert(...)</code> is the remote-call equivalent of the local call @@ -2547,7 +2578,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp <varlistentry> <term><emphasis role="lua" xml:id="net.box.replace"> - conn.space.<replaceable>space-name</replaceable>:replace{field-value, ...}</emphasis></term> + <replaceable>conn</replaceable>.space.<replaceable>space-name</replaceable>:replace{field-value, ...}</emphasis></term> <listitem> <para> <code>conn.space.<replaceable>space-name</replaceable>:replace(...)</code> is the remote-call equivalent of the local call @@ -2558,7 +2589,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp <varlistentry> <term><emphasis role="lua" xml:id="net.box.update"> - conn.space.<replaceable>space-name</replaceable>:update(<replaceable>key</replaceable>, <replaceable>format</replaceable>, ...)</emphasis></term> + <replaceable>conn</replaceable>.space.<replaceable>space-name</replaceable>:update(<replaceable>key</replaceable>, <replaceable>format</replaceable>, ...)</emphasis></term> <listitem> <para> <code>conn.space.<replaceable>space-name</replaceable>:update(...)</code> is the remote-call equivalent of the local call @@ -2569,7 +2600,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp <varlistentry> <term><emphasis role="lua" xml:id="net.box.delete"> - conn.space.<replaceable>space-name</replaceable>:delete{key}</emphasis></term> + <replaceable>conn</replaceable>.space.<replaceable>space-name</replaceable>:delete{key}</emphasis></term> <listitem> <para> <code>conn.space.<replaceable>space-name</replaceable>:delete{...}</code> is the remote-call equivalent of the local call @@ -2580,7 +2611,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp <varlistentry> <term><emphasis role="lua" xml:id="net.box.call"> - conn:call(<replaceable>function-name</replaceable> [, <replaceable>arguments</replaceable>])</emphasis></term> + <replaceable>conn</replaceable>:call(<replaceable>function-name</replaceable> [, <replaceable>arguments</replaceable>])</emphasis></term> <listitem> <para> <code>conn:call('func', '1', '2', '3')</code> is the remote-call equivalent of <code>func('1', '2', '3')</code>. @@ -2594,7 +2625,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp <varlistentry> <term><emphasis role="lua" xml:id="net.box.timeout"> - conn:timeout(<replaceable>timeout</replaceable>)</emphasis></term> + <replaceable>conn</replaceable>:timeout(<replaceable>timeout</replaceable>)</emphasis></term> <listitem> <para> <code>timeout(...)</code> is a wrapper which sets a timeout for the request that follows it. diff --git a/doc/user/replication.xml b/doc/user/replication.xml index c2856b36e5874370e625a3534334f78b97963d6d..668a80bd6a1b800db0fe88d7a206c24af18c13d5 100644 --- a/doc/user/replication.xml +++ b/doc/user/replication.xml @@ -68,8 +68,8 @@ identifier which is unique within the cluster, known as the To prepare the master for connections from the replica, it's only necessary to include "listen" in the initial <code>box.cfg</code> request, for example <code>box.cfg{listen=3301}</code>. - A master with enabled "listen" uri can accept connections - from as many replicas as necessary on that uri. Each replica + A master with enabled "listen" URI can accept connections + from as many replicas as necessary on that URI. Each replica has its own replication state. </para> </section> @@ -120,7 +120,7 @@ identifier which is unique within the cluster, known as the <para> However, once a master failure is detected, the recovery is simple: declare that the replica is now the new master, - by saying <code>box.cfg{... listen=uri}</code>. + by saying <code>box.cfg{... listen=URI}</code>. Then, if there are updates on the old master that were not propagated before the old master went down, they would have to be re-applied manually. diff --git a/doc/user/stored-procedures.xml b/doc/user/stored-procedures.xml index 58316d104d4fdad4d2e9985e1017befdad78d44b..75f38d7bd02a37ff7a412f358714c67a1a3dae1b 100644 --- a/doc/user/stored-procedures.xml +++ b/doc/user/stored-procedures.xml @@ -154,7 +154,8 @@ The included language processor is <link xlink:href="http://luajit.org/">LuaJIT< Major "built-in" components are: fibers, <link xlink:href="http://msgpack.org">MsgPack</link>, digest, JSON, <link xlink:href="http://en.wikipedia.org/wiki/Yaml">YAML</link>, -<link xlink:href="http://en.wikipedia.org/wiki/Inter-process_communication">IPC</link> , and box. +<link xlink:href="http://en.wikipedia.org/wiki/Inter-process_communication">IPC</link>, +fio, and box. </para> <para> @@ -226,7 +227,12 @@ underlying information about typing, arrays, and structures. <para> <emphasis>IPC</emphasis> is Inter-Process Communication. -this is useful for implementations of task queues and long polling. +This is useful for implementations of task queues and long polling. +</para> + +<para> +<emphasis>Fio</emphasis> is standard file IO, +adapted to work with Tarantool's fibers in a cooperative environment. </para> <para> @@ -282,7 +288,8 @@ administration with the built-in packages. <link xlink:href="https://en.wikipedia.org/wiki/Sha-2">SHA-2</link>) as well as a checksum function - (<link xlink:href="https://en.wikipedia.org/wiki/Cyclic_redundancy_check">CRC32</link>). + (<link xlink:href="https://en.wikipedia.org/wiki/Cyclic_redundancy_check">CRC32</link>) + and two functions for <link xlink:href="https://en.wikipedia.org/wiki/Base64">base64</link>. The functions in <code>digest</code> are: <informaltable> <tgroup cols="2" align="left" colsep="1" rowsep="0"> @@ -308,6 +315,8 @@ administration with the built-in packages. <row><entry><code>digest.md4_hex(<replaceable>string</replaceable>)</code></entry><entry> Returns hexadecimal of a digest calculated with md4.</entry></row> <row><entry><code>digest.md5(<replaceable>string</replaceable>)</code></entry><entry> Returns 256-bit digest made with MD5.</entry></row> <row><entry><code>digest.md5_hex(<replaceable>string</replaceable>)</code></entry><entry> Returns hexadecimal of a digest calculated with md5.</entry></row> + <row><entry><code>digest.base64_encode(<replaceable>string</replaceable>)</code></entry><entry> Returns base64 encoding from a regular string.</entry></row> + <row><entry><code>digest.base64_decode(<replaceable>string</replaceable>)</code></entry><entry> Returns a regular string from a base64 encoding.</entry></row> </tbody> </tgroup> </informaltable> @@ -453,7 +462,7 @@ Password is not valid <varlistentry> <term> - <emphasis role="lua">:isnil(<replaceable>uuid_with_type_cdata</replaceable>)</emphasis> + <emphasis role="lua"><replaceable>uuid_with_type_cdata</replaceable>:isnil()</emphasis> </term> <listitem> <para> @@ -1157,7 +1166,7 @@ the status is dead because the cancel worked.<programlisting> </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">channel:put(<replaceable>message[, timeout]</replaceable>)</emphasis></term> + <term><emphasis role="lua"><replaceable>channel</replaceable>:put(<replaceable>message[, timeout]</replaceable>)</emphasis></term> <listitem> <para> Send a message using a channel. If the channel is full, @@ -1177,7 +1186,7 @@ the status is dead because the cancel worked.<programlisting> </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">channel:close()</emphasis></term> + <term><emphasis role="lua"><replaceable>channel</replaceable>:close()</emphasis></term> <listitem> <para> Close the channel. All waiters in the channel will be @@ -1188,7 +1197,7 @@ the status is dead because the cancel worked.<programlisting> </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">channel:get(<replaceable>[timeout]</replaceable>)</emphasis></term> + <term><emphasis role="lua"><replaceable>channel</replaceable>:get(<replaceable>[timeout]</replaceable>)</emphasis></term> <listitem> <para> Fetch a message from a channel. If the channel is empty, @@ -1211,7 +1220,7 @@ the status is dead because the cancel worked.<programlisting> </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">channel:broadcast(<replaceable>message</replaceable>)</emphasis></term> + <term><emphasis role="lua"><replaceable>channel</replaceable>:broadcast(<replaceable>message</replaceable>)</emphasis></term> <listitem> <para> If the channel is empty, <code>channel:broadcast()</code> is equivalent to @@ -1225,7 +1234,7 @@ the status is dead because the cancel worked.<programlisting> </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">channel:is_empty()</emphasis></term> + <term><emphasis role="lua"><replaceable>channel</replaceable>:is_empty()</emphasis></term> <listitem> <para> Check whether the specified channel is empty (has no messages). @@ -1236,7 +1245,7 @@ the status is dead because the cancel worked.<programlisting> </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">channel:is_full()</emphasis></term> + <term><emphasis role="lua"><replaceable>channel</replaceable>:is_full()</emphasis></term> <listitem> <para> Check whether the specified channel is full. @@ -1247,7 +1256,7 @@ the status is dead because the cancel worked.<programlisting> </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">channel:has_readers()</emphasis></term> + <term><emphasis role="lua"><replaceable>channel</replaceable>:has_readers()</emphasis></term> <listitem> <para> Check whether the specified channel is empty and has readers waiting @@ -1260,7 +1269,7 @@ the status is dead because the cancel worked.<programlisting> </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">channel:has_writers()</emphasis></term> + <term><emphasis role="lua"><replaceable>channel</replaceable>:has_writers()</emphasis></term> <listitem> <para> Check whether the specified channel is full and has writers waiting @@ -1273,7 +1282,7 @@ the status is dead because the cancel worked.<programlisting> </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">channel:is_closed()</emphasis></term> + <term><emphasis role="lua"><replaceable>channel</replaceable>:is_closed()</emphasis></term> <listitem> <simpara> Returns: (type = boolean) true if the specified channel is already @@ -1531,7 +1540,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-sysconnect" xreflabel="socket-sysconnect"><emphasis role="lua">sock:sysconnect(<replaceable>host, port</replaceable>)</emphasis></term> + <term xml:id="socket-sysconnect" xreflabel="socket-sysconnect"><emphasis role="lua"><replaceable>sock</replaceable>:sysconnect(<replaceable>host, port</replaceable>)</emphasis></term> <listitem> <para> Connect a socket to a remote host. @@ -1554,7 +1563,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-tcpconnect" xreflabel="socket-tcpconnect"><emphasis role="lua">sock:tcp_connect(<replaceable>host, port</replaceable>)</emphasis></term> + <term xml:id="socket-tcpconnect" xreflabel="socket-tcpconnect"><emphasis role="lua">socket.tcp_connect(<replaceable>host, port</replaceable>)</emphasis></term> <listitem> <para> Connect a socket to a remote host. @@ -1566,13 +1575,13 @@ end Returns: (type = userdata) a connected socket, if no error. </para> <para> - Example: <code>sock:tcp_connect('tarantool.org', 80)</code> + Example: <code>socket.tcp_connect('tarantool.org', 80)</code> </para> </listitem> </varlistentry> <varlistentry> - <term xml:id="socket-send" xreflabel="socket-send"><emphasis role="lua">sock:send(<replaceable>data</replaceable>)</emphasis></term> + <term xml:id="socket-send" xreflabel="socket-send"><emphasis role="lua"><replaceable>sock</replaceable>:send(<replaceable>data</replaceable>)</emphasis></term> <listitem> <para> Send data over a connected socket. @@ -1590,7 +1599,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-syswrite" xreflabel="socket-syswrite"><emphasis role="lua">sock:syswrite(<replaceable>size</replaceable>)</emphasis></term> + <term xml:id="socket-syswrite" xreflabel="socket-syswrite"><emphasis role="lua"><replaceable>sock</replaceable>:syswrite(<replaceable>size</replaceable>)</emphasis></term> <listitem> <para> Write as much as possible data to the socket buffer if non-blocking. @@ -1622,7 +1631,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-readline" xreflabel="socket-readline"><emphasis role="lua">sock:readline(<replaceable>[limit] [, separator list]</replaceable>)</emphasis></term> + <term xml:id="socket-readline" xreflabel="socket-readline"><emphasis role="lua"><replaceable>sock</replaceable>:readline(<replaceable>[limit] [, separator list]</replaceable>)</emphasis></term> <listitem> <para> Read a line from a connected socket. @@ -1669,7 +1678,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-read" xreflabel="socket-read"><emphasis role="lua">sock:read(<replaceable>size</replaceable>)</emphasis></term> + <term xml:id="socket-read" xreflabel="socket-read"><emphasis role="lua"><replaceable>sock</replaceable>:read(<replaceable>size</replaceable>)</emphasis></term> <listitem> <para> Read data on a socket, until <code>size</code> bytes have been read, @@ -1680,7 +1689,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-sysread" xreflabel="socket-sysread"><emphasis role="lua">sock:sysread(<replaceable>size</replaceable>)</emphasis></term> + <term xml:id="socket-sysread" xreflabel="socket-sysread"><emphasis role="lua"><replaceable>sock</replaceable>:sysread(<replaceable>size</replaceable>)</emphasis></term> <listitem> <para> Return all available data from the socket buffer if non-blocking. @@ -1690,7 +1699,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-bind" xreflabel="socket-bind"><emphasis role="lua">sock:bind(<replaceable>host, port</replaceable>)</emphasis></term> + <term xml:id="socket-bind" xreflabel="socket-bind"><emphasis role="lua"><replaceable>sock</replaceable>:bind(<replaceable>host, port</replaceable>)</emphasis></term> <listitem> <para> Bind a socket to the given host/port. @@ -1709,7 +1718,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-listen" xreflabel="socket-listen"><emphasis role="lua">sock:listen(backlog)</emphasis></term> + <term xml:id="socket-listen" xreflabel="socket-listen"><emphasis role="lua"><replaceable>sock</replaceable>:listen(backlog)</emphasis></term> <listitem> <para> Start listening for incoming connections. @@ -1726,7 +1735,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-accept" xreflabel="socket-accept"><emphasis role="lua">sock:accept()</emphasis></term> + <term xml:id="socket-accept" xreflabel="socket-accept"><emphasis role="lua"><replaceable>sock</replaceable>:accept()</emphasis></term> <listitem> <para> Accept a new client connection and create a new connected socket. @@ -1739,7 +1748,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-sendto" xreflabel="socket-sendto"><emphasis role="lua">sock:sendto(<replaceable>data, host, port</replaceable>)</emphasis></term> + <term xml:id="socket-sendto" xreflabel="socket-sendto"><emphasis role="lua"><replaceable>sock</replaceable>:sendto(<replaceable>data, host, port</replaceable>)</emphasis></term> <listitem> <para> Send a message on a UDP socket to a specified host. @@ -1755,7 +1764,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-recvfrom" xreflabel="socket-recvfrom"><emphasis role="lua">sock:recvfrom(<replaceable>limit</replaceable>)</emphasis></term> + <term xml:id="socket-recvfrom" xreflabel="socket-recvfrom"><emphasis role="lua"><replaceable>sock</replaceable>:recvfrom(<replaceable>limit</replaceable>)</emphasis></term> <listitem> <para> Receive a message on a UDP socket. @@ -1771,7 +1780,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-shutdown" xreflabel="socket-shutdown"><emphasis role="lua">sock:shutdown(<replaceable>how</replaceable>)</emphasis></term> + <term xml:id="socket-shutdown" xreflabel="socket-shutdown"><emphasis role="lua"><replaceable>sock</replaceable>:shutdown(<replaceable>how</replaceable>)</emphasis></term> <listitem> <para> Shutdown a reading end, a writing end, or both ends of a socket. @@ -1787,7 +1796,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-close" xreflabel="socket-close"><emphasis role="lua">sock:close()</emphasis></term> + <term xml:id="socket-close" xreflabel="socket-close"><emphasis role="lua"><replaceable>sock</replaceable>:close()</emphasis></term> <listitem> <para> Close (destroy) a socket. @@ -1803,7 +1812,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-error" xreflabel="socket-error"><emphasis role="lua">sock:error() and sock:errno()</emphasis></term> + <term xml:id="socket-error" xreflabel="socket-error"><emphasis role="lua"><replaceable>sock</replaceable>:error() and <replaceable>sock</replaceable>:errno()</emphasis></term> <listitem> <para> Retrieve information about the last error that occurred on a socket, if any. @@ -1819,7 +1828,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-setsockopt" xreflabel="socket-setsockopt"><emphasis role="lua">sock:setsockopt(<replaceable>level, name, value</replaceable>)</emphasis></term> + <term xml:id="socket-setsockopt" xreflabel="socket-setsockopt"><emphasis role="lua"><replaceable>sock</replaceable>:setsockopt(<replaceable>level, name, value</replaceable>)</emphasis></term> <listitem> <para> Set socket flags. The argument values are the same as in the <link xlink:href="http://man7.org/linux/man-pages/man2/setsockopt.2.html">Linux man page</link>. @@ -1835,7 +1844,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-getsockopt" xreflabel="socket-getsockopt"><emphasis role="lua">sock:getsockopt(<replaceable>level, name</replaceable>)</emphasis></term> + <term xml:id="socket-getsockopt" xreflabel="socket-getsockopt"><emphasis role="lua"><replaceable>sock</replaceable>:getsockopt(<replaceable>level, name</replaceable>)</emphasis></term> <listitem> <para> Get socket flags. For a list of possible flags see description of the previous function, @@ -1845,7 +1854,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-linger" xreflabel="socket-linger"><emphasis role="lua">sock:linger([<replaceable>active</replaceable>])</emphasis></term> + <term xml:id="socket-linger" xreflabel="socket-linger"><emphasis role="lua"><replaceable>sock</replaceable>:linger([<replaceable>active</replaceable>])</emphasis></term> <listitem> <para> Set or clear the SO_LINGER flag. For a description of the flag, see <link xlink:href="http://man7.org/linux/man-pages/man1/loginctl.1.html">Linux man page</link>. @@ -1860,7 +1869,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-nonblock" xreflabel="socket-nonblock"><emphasis role="lua">sock:nonblock([<replaceable>flag</replaceable>])</emphasis></term> + <term xml:id="socket-nonblock" xreflabel="socket-nonblock"><emphasis role="lua"><replaceable>sock</replaceable>:nonblock([<replaceable>flag</replaceable>])</emphasis></term> <listitem> <para> <code>sock:nonblock()</code> returns the current flag value. @@ -1872,7 +1881,7 @@ end </varlistentry> <varlistentry> - <term xml:id="socket-readable" xreflabel="socket-readable"><emphasis role="lua">sock:readable([<replaceable>timeout</replaceable>])</emphasis>, <emphasis>sock:writable([<replaceable>timeout</replaceable>])</emphasis>, <emphasis>sock:wait([<replaceable>timeout</replaceable>])</emphasis></term> + <term xml:id="socket-readable" xreflabel="socket-readable"><emphasis role="lua"><replaceable>sock</replaceable>:readable([<replaceable>timeout</replaceable>])</emphasis>, <emphasis>sock:writable([<replaceable>timeout</replaceable>])</emphasis>, <emphasis>sock:wait([<replaceable>timeout</replaceable>])</emphasis></term> <listitem> <para> <code>sock:readable()</code> waits until something is readable, or until a timeout value expires. @@ -2432,7 +2441,7 @@ end one Tarantool server to start listening on an administrative host/port. </para> - + <variablelist> @@ -2497,9 +2506,9 @@ end <listitem> <para> Listen on host:port. The primary way of listening for incoming - requests is via the host and port, or uri, specified in + requests is via the host and port, or URI, specified in <code>box.cfg{listen=...}</code>. The alternative way of - listening is via the host and port, or uri, specified in + listening is via the host and port, or URI, specified in <code>console.listen(...)</code>. This alternative way is called "administrative" or simply "admin port". </para> @@ -2529,6 +2538,61 @@ end +</section> + + +<section xml:id="sp-log"> + <title>package <code>log</code></title> + <para> + The Tarantool server puts all diagnostic messages in a log file + specified by the <link linkend="logger">logger</link> + configuration parameter. Diagnostic messages may be either + system-generated by the server's internal code, or user-generated + with the <code>log.<replaceable>log_level_function_name</replaceable></code> function. + </para> +<variablelist> + <varlistentry> + <term><emphasis role="lua">log.<replaceable>log_level_function_name</replaceable>(<replaceable>log_message</replaceable>)</emphasis></term> + <listitem> + <para> + Output a user-generated message to the <link linkend="logger">log file</link>, given + log_level_function_name = <code>error</code> or <code>warn</code> or <code>info</code> + or <code>debug</code> or <code>rotate</code>. + </para> + <para> + Returns: nothing. + </para> + <para> + Parameters: (type = string) log_message. The actual output will be a + line containing the current timestamp, a module name, 'E' or 'W' or 'I' or 'D' or 'R' depending on + log_level_function_name, and log_message. Output will not occur if log_level_function_name is for a type greater than + <link linkend="log_level">log_level</link>. + </para> + <para> + <bridgehead renderas="sect4">Example showing use of log</bridgehead><programlisting> +#From the shell: +#Start the server, do some requests, exit, and display the log, thus: +~/tarantool/src/tarantool +box.cfg{log_level=3, logger='tarantool.txt'} +log = require('log') +log.error('Error') +log.info('Info') +os.exit() +less tarantool.txt +</programlisting> + The output from the <code>less</code> command will look approximately like this: +<programlisting> +2014-09-21 17:58:40.820 [5257] main/101/interactive C> version 1.6.3-355-ga4f762d +2014-09-21 17:58:40.821 [5257] main/101/interactive C> log level 3 +2014-09-21 17:58:40.821 [5261] main/101/spawner C> initialized +2014-09-21 17:58:40.830 [5257] main/101/interactive [C]:-1 E> Error +</programlisting> + The 'Error' line is visible in tarantool.txt preceded by the letter E. + The 'Info' line is not present because the log_level is 3. + </para> + </listitem> + </varlistentry> + </variablelist> </section> <section xml:id="sp-tonumber64"> diff --git a/doc/user/tutorial.xml b/doc/user/tutorial.xml index 7379892b901524a450c1119f6b68edb753f277f3..c11b52f6ba3b147f2cf2c5c5f4d479015d1bc87f 100644 --- a/doc/user/tutorial.xml +++ b/doc/user/tutorial.xml @@ -350,16 +350,7 @@ ones unless you intend to work on the documentation.</para> <command>cd</command> python-daemon-1.5.5 <command>sudo python</command> setup.py install </userinput> -# python module for template engine (jinja2): For documentation: -# (If wget fails, check the <citetitle xlink:href="https://pypi.python.org/pypi/Jinja2" xlink:title="Python Jinja2">python-jinja2</citetitle> web site -# to see what the current version is.) -<userinput> -<command>cd</command> ~ -<command>wget</command> https://pypi.python.org/packages/source/J/Jinja2/Jinja2-2.7.2.tar.gz -<command>tar</command> <option>-xzvf</option> Jinja2-2.7.2.tar.gz -<command>cd</command> Jinja2-2.7.2 -<command>sudo python</command> setup.py install -</userinput> + # python module for text-to-html conversion (markdown): For documentation: # (If wget fails, check the <citetitle xlink:href="http://pypi.python.org/pypi/Markdown/" xlink:title="Python implementation of Markdown">python-markdown</citetitle> web site # to see what the current version is.) @@ -370,6 +361,19 @@ ones unless you intend to work on the documentation.</para> <command>cd</command> Markdown-2.3.1 <command>sudo python</command> setup.py install </userinput> +# python module which includes Jinja2 template engine: For documentation: +<userinput> +<command>sudo pip install pelican</command> +</userinput> +# python module for HTML scraping: For documentation: +<userinput> +<command>cd</command> ~ +<command>wget</command> http://www.crummy.com/software/BeautifulSoup/bs3/download//3.x/BeautifulSoup-3.2.1.tar.gz +<command>tar</command> -xzvf BeautifulSoup-3.2.1.tar.gz +<command>cd</command> BeautifulSoup-3.2.1 +<command>sudo python</command> setup.py install +</userinput> + </programlisting> </para> diff --git a/extra/dist/default/tarantool b/extra/dist/default/tarantool index 81faf68920a1a7d6b61794b59c2ed71c736a532c..a861bdf5f135e95405a28eab718517f5992537d6 100644 --- a/extra/dist/default/tarantool +++ b/extra/dist/default/tarantool @@ -1,10 +1,11 @@ -- Options for Tarantool default_cfg = { - pid_file = "/var/run/tarantool", -- will become pid_file .. instance .. '.pid' - wal_dir = "/var/lib/tarantool", -- will become wal_dir/instance/ - snap_dir = "/var/lib/tarantool", -- snap_dir/instance/ - logger = "/var/log/tarantool", -- logger/instance .. '.log' - username = "tarantool", + pid_file = "/var/run/tarantool", -- will become pid_file .. instance .. '.pid' + wal_dir = "/var/lib/tarantool", -- will become wal_dir/instance/ + snap_dir = "/var/lib/tarantool", -- snap_dir/instance/ + sophia_dir = "/var/lib/tarantool", -- will become sophia_dir/sophia/instance/ + logger = "/var/log/tarantool", -- logger/instance .. '.log' + username = "tarantool", } instance_dir = "/etc/tarantool/instances.enabled" diff --git a/extra/dist/dist.lua b/extra/dist/dist.lua index d48317b28faf6b0c8ae8207d21385618f0c211e9..9e14590b8bd400a2f8468817f7c23b2ebde78002 100755 --- a/extra/dist/dist.lua +++ b/extra/dist/dist.lua @@ -1,5 +1,93 @@ #!/usr/bin/env tarantool +--[[ + +=head1 NAME + +dist.lua - an utility to control tarantool instances + +=head1 SYNOPSIS + + vim /etc/tarantool/instances.enabled/my_instance.lua + dist.lua start my_instance + dist.lua stop my_instance + dist.lua logrotate my_instance + +=head1 DESCRIPTION + +The script is read C</etc/sysconfig/tarantool> or C</etc/default/tarantool>. +The file contains common default instances options: + + $ cat /etc/default/tarantool + + + -- Options for Tarantool + default_cfg = { + -- will become pid_file .. instance .. '.pid' + pid_file = "/var/run/tarantool", + + -- will become wal_dir/instance/ + wal_dir = "/var/lib/tarantool", + + -- snap_dir/instance/ + snap_dir = "/var/lib/tarantool", + + -- sophia_dir/instance/ + sophia_dir = "/var/lib/tarantool/sophia", + + -- logger/instance .. '.log' + logger = "/var/log/tarantool", + + username = "tarantool", + } + + instance_dir = "/etc/tarantool/instances.enabled" + + +The file defines C<instance_dir> where user can place his +applications (instances). + +Each instance can be controlled by C<dist.lua>: + +=head2 Starting instance + + dist.lua start instance_name + +=head2 Stopping instance + + dist.lua stop instance_name + +=head2 Logrotate instance's log + + dist.lua logrotate instance_name + +=head2 Enter instance admin console + + dist.lua enter instance_name + +=head2 status + + dist.lua status instance_name + +Check if instance is up. + +If pid file exists and control socket exists and control socket is alive +returns code C<0>. + +Return code != 0 in other cases. Can complain in log (stderr) if pid file +exists and socket doesn't, etc. + +=head1 COPYRIGHT + +Copyright (C) 2010-2013 Tarantool AUTHORS: +please see AUTHORS file. + + + +=cut + +]] + local fio = require 'fio' local log = require 'log' local errno = require 'errno' @@ -41,19 +129,21 @@ if instance_dir == nil then instance_dir = '/etc/tarantool/instances.enabled' end -default_cfg.pid_file = default_cfg.pid_file and default_cfg.pid_file or "/var/run/tarantool" -default_cfg.wal_dir = default_cfg.wal_dir and default_cfg.wal_dir or "/var/lib/tarantool" -default_cfg.snap_dir = default_cfg.snap_dir and default_cfg.snap_dir or "/var/lib/tarantool" -default_cfg.logger = default_cfg.logger and default_cfg.logger or "/var/log/tarantool" -default_cfg.username = default_cfg.username and default_cfg.username or "tarantool" +default_cfg.pid_file = default_cfg.pid_file and default_cfg.pid_file or "/var/run/tarantool" +default_cfg.wal_dir = default_cfg.wal_dir and default_cfg.wal_dir or "/var/lib/tarantool" +default_cfg.snap_dir = default_cfg.snap_dir and default_cfg.snap_dir or "/var/lib/tarantool" +default_cfg.sophia_dir = default_cfg.sophia_dir and default_cfg.sophia_dir or "/var/lib/tarantool" +default_cfg.logger = default_cfg.logger and default_cfg.logger or "/var/log/tarantool" +default_cfg.username = default_cfg.username and default_cfg.username or "tarantool" -- create a path to the control socket (admin console) local console_sock = fio.pathjoin(default_cfg.pid_file, instance .. '.control') -default_cfg.pid_file = fio.pathjoin(default_cfg.pid_file, instance .. '.pid') -default_cfg.wal_dir = fio.pathjoin(default_cfg.wal_dir, instance) -default_cfg.snap_dir = fio.pathjoin(default_cfg.snap_dir, instance) -default_cfg.logger = fio.pathjoin(default_cfg.logger, instance .. '.log') +default_cfg.pid_file = fio.pathjoin(default_cfg.pid_file, instance .. '.pid') +default_cfg.wal_dir = fio.pathjoin(default_cfg.wal_dir, instance) +default_cfg.snap_dir = fio.pathjoin(default_cfg.snap_dir, instance) +default_cfg.sophia_dir = fio.pathjoin(default_cfg.sophia_dir, instance, 'sophia') +default_cfg.logger = fio.pathjoin(default_cfg.logger, instance .. '.log') local instance_lua = fio.pathjoin(instance_dir, instance .. '.lua') @@ -76,16 +166,18 @@ function mk_default_dirs(cfg) if fio.stat(pid_dir) == nil then mkdir(pid_dir) end - -- create wal_dir if fio.stat(cfg.wal_dir) == nil then mkdir(cfg.wal_dir) end - -- create snap_dir if fio.stat(cfg.snap_dir) == nil then mkdir(cfg.snap_dir) end + -- create sophia_dir + if fio.stat(cfg.sophia_dir) == nil then + mkdir(cfg.sophia_dir) + end -- create log_dir log_dir = fio.dirname(cfg.logger) if log_dir:find('|') == nil and fio.stat(log_dir) == nil then @@ -176,6 +268,52 @@ elseif cmd == 'logrotate' then s:read({ '[.][.][.]' }, 2) os.exit(0) + +elseif cmd == 'enter' then + if fio.stat(console_sock) == nil then + log.error("Can't connect to %s (socket not found)", console_sock) + os.exit(-1) + end + + log.info('Connecting to %s', console_sock) + + local cmd = string.format( + "require('console').connect('%s')", console_sock) + + console.on_start( function(self) self:eval(cmd) end ) + console.on_client_disconnect( function(self) self.running = false end ) + console.start() + os.exit(0) +elseif cmd == 'status' then + if fio.stat(force_cfg.pid_file) == nil then + if errno() == errno.ENOENT then + os.exit(1) + end + log.error("Cant access pidfile %s: %s", + force_cfg.pid_file, errno.strerror()) + end + + if fio.stat(console_sock) == nil then + if errno() == errno.ENOENT then + log.warn("pidfile is exists, but control socket (%s) isn't", + console_sock) + os.exit(2) + end + end + + local s = socket.tcp_connect('unix/', console_sock) + if s == nil then + if errno() ~= errno.EACCES then + log.warn("Can't access control socket %s: %s", console_sock, + errno.strerror()) + os.exit(3) + else + os.exit(0) + end + end + + s:close() + os.exit(0) else log.error("Unknown command '%s'", cmd) os.exit(-1) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9a8208114aae464c3ea50e8f5742834d156b2b24..98020848997baf23b5339a0755f013ca9ce2084c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,7 @@ lua_source(lua_sources lua/init.lua) lua_source(lua_sources lua/uuid.lua) lua_source(lua_sources lua/digest.lua) lua_source(lua_sources lua/msgpackffi.lua) +lua_source(lua_sources lua/uri.lua) lua_source(lua_sources lua/console.lua) lua_source(lua_sources lua/bsdsocket.lua) lua_source(lua_sources lua/errno.lua) @@ -39,7 +40,7 @@ set_property(DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${lua_sources}) add_custom_target(ragel WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMAND ragel -G2 src/uri.rl -o src/uri.cc) + COMMAND ragel -G2 src/uri.rl -o src/uri.c) set (common_sources memory.cc @@ -55,9 +56,6 @@ set (common_sources pickle.cc coro.cc stat.cc - iproto.cc - iproto_constants.cc - iproto_port.cc object.cc exception.cc ipc.cc @@ -76,7 +74,7 @@ set (common_sources fiob.c tt_uuid.c ffisyms.cc - uri.cc + uri.c coeio_file.cc lua/digest.cc lua/init.cc diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt index 896003798e417c1f183db36681e090db332d2fbc..bef3d928599d4b02f47441cda1c6e40f66c78c02 100644 --- a/src/box/CMakeLists.txt +++ b/src/box/CMakeLists.txt @@ -17,6 +17,10 @@ add_custom_target(box_generate_lua_sources set_property(DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${lua_sources}) add_library(box + iproto.cc + iproto_constants.c + iproto_port.cc + xrow.cc tuple.cc tuple_convert.cc tuple_update.cc diff --git a/src/box/access.h b/src/box/access.h index b0cbf366c4cafdc94261813ff62523d5fc363e50..385807aa4e37729031181450e945b76952ee21df 100644 --- a/src/box/access.h +++ b/src/box/access.h @@ -142,9 +142,12 @@ user_by_name(const char *name, uint32_t len); #define user() \ ({ \ struct session *s = session(); \ - uint8_t auth_token = s ? s->auth_token : (int) ADMIN; \ - struct user *u = &users[auth_token]; \ - assert(u->auth_token == auth_token); \ + struct user *u = &users[s->auth_token]; \ + if (u->auth_token != s->auth_token || \ + u->uid != s->uid) { \ + tnt_raise(ClientError, ER_NO_SUCH_USER, \ + int2str(s->uid)); \ + } \ u; \ }) diff --git a/src/box/alter.cc b/src/box/alter.cc index b31eb9a6e7bf24c87f79280a3da6c30c859050c7..c02531e87960c23b25dea7a8d2ff0bdf7faa41c7 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -1638,7 +1638,7 @@ on_commit_dd_cluster(struct trigger *trigger, void *event) uint32_t id = tuple_field_u32(new_tuple, 0); tt_uuid uuid = tuple_field_uuid(new_tuple, 1); - cluster_add_server(&uuid, id); + cluster_set_server(&uuid, id); } static struct trigger commit_cluster_trigger = @@ -1682,6 +1682,14 @@ on_replace_dd_cluster(struct trigger *trigger, void *event) if (tt_uuid_is_nil(&server_uuid)) tnt_raise(ClientError, ER_INVALID_UUID, tt_uuid_str(&server_uuid)); + struct tuple *old_tuple = stmt->old_tuple; + if (old_tuple != NULL) { + /* server_id is read-only, other fields can be changed */ + uint32_t old_server_id = tuple_field_u32(old_tuple, 0); + if (server_id != old_server_id) + tnt_raise(ClientError, ER_SERVER_ID_IS_RO, + (unsigned) server_id); + } trigger_add(&txn->on_commit, &commit_cluster_trigger); } diff --git a/src/box/box.cc b/src/box/box.cc index 13d61afb28279632d87005b470d557cde67b9a30..8c9f0b41c64e73de8d6a812b3c3bb5d456e4e713 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -34,7 +34,7 @@ #include "recovery.h" #include "log_io.h" #include <say.h> -#include <iproto.h> +#include "iproto.h" #include "replication.h" #include <stat.h> #include <tarantool.h> @@ -90,12 +90,24 @@ static void process_ro(struct port *port, struct request *request) { if (!iproto_type_is_select(request->type)) - tnt_raise(LoggedError, ER_SECONDARY); + tnt_raise(LoggedError, ER_READONLY); return process_rw(port, request); } +void +box_set_ro(bool ro) +{ + box_process = ro ? process_ro : process_rw; +} + +bool +box_is_ro(void) +{ + return box_process == process_ro; +} + static void -recover_row(void *param __attribute__((unused)), struct iproto_header *row) +recover_row(void *param __attribute__((unused)), struct xrow_header *row) { assert(row->bodycnt == 1); /* always 1 for read */ struct request request; @@ -114,15 +126,18 @@ box_check_replication_source(const char *source) if (source == NULL) return; struct uri uri; - if (uri_parse(&uri, source)) { - tnt_raise(ClientError, ER_CFG, - "incorrect replication source"); + + /* URI format is [host:]service */ + if (uri_parse(&uri, source) || !uri.service) { + tnt_raise(ClientError, ER_CFG, "replication source, " + "expected host:service or /unix.socket"); } } static void box_check_wal_mode(const char *mode_name) { + assert(mode_name != NULL); /* checked in Lua */ int mode = strindex(wal_mode_STRS, mode_name, WAL_MODE_MAX); if (mode == WAL_MODE_MAX) { tnt_raise(ClientError, ER_CFG, @@ -134,6 +149,7 @@ static void box_check_config() { box_check_wal_mode(cfg_gets("wal_mode")); + box_check_replication_source(cfg_gets("replication_source")); /* check rows_per_wal configuration */ if (cfg_geti("rows_per_wal") <= 1) { @@ -233,7 +249,6 @@ box_leave_local_standby_mode(void *data __attribute__((unused))) stat_cleanup(stat_base, IPROTO_TYPE_DML_MAX); box_set_wal_mode(cfg_gets("wal_mode")); - box_process = process_rw; if (recovery_has_remote(recovery)) recovery_follow_remote(recovery); @@ -359,15 +374,6 @@ engine_init() SophiaFactory *sophia = new SophiaFactory(); sophia->init(); engine_register(sophia); - - /* Prepare storage and recover data. - * - * This is first phase of recover, schema is not known yet. - * Internal sophia spaces (databases) are created in - * recover-delay mode and not accessible yet. - * Recover completes on first engine index creation. - */ - sophia->recover(); } void @@ -419,6 +425,7 @@ box_init() space_end_recover_snapshot(); snapshot_save(recovery); } + fiber_gc(); title("orphan", NULL); recovery_follow_local(recovery, @@ -454,8 +461,8 @@ snapshot_write_tuple(struct log_io *l, body.v_space_id = mp_bswap_u32(n); body.k_tuple = IPROTO_TUPLE; - struct iproto_header row; - memset(&row, 0, sizeof(struct iproto_header)); + struct xrow_header row; + memset(&row, 0, sizeof(struct xrow_header)); row.type = IPROTO_INSERT; row.bodycnt = 2; @@ -516,7 +523,7 @@ box_snapshot(void) return (WIFSIGNALED(status) ? EINTR : WEXITSTATUS(status)); } - slab_arena_mprotect(&tuple_arena); + slab_arena_mprotect(&memtx_arena); cord_set_name("snap"); title("dumper", "%" PRIu32, getppid()); diff --git a/src/box/box.h b/src/box/box.h index 8bb7f8751759d976a8ceb68bf10399583b88fe08..970dad6d78e101a27876755f1fe77989e5535e66 100644 --- a/src/box/box.h +++ b/src/box/box.h @@ -62,7 +62,12 @@ void box_free(void); typedef void (*box_process_func)(struct port *port, struct request *request); /** For read-write operations. */ extern box_process_func box_process; -/** For read-only port. */ + +void +box_set_ro(bool ro); + +bool +box_is_ro(void); /** Non zero if snapshot is in progress. */ extern int snapshot_pid; diff --git a/src/box/cluster.cc b/src/box/cluster.cc index c42f28bd0110fbf23c6b795ba02eb6e0d48681df..356f49ff313f4fa86dfe74d4322b4fbe4edf9c21 100644 --- a/src/box/cluster.cc +++ b/src/box/cluster.cc @@ -26,6 +26,7 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +#include "box.h" #include "cluster.h" #include "recovery.h" #include "exception.h" @@ -43,19 +44,28 @@ cluster_clock() } void -cluster_add_server(const tt_uuid *server_uuid, uint32_t server_id) +cluster_set_server(const tt_uuid *server_uuid, uint32_t server_id) { struct recovery_state *r = recovery; /** Checked in the before-commit trigger */ assert(!tt_uuid_is_nil(server_uuid)); assert(!cserver_id_is_reserved(server_id)); + if (r->server_id == server_id) { + if (tt_uuid_is_equal(&r->server_uuid, server_uuid)) + return; + say_warn("server uuid changed to %s", tt_uuid_str(server_uuid)); + assert(vclock_has(&r->vclock, server_id)); + memcpy(&r->server_uuid, server_uuid, sizeof(*server_uuid)); + return; + } + /* Add server */ vclock_add_server(&r->vclock, server_id); - if (tt_uuid_is_equal(&r->server_uuid, server_uuid)) { /* Assign local server id */ assert(r->server_id == 0); r->server_id = server_id; + box_set_ro(false); } } diff --git a/src/box/cluster.h b/src/box/cluster.h index 257e4b8c69ae8ab23730628a935161707a054ee1..b98e2ef1b1d2e3d623c65bce6aa17553854c0160 100644 --- a/src/box/cluster.h +++ b/src/box/cluster.h @@ -103,7 +103,7 @@ cserver_id_is_reserved(uint32_t id) * The server is added to the cluster lsn table with LSN 0. */ void -cluster_add_server(const tt_uuid *server_uuid, uint32_t id); +cluster_set_server(const tt_uuid *server_uuid, uint32_t id); /** }}} **/ diff --git a/src/box/engine_sophia.cc b/src/box/engine_sophia.cc index 8694511003986cbf020d2ce9d72cd27b653c8f5e..42318828566ff01fe04f35096cd3a7d7e821c317 100644 --- a/src/box/engine_sophia.cc +++ b/src/box/engine_sophia.cc @@ -26,6 +26,7 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +#include "cfg.h" #include "txn.h" #include "tuple.h" #include "engine.h" @@ -41,6 +42,7 @@ #include <string.h> #include <sys/stat.h> #include <sys/types.h> +#include <dirent.h> #include <errno.h> struct Sophia: public Engine { @@ -92,21 +94,9 @@ SophiaFactory::init() env = sp_env(); if (env == NULL) panic("failed to create sophia environment"); - void *conf = sp_ctl(env, "conf"); - sp_set(conf, "env.dir", "sophia"); - sp_set(conf, "env.create_on_write", 1); -} - -void -SophiaFactory::recover() -{ - say_info("start sophia recover"); - int rc = sp_open(env); if (rc == -1) - panic("sophia recovery failed"); - - say_info("complete"); + tnt_raise(ClientError, ER_SOPHIA, sp_error(env)); } Engine* @@ -122,7 +112,6 @@ SophiaFactory::recoveryEvent(enum engine_recovery_event event) case END_RECOVERY_SNAPSHOT: recovery.replace = sophia_replace_recover; break; - case END_RECOVERY: recovery.state = READY_NO_KEYS; recovery.replace = sophia_replace; @@ -142,15 +131,41 @@ SophiaFactory::createIndex(struct key_def *key_def) } } +static inline int +drop_repository(char *path) +{ + DIR *dir = opendir(path); + if (dir == NULL) + return -1; + char file[1024]; + struct dirent *de; + while ((de = readdir(dir))) { + if (de->d_name[0] == '.') + continue; + snprintf(file, sizeof(file), "%s/%s", path, de->d_name); + int rc = unlink(file); + if (rc == -1) { + closedir(dir); + return -1; + } + } + closedir(dir); + return rmdir(path); +} + void SophiaFactory::dropIndex(Index *index) { SophiaIndex *i = (SophiaIndex*)index; - int rc = sp_drop(i->db); + int rc = sp_destroy(i->db); if (rc == -1) tnt_raise(ClientError, ER_SOPHIA, sp_error(i->db)); i->db = NULL; i->env = NULL; + char path[PATH_MAX]; + snprintf(path, sizeof(path), "%s/%" PRIu32, + cfg_gets("sophia_dir"), index->key_def->space_id); + drop_repository(path); } void diff --git a/src/box/engine_sophia.h b/src/box/engine_sophia.h index 90c14ba9f3e2864cbcaf8afb673081f6aae7e4bb..3bb0bc0d544dd98d43fbb481c5f48e554366a3a7 100644 --- a/src/box/engine_sophia.h +++ b/src/box/engine_sophia.h @@ -32,7 +32,6 @@ struct SophiaFactory: public EngineFactory { SophiaFactory(); virtual void init(); - virtual void recover(); virtual Engine *open(); virtual Index *createIndex(struct key_def *key_def); virtual void dropIndex(Index *index); diff --git a/src/iproto.cc b/src/box/iproto.cc similarity index 99% rename from src/iproto.cc rename to src/box/iproto.cc index eefc3b7130d6fb12a5566029f8ea280194004f03..512d11f0b43a1f5b9de7661b1d94edd88b5b7de8 100644 --- a/src/iproto.cc +++ b/src/box/iproto.cc @@ -42,10 +42,12 @@ #include "scoped_guard.h" #include "memory.h" #include "msgpuck/msgpuck.h" -#include "box/replication.h" -#include "box/session.h" +#include "replication.h" +#include "session.h" #include "third_party/base64.h" #include "coio.h" +#include "xrow.h" +#include "iproto_constants.h" class IprotoConnectionShutdown: public Exception { @@ -77,7 +79,7 @@ struct iproto_request struct session *session; iproto_request_f process; /* Request message code and sync. */ - struct iproto_header header; + struct xrow_header header; /* Box request, if this is a DML */ struct request request; size_t total_len; @@ -485,10 +487,9 @@ iproto_enqueue_batch(struct iproto_connection *con, struct ibuf *in) iproto_request_new(con, iproto_process_dml); IprotoRequestGuard guard(ireq); - iproto_header_decode(&ireq->header, &pos, reqend); + xrow_header_decode(&ireq->header, &pos, reqend); ireq->total_len = pos - reqstart; /* total request length */ - /* * sic: in case of exception con->parse_size * as well as in->pos must not be advanced, to diff --git a/src/iproto.h b/src/box/iproto.h similarity index 100% rename from src/iproto.h rename to src/box/iproto.h diff --git a/src/box/iproto_constants.c b/src/box/iproto_constants.c new file mode 100644 index 0000000000000000000000000000000000000000..a0893501f7cf4bcb4e31acf23663fc7e05e1acb1 --- /dev/null +++ b/src/box/iproto_constants.c @@ -0,0 +1,154 @@ +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "iproto_constants.h" + +const unsigned char iproto_key_type[IPROTO_KEY_MAX] = +{ + /* {{{ header */ + /* 0x00 */ MP_UINT, /* IPROTO_REQUEST_TYPE */ + /* 0x01 */ MP_UINT, /* IPROTO_SYNC */ + /* 0x02 */ MP_UINT, /* IPROTO_SERVER_ID */ + /* 0x03 */ MP_UINT, /* IPROTO_LSN */ + /* 0x04 */ MP_DOUBLE, /* IPROTO_TIMESTAMP */ + /* }}} */ + + /* {{{ unused */ + /* 0x05 */ MP_UINT, + /* 0x06 */ MP_UINT, + /* 0x07 */ MP_UINT, + /* 0x08 */ MP_UINT, + /* 0x09 */ MP_UINT, + /* 0x0a */ MP_UINT, + /* 0x0b */ MP_UINT, + /* 0x0c */ MP_UINT, + /* 0x0d */ MP_UINT, + /* 0x0e */ MP_UINT, + /* 0x0f */ MP_UINT, + /* }}} */ + + /* {{{ body -- integer keys */ + /* 0x10 */ MP_UINT, /* IPROTO_SPACE_ID */ + /* 0x11 */ MP_UINT, /* IPROTO_INDEX_ID */ + /* 0x12 */ MP_UINT, /* IPROTO_LIMIT */ + /* 0x13 */ MP_UINT, /* IPROTO_OFFSET */ + /* 0x14 */ MP_UINT, /* IPROTO_ITERATOR */ + /* }}} */ + + /* {{{ unused */ + /* 0x15 */ MP_UINT, + /* 0x16 */ MP_UINT, + /* 0x17 */ MP_UINT, + /* 0x18 */ MP_UINT, + /* 0x19 */ MP_UINT, + /* 0x1a */ MP_UINT, + /* 0x1b */ MP_UINT, + /* 0x1c */ MP_UINT, + /* 0x1d */ MP_UINT, + /* 0x1e */ MP_UINT, + /* 0x1f */ MP_UINT, + /* }}} */ + + /* {{{ body -- all keys */ + /* 0x20 */ MP_ARRAY, /* IPROTO_KEY */ + /* 0x21 */ MP_ARRAY, /* IPROTO_TUPLE */ + /* 0x22 */ MP_STR, /* IPROTO_FUNCTION_NAME */ + /* 0x23 */ MP_STR, /* IPROTO_USER_NAME */ + /* 0x24 */ MP_STR, /* IPROTO_SERVER_UUID */ + /* 0x25 */ MP_STR, /* IPROTO_CLUSTER_UUID */ + /* 0x26 */ MP_MAP, /* IPROTO_VCLOCK */ + /* }}} */ +}; + +const char *iproto_type_strs[] = +{ + NULL, + "SELECT", + "INSERT", + "REPLACE", + "UPDATE", + "DELETE", + "CALL", + "AUTH" +}; + +#define bit(c) (1ULL<<IPROTO_##c) +const uint64_t iproto_body_key_map[IPROTO_TYPE_DML_MAX] = { + 0, /* unused */ + bit(SPACE_ID) | bit(LIMIT) | bit(KEY), /* SELECT */ + bit(SPACE_ID) | bit(TUPLE), /* INSERT */ + bit(SPACE_ID) | bit(TUPLE), /* REPLACE */ + bit(SPACE_ID) | bit(KEY) | bit(TUPLE), /* UPDATE */ + bit(SPACE_ID) | bit(KEY), /* DELETE */ + bit(FUNCTION_NAME) | bit(TUPLE), /* CALL */ + bit(USER_NAME) | bit(TUPLE) /* AUTH */ +}; +#undef bit + +const char *iproto_key_strs[IPROTO_KEY_MAX] = { + "type", /* 0x00 */ + "sync", /* 0x01 */ + "server_id", /* 0x02 */ + "lsn", /* 0x03 */ + "timestamp", /* 0x04 */ + "", /* 0x05 */ + "", /* 0x06 */ + "", /* 0x07 */ + "", /* 0x08 */ + "", /* 0x09 */ + "", /* 0x0a */ + "", /* 0x0b */ + "", /* 0x0c */ + "", /* 0x0d */ + "", /* 0x0e */ + "", /* 0x0f */ + "space_id", /* 0x10 */ + "index_id", /* 0x11 */ + "limit", /* 0x12 */ + "offset", /* 0x13 */ + "iterator", /* 0x14 */ + "", /* 0x15 */ + "", /* 0x16 */ + "", /* 0x17 */ + "", /* 0x18 */ + "", /* 0x19 */ + "", /* 0x1a */ + "", /* 0x1b */ + "", /* 0x1c */ + "", /* 0x1d */ + "", /* 0x1e */ + "", /* 0x1f */ + "key", /* 0x20 */ + "tuple", /* 0x21 */ + "function name", /* 0x22 */ + "user name", /* 0x23 */ + "server UUID" /* 0x24 */ + "cluster UUID" /* 0x25 */ + "vector clock" /* 0x26 */ +}; + diff --git a/src/iproto_constants.h b/src/box/iproto_constants.h similarity index 59% rename from src/iproto_constants.h rename to src/box/iproto_constants.h index 0f79ed989b7f6c642847f2ea0d87a42509cdef46..e89ad4fd3301e3912b8d8753503b00ef1dd833f7 100644 --- a/src/iproto_constants.h +++ b/src/box/iproto_constants.h @@ -30,7 +30,6 @@ */ #include <stdbool.h> #include <stdint.h> -#include <sys/uio.h> /* struct iovec */ #include <msgpuck/msgpuck.h> #if defined(__cplusplus) @@ -41,8 +40,8 @@ enum { /** Maximal iproto package body length (2GiB) */ IPROTO_BODY_LEN_MAX = 2147483648UL, IPROTO_GREETING_SIZE = 128, - IPROTO_FIXHEADER_SIZE = 5, /* len + (padding) */ - XLOG_FIXHEADER_SIZE = 19 /* marker + len + prev crc32 + cur crc32 + (padding) */ + /** marker + len + prev crc32 + cur crc32 + (padding) */ + XLOG_FIXHEADER_SIZE = 19 }; @@ -82,7 +81,7 @@ enum iproto_key { bit(OFFSET) | bit(ITERATOR) | bit(KEY) | \ bit(TUPLE) | bit(FUNCTION_NAME) | bit(USER_NAME)) static inline bool -iproto_header_has_key(const char *pos, const char *end) +xrow_header_has_key(const char *pos, const char *end) { unsigned char key = pos < end ? *pos : (unsigned char) IPROTO_KEY_MAX; return key < IPROTO_KEY_MAX && IPROTO_HEAD_BMAP & (1ULL<<key); @@ -161,132 +160,6 @@ iproto_type_is_error(uint32_t type) return (type & IPROTO_TYPE_ERROR) != 0; } -enum { - IPROTO_PACKET_HEAD_IOVMAX = 1, - IPROTO_PACKET_BODY_IOVMAX = 2, - IPROTO_PACKET_IOVMAX = IPROTO_PACKET_HEAD_IOVMAX + - IPROTO_PACKET_BODY_IOVMAX -}; - -enum { IPROTO_ROW_IOVMAX = IPROTO_PACKET_IOVMAX + 1 }; - - -struct iproto_header { - uint32_t type; - uint32_t server_id; - uint64_t sync; - uint64_t lsn; - double tm; - - int bodycnt; - struct iovec body[IPROTO_PACKET_BODY_IOVMAX]; -}; - -void -iproto_header_decode(struct iproto_header *header, - const char **pos, const char *end); -struct tt_uuid; - -void -iproto_decode_uuid(const char **pos, struct tt_uuid *out); - -char * -iproto_encode_uuid(char *pos, const struct tt_uuid *in); - -/** Return a 4-byte numeric error code, with status flags. */ -static inline uint32_t -iproto_encode_error(uint32_t error) -{ - return error | IPROTO_TYPE_ERROR; -} - -int -iproto_header_encode(const struct iproto_header *header, - struct iovec *out); - -int -iproto_row_encode(const struct iproto_header *row, struct iovec *out); - -/** - * \brief Decode ERROR and re-throw it as ClientError exception - * \param row - */ -void -iproto_decode_error(struct iproto_header *row); - -/** - * \brief Encode AUTH command - * \param[out] row - * \param greeting - IPROTO greeting - * \param login - user login - * \param password - user password - */ -void -iproto_encode_auth(struct iproto_header *row, const char *greeting, - const char *login, const char *password); - -/** - * \brief Encode SUBSCRIBE command - * \param row[out] - * \param cluster_uuid cluster uuid - * \param server_uuid server uuid - * \param vclock server vclock - */ -void -iproto_encode_subscribe(struct iproto_header *row, - const struct tt_uuid *cluster_uuid, - const struct tt_uuid *server_uuid, - const struct vclock *vclock); - -/** - * \brief Decode SUBSCRIBE command - * \param row - * \param[out] cluster_uuid - * \param[out] server_uuid - * \param[out] vclock - */ -void -iproto_decode_subscribe(struct iproto_header *row, struct tt_uuid *cluster_uuid, - struct tt_uuid *server_uuid, struct vclock *vclock); - -/** - * \brief Encode JOIN command - * \param[out] row - * \param server_uuid - */ -void -iproto_encode_join(struct iproto_header *row, const struct tt_uuid *server_uuid); - -/** - * \brief Decode JOIN command - * \param row - * \param[out] server_uuid - */ -static inline void -iproto_decode_join(struct iproto_header *row, struct tt_uuid *server_uuid) -{ - return iproto_decode_subscribe(row, NULL, server_uuid, NULL); -} - -/** - * \brief Encode end of stream command (a response to JOIN command) - * \param row[out] - * \param vclock - */ -void -iproto_encode_eos(struct iproto_header *row, const struct vclock *vclock); - -/** - * \brief Decode end of stream command (a response to JOIN command) - * \param row - * \param[out] vclock - */ -static inline void -iproto_decode_eos(struct iproto_header *row, struct vclock *vclock) -{ - return iproto_decode_subscribe(row, NULL, NULL, vclock); -} - #if defined(__cplusplus) } /* extern "C" */ #endif diff --git a/src/iproto_port.cc b/src/box/iproto_port.cc similarity index 96% rename from src/iproto_port.cc rename to src/box/iproto_port.cc index df15328626616bdc0c921a5bb0bbdcb08226a6b0..b1f227dd1d36d1f2ce459f9ca582ee2f4a6c3174 100644 --- a/src/iproto_port.cc +++ b/src/box/iproto_port.cc @@ -27,7 +27,7 @@ * SUCH DAMAGE. */ #include "iproto_port.h" - +#include "iproto_constants.h" /* m_ - msgpack meta, k_ - key, v_ - value */ struct iproto_header_bin { @@ -61,6 +61,13 @@ static const struct iproto_body_bin iproto_error_bin = { 0x81, IPROTO_ERROR, 0xdb, 0 }; +/** Return a 4-byte numeric error code, with status flags. */ +static inline uint32_t +iproto_encode_error(uint32_t error) +{ + return error | IPROTO_TYPE_ERROR; +} + void iproto_reply_ping(struct obuf *out, uint64_t sync) { diff --git a/src/iproto_port.h b/src/box/iproto_port.h similarity index 96% rename from src/iproto_port.h rename to src/box/iproto_port.h index 0c45798ceac4da8d2d8ffbd0cee05acf07737fee..0613854abf911c67eb00b04c6ccb513f3aaad344 100644 --- a/src/iproto_port.h +++ b/src/box/iproto_port.h @@ -28,13 +28,12 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#include "box/box.h" -#include "box/request.h" -#include "box/port.h" -#include "box/tuple.h" +#include "box.h" +#include "request.h" +#include "port.h" +#include "tuple.h" #include "iobuf.h" #include "msgpuck/msgpuck.h" -#include "iproto_constants.h" /** * struct iproto_port users need to be careful to: diff --git a/src/box/log_io.cc b/src/box/log_io.cc index 69e6d1660d96a257229c9f05d4e026eaeb7aeef4..349538e4d880f610e82999a67a1af34dfd70fe9f 100644 --- a/src/box/log_io.cc +++ b/src/box/log_io.cc @@ -36,11 +36,11 @@ #include "third_party/tarantool_eio.h" #include "fiob.h" #include "msgpuck/msgpuck.h" -#include "iproto_constants.h" #include "scoped_guard.h" #define MH_UNDEF 1 /* conflicts with mh_nodeids_t */ #include "recovery.h" /* for mh_cluster */ #include "vclock.h" +#include "iproto_constants.h" /* * marker is MsgPack fixext2 @@ -273,7 +273,7 @@ format_filename(struct log_dir *dir, int64_t signt, enum log_suffix suffix) /* {{{ struct log_io_cursor */ static int -row_reader(FILE *f, struct iproto_header *row) +row_reader(FILE *f, struct xrow_header *row) { const char *data; @@ -326,15 +326,15 @@ row_reader(FILE *f, struct iproto_header *row) tnt_raise(ClientError, ER_INVALID_MSGPACK, "invalid crc32"); data = bodybuf; - iproto_header_decode(row, &data, bodybuf + len); + xrow_header_decode(row, &data, bodybuf + len); return 0; } int -xlog_encode_row(const struct iproto_header *row, struct iovec *iov) +xlog_encode_row(const struct xrow_header *row, struct iovec *iov) { - int iovcnt = iproto_header_encode(row, iov + 1) + 1; + int iovcnt = xrow_header_encode(row, iov + 1) + 1; char *fixheader = (char *) region_alloc(&fiber()->gc, XLOG_FIXHEADER_SIZE); uint32_t len = 0; @@ -362,7 +362,7 @@ xlog_encode_row(const struct iproto_header *row, struct iovec *iov) iov[0].iov_base = fixheader; iov[0].iov_len = XLOG_FIXHEADER_SIZE; - assert(iovcnt <= XLOG_ROW_IOVMAX); + assert(iovcnt <= XROW_IOVMAX); return iovcnt; } @@ -400,7 +400,7 @@ log_io_cursor_close(struct log_io_cursor *i) * */ int -log_io_cursor_next(struct log_io_cursor *i, struct iproto_header *row) +log_io_cursor_next(struct log_io_cursor *i, struct xrow_header *row) { struct log_io *l = i->log; log_magic_t magic; @@ -711,7 +711,8 @@ log_io_verify_meta(struct log_io *l, const tt_uuid *server_uuid) if (server_uuid != NULL && !tt_uuid_is_nil(server_uuid) && !tt_uuid_is_equal(server_uuid, &l->server_uuid)) { say_error("%s: invalid server uuid", l->filename); - return -1; + if (l->dir->panic_if_error) + return -1; } return 0; } diff --git a/src/box/log_io.h b/src/box/log_io.h index 7cc63892b2249f71cc5384a2b098d0d2539acb31..52cf559db03c006f7eef059b21965a14afcfb680 100644 --- a/src/box/log_io.h +++ b/src/box/log_io.h @@ -34,7 +34,7 @@ #include <sys/uio.h> #include "trivia/util.h" #include "third_party/tarantool_ev.h" -#include "iproto_constants.h" +#include "xrow.h" #include "tt_uuid.h" #include "vclock.h" @@ -132,10 +132,9 @@ void log_io_cursor_close(struct log_io_cursor *i); int -log_io_cursor_next(struct log_io_cursor *i, struct iproto_header *packet); +log_io_cursor_next(struct log_io_cursor *i, struct xrow_header *packet); int -xlog_encode_row(const struct iproto_header *packet, struct iovec *iov); -enum { XLOG_ROW_IOVMAX = IPROTO_PACKET_IOVMAX + 1 }; +xlog_encode_row(const struct xrow_header *packet, struct iovec *iov); typedef uint32_t log_magic_t; diff --git a/src/box/lua/info.cc b/src/box/lua/info.cc index ec13926417ad5f5ae6fd001d809b03f2394dbe47..f1616df17f60b5bb94d5b3490b62e34f65a7ba72 100644 --- a/src/box/lua/info.cc +++ b/src/box/lua/info.cc @@ -59,11 +59,6 @@ lbox_info_recovery_last_update_tstamp(struct lua_State *L) static int lbox_info_server(struct lua_State *L) { - if (recovery->server_id == 0) { - lua_pushnil(L); - return 1; - } - lua_createtable(L, 0, 2); lua_pushliteral(L, "id"); lua_pushinteger(L, recovery->server_id); @@ -72,8 +67,11 @@ lbox_info_server(struct lua_State *L) lua_pushlstring(L, tt_uuid_str(&recovery->server_uuid), UUID_STR_LEN); lua_settable(L, -3); lua_pushliteral(L, "lsn"); - luaL_pushnumber64(L, vclock_get(&recovery->vclock, - recovery->server_id)); + luaL_pushinumber64(L, vclock_get(&recovery->vclock, + recovery->server_id)); + lua_settable(L, -3); + lua_pushliteral(L, "ro"); + lua_pushboolean(L, box_is_ro()); lua_settable(L, -3); return 1; diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua index 6743b23da7998e9fa98aa90ae65135bd6413a8c2..126bc550ce075005651b18de318ada60f0b1f2a1 100644 --- a/src/box/lua/load_cfg.lua +++ b/src/box/lua/load_cfg.lua @@ -32,6 +32,7 @@ local default_cfg = { work_dir = nil, snap_dir = ".", wal_dir = ".", + sophia_dir = './sophia', logger = nil, logger_nonblock = true, log_level = 5, @@ -51,14 +52,14 @@ local default_cfg = { username = nil , coredump = false, - -- snap_daemon + -- snapshot_daemon snapshot_period = 0, -- 0 = disabled snapshot_count = 6, } -- types of available options -- could be comma separated lua types or 'any' if any type is allowed -local template_cfg = { +local template = { listen = 'string, number', slab_alloc_arena = 'number', slab_alloc_minimal = 'number', @@ -66,6 +67,7 @@ local template_cfg = { work_dir = 'string', snap_dir = 'string', wal_dir = 'string', + sophia_dir = 'string', logger = 'string', logger_nonblock = 'boolean', log_level = 'number', @@ -97,50 +99,14 @@ local dynamic_cfg = { too_long_threshold = ffi.C.box_set_too_long_threshold, snap_io_rate_limit = ffi.C.box_set_snap_io_rate_limit, - -- snap_daemon - snapshot_period = box.internal.snap_daemon.set_snapshot_period, - snapshot_count = box.internal.snap_daemon.set_snapshot_count, + -- snapshot_daemon + snapshot_period = box.internal.snapshot_daemon.set_snapshot_period, + snapshot_count = box.internal.snapshot_daemon.set_snapshot_count, } -local function reload_cfg(oldcfg, newcfg) - if newcfg == nil then - newcfg = {} - end - for key, val in pairs(newcfg) do - if dynamic_cfg[key] == nil then - box.error(box.error.RELOAD_CFG, key); - end - if val == "" then - val = nil - end - if wrapper_cfg[key] ~= nil then - val = wrapper_cfg[key](val) - end - dynamic_cfg[key](val) - rawset(oldcfg, key, val) - end - if type(box.on_reload_configuration) == 'function' then - box.on_reload_configuration() - end -end - -local box = require('box') --- Move all box members to box_saved -local box_configured = {} -for k, v in pairs(box) do - box_configured[k] = v - box[k] = nil -end - -setmetatable(box, { - __index = function(table, index) - error("Please call box.cfg{} first") - end -}) - -local function check_param_table(table, template) +local function prepare_cfg(table) if table == nil then - return + return {} end if type(table) ~= 'table' then error("Error: cfg should be a table") @@ -149,9 +115,13 @@ local function check_param_table(table, template) if table.dont_check then return end + local newtable = {} for k,v in pairs(table) do if template[k] == nil then error("Error: cfg parameter '" .. k .. "' is unexpected") + elseif v == "" or v == nil then + -- "" and NULL = ffi.cast('void *', 0) set option to default value + v = default_cfg[k] elseif template[k] == 'any' then -- any type is ok elseif (string.find(template[k], ',') == nil) then @@ -166,29 +136,52 @@ local function check_param_table(table, template) error("Error: cfg parameter '" .. k .. "' should be one of types: " .. template[k]) end end + if wrapper_cfg[k] ~= nil then + v = wrapper_cfg[k](v) + end + newtable[k] = v end + return newtable end - -local function update_param_table(table, defaults) - if table == nil then - table = {} - end - for k,v in pairs(defaults) do - if table[k] == nil then - table[k] = v +local function reload_cfg(oldcfg, newcfg) + newcfg = prepare_cfg(newcfg) + for key, val in pairs(newcfg) do + if dynamic_cfg[key] == nil then + box.error(box.error.RELOAD_CFG, key); end + dynamic_cfg[key](val) + rawset(oldcfg, key, val) + end + if type(box.on_reload_configuration) == 'function' then + box.on_reload_configuration() end - return table end -function box.cfg(cfg) - check_param_table(cfg, template_cfg) - cfg = update_param_table(cfg, default_cfg) +local box = require('box') +-- Move all box members to box_saved +local box_configured = {} +for k, v in pairs(box) do + box_configured[k] = v + -- box.net.box uses box.error and box.internal + if k ~= 'error' and k ~= 'internal' then + box[k] = nil + end +end + +setmetatable(box, { + __index = function(table, index) + error(debug.traceback("Please call box.cfg{} first")) + error("Please call box.cfg{} first") + end +}) - for k,v in pairs(wrapper_cfg) do - -- options that can be number or string - cfg[k] = wrapper_cfg[k](cfg[k]) +function box.cfg(cfg) + cfg = prepare_cfg(cfg) + for k,v in pairs(default_cfg) do + if cfg[k] == nil then + cfg[k] = v + end end -- Restore box members from box_saved after initial configuration for k, v in pairs(box_configured) do @@ -205,7 +198,7 @@ function box.cfg(cfg) }) ffi.C.load_cfg() - box.internal.snap_daemon.start() + box.internal.snapshot_daemon.start() end jit.off(box.cfg) jit.off(reload_cfg) diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index bb1e9a46f2f4a0d167c9a0b39baad5a224a7494b..0999acf65e7b9f28f83cd8880da1f253c8eaa09b 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -188,7 +188,7 @@ box.schema.space.create = function(name, options) engine = 'string', id = 'number', field_count = 'number', - user = 'user', + user = 'string, number', } local options_defaults = { engine = 'memtx', @@ -303,6 +303,7 @@ box.schema.index.create = function(space_id, name, options) parts = 'table', unique = 'boolean', id = 'number', + if_not_exists = 'boolean', } local options_defaults = { type = 'tree', @@ -315,6 +316,13 @@ box.schema.index.create = function(space_id, name, options) options.parts = update_index_parts(options.parts) local _index = box.space[box.schema.INDEX_ID] + if _index.index.name:get{space_id, name} then + if options.if_not_exists then + return box.space[space_id].index[name], "not created" + else + box.error(box.error.INDEX_EXISTS, name) + end + end local unique = options.unique and 1 or 0 local part_count = bit.rshift(#options.parts, 1) diff --git a/src/box/lua/slab.cc b/src/box/lua/slab.cc index 4095ce312e2907288854a0ab631e5c57e7a53f9b..400c53d95784a745b1ed4c9def4e432bb9e83a4c 100644 --- a/src/box/lua/slab.cc +++ b/src/box/lua/slab.cc @@ -37,6 +37,7 @@ extern "C" { #include "box/tuple.h" #include "small/small.h" +#include "memory.h" /** A callback passed into salloc_stat() and invoked for every slab class. */ extern "C" { @@ -88,7 +89,7 @@ lbox_slab_info(struct lua_State *L) lua_pushstring(L, "slabs"); lua_newtable(L); luaL_setmaphint(L, -1); - small_stats(&talloc, &totals, small_stats_lua_cb, L); + small_stats(&memtx_alloc, &totals, small_stats_lua_cb, L); lua_settable(L, -3); lua_pushstring(L, "arena_used"); @@ -102,15 +103,15 @@ lbox_slab_info(struct lua_State *L) char value[32]; double items_used_ratio = 100 * ((double)totals.used) - / ((double)talloc.cache->arena->prealloc + 0.0001); + / ((double)memtx_alloc.cache->arena->prealloc + 0.0001); snprintf(value, sizeof(value), "%0.1lf%%", items_used_ratio); lua_pushstring(L, "items_used_ratio"); lua_pushstring(L, value); lua_settable(L, -3); double arena_used_ratio = 100 - * ((double)talloc.cache->arena->used) - / ((double)talloc.cache->arena->prealloc + 0.0001); + * ((double)memtx_alloc.cache->arena->used) + / ((double)memtx_alloc.cache->arena->prealloc + 0.0001); snprintf(value, sizeof(value), "%0.1lf%%", arena_used_ratio); lua_pushstring(L, "arena_used_ratio"); lua_pushstring(L, value); @@ -119,10 +120,26 @@ lbox_slab_info(struct lua_State *L) return 1; } +static int +lbox_runtime_info(struct lua_State *L) +{ + lua_newtable(L); + + lua_pushstring(L, "used"); + luaL_pushnumber64(L, runtime.used); + lua_settable(L, -3); + + lua_pushstring(L, "maxalloc"); + luaL_pushnumber64(L, runtime.maxalloc); + lua_settable(L, -3); + + return 1; +} + static int lbox_slab_check(struct lua_State *L __attribute__((unused))) { - slab_cache_check(talloc.cache); + slab_cache_check(memtx_alloc.cache); return 0; } @@ -142,6 +159,16 @@ box_lua_slab_init(struct lua_State *L) lua_pushcfunction(L, lbox_slab_check); lua_settable(L, -3); + lua_settable(L, -3); /* box.slab */ + + lua_pushstring(L, "runtime"); + lua_newtable(L); + + lua_pushstring(L, "info"); + lua_pushcfunction(L, lbox_runtime_info); lua_settable(L, -3); - lua_pop(L, 1); + + lua_settable(L, -3); /* box.runtime */ + + lua_pop(L, 1); /* box. */ } diff --git a/src/box/lua/snapshot_daemon.lua b/src/box/lua/snapshot_daemon.lua index 6dc9cff6ee46bdec3935cb5a6696c63e855e87ca..8b8938d2b6196de60a856e7e2cf227d097d64579 100644 --- a/src/box/lua/snapshot_daemon.lua +++ b/src/box/lua/snapshot_daemon.lua @@ -1,4 +1,4 @@ --- snap_daemon.lua (internal file) +-- snapshot_daemon.lua (internal file) do local log = require 'log' @@ -7,7 +7,7 @@ do local yaml = require 'yaml' local errno = require 'errno' - local PREFIX = 'snap_daemon' + local PREFIX = 'snapshot_daemon' local daemon = { status = 'stopped' } @@ -239,6 +239,10 @@ do end, set_snapshot_count = function(snapshot_count) + if math.floor(snapshot_count) ~= snapshot_count then + box.error(box.error.PROC_LUA, + "snapshot_count must be integer") + end local daemon = box.internal[PREFIX] or daemon log.info("new snapshot count is %s", tostring(snapshot_count)) diff --git a/src/box/lua/tuple.cc b/src/box/lua/tuple.cc index c5f0957892afb8ebb0a40491ebd720b6beeb76f9..a5057c1bec84f1109301c397d42044102ccd002f 100644 --- a/src/box/lua/tuple.cc +++ b/src/box/lua/tuple.cc @@ -374,3 +374,16 @@ box_lua_tuple_init(struct lua_State *L) box_lua_slab_init(L); } + +struct tuple * +boxffi_tuple_update(struct tuple *tuple, const char *expr, const char *expr_end) +{ + RegionGuard region_guard(&fiber()->gc); + try { + return tuple_update(tuple_format_ber, + region_alloc_cb, &fiber()->gc, + tuple, expr, expr_end, 1); + } catch (ClientError *e) { + return NULL; + } +} diff --git a/src/box/lua/tuple.h b/src/box/lua/tuple.h index bdcb840840c3331f1a4cf3646fbdbad4b12f2a71..05a830b168ad46897ccd6fc49a28bc52235d8db2 100644 --- a/src/box/lua/tuple.h +++ b/src/box/lua/tuple.h @@ -52,4 +52,15 @@ luamp_encodestack(struct lua_State *L, struct tbuf *b, void box_lua_tuple_init(struct lua_State *L); +#if defined(__cplusplus) +extern "C" { +#endif + +struct tuple * +boxffi_tuple_update(struct tuple *tuple, const char *expr, const char *expr_end); + +#if defined(__cplusplus) +} /* extern "C" */ +#endif + #endif /* INCLUDES_TARANTOOL_MOD_BOX_LUA_TUPLE_H */ diff --git a/src/box/lua/tuple.lua b/src/box/lua/tuple.lua index 695d9afd25e9957e20645c721e842e2522854fef..515c792f47aeaa9ef511d531df7e13214676016f 100644 --- a/src/box/lua/tuple.lua +++ b/src/box/lua/tuple.lua @@ -4,6 +4,7 @@ local ffi = require('ffi') local yaml = require('yaml') local msgpackffi = require('msgpackffi') local fun = require('fun') +local internal = require('box.internal') ffi.cdef([[ struct tuple @@ -39,10 +40,26 @@ tuple_next(struct tuple_iterator *it); void tuple_to_buf(struct tuple *tuple, char *buf); + +struct tuple * +boxffi_tuple_update(struct tuple *tuple, const char *expr, const char *expr_end); ]]) local builtin = ffi.C +local const_struct_tuple_ref_t = ffi.typeof('const struct tuple&') + +local tuple_gc = function(tuple) + builtin.tuple_ref(tuple, -1) +end + +local tuple_bless = function(tuple) + -- update in-place, do not spent time calling tuple_ref + local tuple2 = ffi.gc(ffi.cast(const_struct_tuple_ref_t, tuple), tuple_gc) + tuple._refs = tuple._refs + 1 + return tuple2 +end + local tuple_iterator_t = ffi.typeof('struct tuple_iterator') local function tuple_iterator_next(it, tuple, pos) @@ -130,6 +147,19 @@ local function tuple_findall(tuple, offset, val) :totable() end +local function tuple_update(tuple, expr) + if type(expr) ~= 'table' then + error("Usage: tuple:update({ { op, field, arg}+ })") + end + expr = internal.normalize_update_ops(expr) + local pexpr, pexpr_end = msgpackffi.encode_tuple(expr) + local tuple = builtin.boxffi_tuple_update(tuple, pexpr, pexpr_end) + if tuple == NULL then + return box.error() + end + return tuple_bless(tuple) +end + -- Set encode hooks for msgpackffi local function tuple_to_msgpack(buf, tuple) buf:reserve(tuple._bsize) @@ -137,7 +167,6 @@ local function tuple_to_msgpack(buf, tuple) buf.p = buf.p + tuple._bsize end - msgpackffi.on_encode(ffi.typeof('const struct tuple &'), tuple_to_msgpack) @@ -153,25 +182,13 @@ local methods = { ["findall"] = tuple_findall; ["unpack"] = tuple_unpack; ["totable"] = tuple_totable; + ["update"] = tuple_update; ["bsize"] = function(tuple) return tonumber(tuple._bsize) end; ["__serialize"] = tuple_totable; -- encode hook for msgpack/yaml/json } -local const_struct_tuple_ref_t = ffi.typeof('const struct tuple&') - -local tuple_gc = function(tuple) - builtin.tuple_ref(tuple, -1) -end - -local tuple_bless = function(tuple) - -- update in-place, do not spent time calling tuple_ref - local tuple2 = ffi.gc(ffi.cast(const_struct_tuple_ref_t, tuple), tuple_gc) - tuple._refs = tuple._refs + 1 - return tuple2 -end - local tuple_field = function(tuple, field_n) local field = builtin.tuple_field(tuple, field_n - 1) if field == nil then diff --git a/src/box/recovery.cc b/src/box/recovery.cc index b56d40e7a3adda6f3fbd9264ed0fde00e1848c0b..e782e96bf8cd11a01a5713ca83a1f1e8be48ddfb 100644 --- a/src/box/recovery.cc +++ b/src/box/recovery.cc @@ -42,7 +42,7 @@ #include "replica.h" #include "fiber.h" #include "msgpuck/msgpuck.h" -#include "iproto_constants.h" +#include "xrow.h" #include "crc32.h" #include "scoped_guard.h" #include "box/cluster.h" @@ -118,7 +118,7 @@ const char *wal_mode_STRS[] = { "none", "write", "fsync", NULL }; /* {{{ LSN API */ static void -fill_lsn(struct recovery_state *r, struct iproto_header *row) +fill_lsn(struct recovery_state *r, struct xrow_header *row) { if (row == NULL || row->server_id == 0) { /* Local request */ @@ -226,7 +226,6 @@ recovery_free() */ log_io_close(&r->current_wal); } - recovery= NULL; } @@ -239,7 +238,7 @@ recovery_setup_panic(struct recovery_state *r, bool on_snap_error, } void -recovery_process(struct recovery_state *r, struct iproto_header *row) +recovery_process(struct recovery_state *r, struct xrow_header *row) { /* Check lsn */ int64_t current_signt = vclock_get(&r->vclock, row->server_id); @@ -326,7 +325,7 @@ recover_wal(struct recovery_state *r, struct log_io *l) log_io_cursor_open(&i, l); - struct iproto_header row; + struct xrow_header row; while (log_io_cursor_next(&i, &row) == 0) { try { recovery_process(r, &row); @@ -483,9 +482,7 @@ recover_remaining_wals(struct recovery_state *r) result = -1; } -#if 0 region_free(&fiber()->gc); -#endif return result; } @@ -665,7 +662,7 @@ struct wal_write_request { /* Auxiliary. */ int64_t res; struct fiber *fiber; - struct iproto_header *row; + struct xrow_header *row; }; /* Context of the WAL writer thread. */ @@ -979,7 +976,7 @@ wal_fill_batch(struct log_io *wal, struct fio_batch *batch, int rows_per_wal, assert(max_rows > 0); fio_batch_start(batch, max_rows); - struct iovec iov[XLOG_ROW_IOVMAX]; + struct iovec iov[XROW_IOVMAX]; while (req != NULL && !fio_batch_has_space(batch, nelem(iov))) { int iovcnt = xlog_encode_row(req->row, iov); fio_batch_add(batch, iov, iovcnt); @@ -1026,6 +1023,7 @@ wal_write_to_disk(struct recovery_state *r, struct wal_writer *writer, break; req = write_end; } + fiber_gc(); STAILQ_SPLICE(input, write_end, wal_fifo_entry, rollback); STAILQ_CONCAT(commit, input); } @@ -1073,7 +1071,7 @@ wal_writer_thread(void *worker_args) * to be written to disk and wait until this task is completed. */ int -wal_write(struct recovery_state *r, struct iproto_header *row) +wal_write(struct recovery_state *r, struct xrow_header *row) { /* * Bump current LSN even if wal_mode = NONE, so that @@ -1120,7 +1118,7 @@ wal_write(struct recovery_state *r, struct iproto_header *row) /* {{{ box.snapshot() */ void -snapshot_write_row(struct log_io *l, struct iproto_header *row) +snapshot_write_row(struct log_io *l, struct xrow_header *row) { static uint64_t bytes; ev_tstamp elapsed; @@ -1140,7 +1138,7 @@ snapshot_write_row(struct log_io *l, struct iproto_header *row) row->lsn = ++l->rows; row->sync = 0; /* don't write sync to wal */ - struct iovec iov[XLOG_ROW_IOVMAX]; + struct iovec iov[XROW_IOVMAX]; int iovcnt = xlog_encode_row(row, iov); /* TODO: use writev here */ @@ -1156,7 +1154,7 @@ snapshot_write_row(struct log_io *l, struct iproto_header *row) if (l->rows % 100000 == 0) say_crit("%.1fM rows written", l->rows / 1000000.); - region_free_after(&fiber()->gc, 128 * 1024); + fiber_gc(); if (r->snap_io_rate_limit != UINT64_MAX) { if (last == 0) { diff --git a/src/box/recovery.h b/src/box/recovery.h index 0c5a484b95586e5381e98322e4c7e008312f1cd9..60fff69fa0e90325a6225b310dac179d52a17d9e 100644 --- a/src/box/recovery.h +++ b/src/box/recovery.h @@ -36,6 +36,7 @@ #include "vclock.h" #include "tt_uuid.h" #include "replica.h" +#include "small/region.h" #if defined(__cplusplus) extern "C" { @@ -44,7 +45,7 @@ extern "C" { struct fiber; struct tbuf; -typedef void (row_handler)(void *, struct iproto_header *packet); +typedef void (row_handler)(void *, struct xrow_header *packet); typedef void (snapshot_handler)(struct log_io *); typedef void (join_handler)(const struct tt_uuid *node_uuid); @@ -113,15 +114,15 @@ void recovery_follow_local(struct recovery_state *r, ev_tstamp wal_dir_rescan_de void recovery_finalize(struct recovery_state *r); int recover_wal(struct recovery_state *r, struct log_io *l); -int wal_write(struct recovery_state *r, struct iproto_header *packet); +int wal_write(struct recovery_state *r, struct xrow_header *packet); void recovery_setup_panic(struct recovery_state *r, bool on_snap_error, bool on_wal_error); -void recovery_process(struct recovery_state *r, struct iproto_header *packet); +void recovery_process(struct recovery_state *r, struct xrow_header *packet); struct fio_batch; void -snapshot_write_row(struct log_io *l, struct iproto_header *packet); +snapshot_write_row(struct log_io *l, struct xrow_header *packet); void snapshot_save(struct recovery_state *r); #if defined(__cplusplus) diff --git a/src/box/replica.cc b/src/box/replica.cc index bb9a9975876aa862eaa310bf33807b0363297407..deff8eafbd89714840e344855d6e5b671eda392e 100644 --- a/src/box/replica.cc +++ b/src/box/replica.cc @@ -38,48 +38,48 @@ #include "scoped_guard.h" #include "coio_buf.h" #include "recovery.h" -#include "iproto_constants.h" +#include "xrow.h" #include "msgpuck/msgpuck.h" #include "session.h" #include "box/cluster.h" +#include "iproto_constants.h" static const int RECONNECT_DELAY = 1.0; static void remote_read_row(struct ev_io *coio, struct iobuf *iobuf, - struct iproto_header *row) + struct xrow_header *row) { struct ibuf *in = &iobuf->in; /* Read fixed header */ - if (ibuf_size(in) < IPROTO_FIXHEADER_SIZE) - coio_breadn(coio, in, IPROTO_FIXHEADER_SIZE - ibuf_size(in)); + if (ibuf_size(in) < 1) + coio_breadn(coio, in, 1); /* Read length */ if (mp_typeof(*in->pos) != MP_UINT) { tnt_raise(ClientError, ER_INVALID_MSGPACK, - "invalid fixed header"); + "packet length"); } + ssize_t to_read = mp_check_uint(in->pos, in->end); + if (to_read > 0) + coio_breadn(coio, in, to_read); uint32_t len = mp_decode_uint((const char **) &in->pos); - if (len > IPROTO_BODY_LEN_MAX) { - tnt_raise(ClientError, ER_INVALID_MSGPACK, - "received packet is too big"); - } /* Read header and body */ - ssize_t to_read = len - ibuf_size(in); + to_read = len - ibuf_size(in); if (to_read > 0) coio_breadn(coio, in, to_read); - iproto_header_decode(row, (const char **) &in->pos, in->pos + len); + xrow_header_decode(row, (const char **) &in->pos, in->pos + len); } static void -remote_write_row(struct ev_io *coio, const struct iproto_header *row) +remote_write_row(struct ev_io *coio, const struct xrow_header *row) { - struct iovec iov[IPROTO_ROW_IOVMAX]; - int iovcnt = iproto_row_encode(row, iov); + struct iovec iov[XROW_IOVMAX]; + int iovcnt = xrow_to_iovec(row, iov); coio_writev(coio, iov, iovcnt, 0); } @@ -89,25 +89,47 @@ remote_connect(struct recovery_state *r, struct ev_io *coio, { char greeting[IPROTO_GREETING_SIZE]; - evio_socket(coio, AF_INET, SOCK_STREAM, IPPROTO_TCP); - + struct remote *remote = &r->remote; struct uri *uri = &r->remote.uri; - - coio_connect(coio, &uri->addr, uri->addr_len); + /* + * coio_connect() stores resolved address to \a &remote->addr + * on success. &remote->addr_len is a value-result argument which + * must be initialized to the size of associated buffer (addrstorage) + * before calling coio_connect(). Since coio_connect() performs + * DNS resolution under the hood it is theoretically possible that + * remote->addr_len will be different even for same uri. + */ + remote->addr_len = sizeof(remote->addrstorage); + /* Prepare null-terminated strings for coio_connect() */ + char host[URI_MAXHOST] = { '\0' }; + if (uri->host) { + snprintf(host, sizeof(host), "%.*s", (int) uri->host_len, + uri->host); + } + char service[URI_MAXSERVICE]; + snprintf(service, sizeof(service), "%.*s", (int) uri->service_len, + uri->service); + coio_connect(coio, host, service, &remote->addr, &remote->addr_len); + assert(coio->fd >= 0); coio_readn(coio, greeting, sizeof(greeting)); - say_crit("connected to master"); - if (!r->remote.uri.login[0]) + say_crit("connected to %s", sio_strfaddr(&remote->addr, + remote->addr_len)); + + /* Perform authentication if user provided at least login */ + if (!r->remote.uri.login) return; /* Authenticate */ say_debug("authenticating..."); - struct iproto_header row; - iproto_encode_auth(&row, greeting, uri->login, uri->password); + struct xrow_header row; + xrow_encode_auth(&row, greeting, uri->login, + uri->login_len, uri->password, + uri->password_len); remote_write_row(coio, &row); remote_read_row(coio, iobuf, &row); if (row.type != IPROTO_OK) - iproto_decode_error(&row); /* auth failed */ + xrow_decode_error(&row); /* auth failed */ /* auth successed */ say_info("authenticated"); @@ -152,8 +174,8 @@ replica_bootstrap(struct recovery_state *r) } /* Send JOIN request */ - struct iproto_header row; - iproto_encode_join(&row, &r->server_uuid); + struct xrow_header row; + xrow_encode_join(&row, &r->server_uuid); remote_write_row(&coio, &row); /* Add a surrogate server id for snapshot rows */ @@ -170,7 +192,7 @@ replica_bootstrap(struct recovery_state *r) /* Regular snapshot row (IPROTO_INSERT) */ recovery_process(r, &row); } else /* error or unexpected packet */ { - iproto_decode_error(&row); /* rethrow error */ + xrow_decode_error(&row); /* rethrow error */ } } @@ -178,7 +200,7 @@ replica_bootstrap(struct recovery_state *r) struct vclock vclock; vclock_create(&vclock); assert(row.type == IPROTO_OK); - iproto_decode_eos(&row, &vclock); + xrow_decode_vclock(&row, &vclock); /* Replace server vclock using data from snapshot */ vclock_copy(&r->vclock, &vclock); @@ -209,7 +231,7 @@ pull_from_remote(va_list ap) for (;;) { const char *err = NULL; try { - struct iproto_header row; + struct xrow_header row; fiber_setcancellable(true); if (! evio_is_active(&coio)) { remote_set_status(&r->remote, "connecting"); @@ -219,7 +241,7 @@ pull_from_remote(va_list ap) remote_connect(r, &coio, iobuf); /* Send SUBSCRIBE request */ err = "can't subscribe to master"; - iproto_encode_subscribe(&row, &cluster_id, + xrow_encode_subscribe(&row, &cluster_id, &r->server_uuid, &r->vclock); remote_write_row(&coio, &row); r->remote.warning_said = false; @@ -228,7 +250,7 @@ pull_from_remote(va_list ap) err = "can't read row"; remote_read_row(&coio, iobuf, &row); if (!iproto_type_is_dml(row.type)) - iproto_decode_error(&row); /* error */ + xrow_decode_error(&row); /* error */ fiber_setcancellable(false); err = NULL; @@ -285,7 +307,7 @@ recovery_follow_remote(struct recovery_state *r) assert(r->remote.reader == NULL); assert(recovery_has_remote(r)); - const char *uri = uri_to_string(&r->remote.uri); + const char *uri = uri_format(&r->remote.uri); say_crit("starting replication from %s", uri); snprintf(name, sizeof(name), "replica/%s", uri); @@ -316,14 +338,12 @@ recovery_set_remote(struct recovery_state *r, const char *uri) r->remote.source[0] = '\0'; return; } - /* - * @todo: as long as DNS is involved, this may fail even - * on a valid uri. Don't panic in this case. - */ - if (uri_parse(&r->remote.uri, uri)) - panic("Can't parse uri: %s", uri); - snprintf(r->remote.source, - sizeof(r->remote.source), "%s", uri); + snprintf(r->remote.source, sizeof(r->remote.source), "%s", uri); + struct remote *remote = &r->remote; + int rc = uri_parse(&remote->uri, r->remote.source); + /* URI checked by box_check_replication_source() */ + assert(rc == 0 && remote->uri.service != NULL); + (void) rc; } bool diff --git a/src/box/replica.h b/src/box/replica.h index 0f79c512ec4720afef23d8f095bf3c56c24d8c80..08832263537206c0c8cf26bf80de1279a8cd7d16 100644 --- a/src/box/replica.h +++ b/src/box/replica.h @@ -32,15 +32,20 @@ #include "tarantool_ev.h" #include <uri.h> -enum { REMOTE_SOURCE_MAXLEN = 64 }; +enum { REMOTE_SOURCE_MAXLEN = 1024 }; /* enough to fit URI with passwords */ /** Master connection */ struct remote { - struct uri uri; struct fiber *reader; ev_tstamp recovery_lag, recovery_last_update_tstamp; bool warning_said; char source[REMOTE_SOURCE_MAXLEN]; + struct uri uri; + union { + struct sockaddr addr; + struct sockaddr_storage addrstorage; + }; + socklen_t addr_len; }; /** Connect to a master and request a snapshot. diff --git a/src/box/replication.cc b/src/box/replication.cc index 49a5aef7efaf5b117d24b2eb6386b0c10d66a742..295c1335149688d456629ef3417225588103a4ef 100644 --- a/src/box/replication.cc +++ b/src/box/replication.cc @@ -213,11 +213,11 @@ struct replication_request { /** Replication acceptor fiber handler. */ void -replication_join(int fd, struct iproto_header *header) +replication_join(int fd, struct xrow_header *packet) { - assert(header->type == IPROTO_JOIN); + assert(packet->type == IPROTO_JOIN); struct tt_uuid server_uuid = uuid_nil; - iproto_decode_join(header, &server_uuid); + xrow_decode_join(packet, &server_uuid); /* Notify box about new cluster server */ recovery->join_handler(&server_uuid); @@ -230,8 +230,8 @@ replication_join(int fd, struct iproto_header *header) } request->fd = fd; request->io.data = request; - request->data.type = header->type; - request->data.sync = header->sync; + request->data.type = packet->type; + request->data.sync = packet->sync; ev_io_init(&request->io, replication_send_socket, master_to_spawner_socket, EV_WRITE); @@ -240,13 +240,13 @@ replication_join(int fd, struct iproto_header *header) /** Replication acceptor fiber handler. */ void -replication_subscribe(int fd, struct iproto_header *packet) +replication_subscribe(int fd, struct xrow_header *packet) { struct tt_uuid uu = uuid_nil, server_uuid = uuid_nil; struct vclock vclock; vclock_create(&vclock); - iproto_decode_subscribe(packet, &uu, &server_uuid, &vclock); + xrow_decode_subscribe(packet, &uu, &server_uuid, &vclock); /** * Check that the given UUID matches the UUID of the @@ -636,7 +636,7 @@ replication_relay_recv(ev_loop * /* loop */, struct ev_io *w, int __attribute__( /** Send a single row to the client. */ static void -replication_relay_send_row(void * /* param */, struct iproto_header *packet) +replication_relay_send_row(void * /* param */, struct xrow_header *packet) { assert(iproto_type_is_dml(packet->type)); struct recovery_state *r = recovery; @@ -644,8 +644,8 @@ replication_relay_send_row(void * /* param */, struct iproto_header *packet) /* Don't duplicate data */ if (packet->server_id == 0 || packet->server_id != r->server_id) { packet->sync = relay.sync; - struct iovec iov[IPROTO_ROW_IOVMAX]; - int iovcnt = iproto_row_encode(packet, iov); + struct iovec iov[XROW_IOVMAX]; + int iovcnt = xrow_to_iovec(packet, iov); sio_writev_all(relay.sock, iov, iovcnt); } @@ -666,11 +666,11 @@ replication_relay_join(struct recovery_state *r) recover_snap(r); /* Send response to JOIN command = end of stream */ - struct iproto_header row; - iproto_encode_eos(&row, &r->vclock); + struct xrow_header row; + xrow_encode_vclock(&row, &r->vclock); row.sync = relay.sync; - struct iovec iov[IPROTO_ROW_IOVMAX]; - int iovcnt = iproto_row_encode(&row, iov); + struct iovec iov[XROW_IOVMAX]; + int iovcnt = xrow_to_iovec(&row, iov); sio_writev_all(relay.sock, iov, iovcnt); say_info("snapshot sent"); @@ -745,6 +745,8 @@ replication_relay_loop() ev_io_init(&sock_read_ev, replication_relay_recv, relay.sock, EV_READ); ev_io_start(loop(), &sock_read_ev); + /** Turn off the non-blocking mode,if any. */ + sio_setfl(relay.sock, O_NONBLOCK, 0); /* Initialize the recovery process */ recovery_init(cfg_snap_dir, cfg_wal_dir, diff --git a/src/box/replication.h b/src/box/replication.h index d6a869b9dca4a0163af76a0d996d4bfee0c9f2f1..c100196ddc43ca07e2b3b4aea6e632cca5e3eef0 100644 --- a/src/box/replication.h +++ b/src/box/replication.h @@ -40,7 +40,7 @@ void replication_prefork(const char *snap_dir, const char *wal_dir); void -replication_join(int fd, struct iproto_header *packet); +replication_join(int fd, struct xrow_header *packet); /** * Subscribe a replica to updates. @@ -48,7 +48,7 @@ replication_join(int fd, struct iproto_header *packet); * @return None. On error, closes the socket. */ void -replication_subscribe(int fd, struct iproto_header *packet); +replication_subscribe(int fd, struct xrow_header *packet); #endif // TARANTOOL_REPLICATION_H_INCLUDED diff --git a/src/box/request.cc b/src/box/request.cc index 200c6493963e161603dbeecc9566e56e822ed053..f8a19d2aa510610c5c809815a4026cfe5aef969f 100644 --- a/src/box/request.cc +++ b/src/box/request.cc @@ -155,6 +155,10 @@ execute_select(struct request *request, struct port *port) break; port_add_tuple(port, tuple); } + if (! in_txn()) { + /* no txn is created, so simply collect garbage here */ + fiber_gc(); + } } void diff --git a/src/box/request.h b/src/box/request.h index 3e06650310a91ffa8876c0cd858cf81868d9d281..e257109f65fc3b07820e2d040831cc57b7c77b8c 100644 --- a/src/box/request.h +++ b/src/box/request.h @@ -29,13 +29,12 @@ * SUCH DAMAGE. */ #include <stdbool.h> -#include "iproto_constants.h" +#include "xrow.h" struct txn; struct port; typedef void (*request_execute_f)(struct request *, struct port *); -enum { REQUEST_IOVMAX = IPROTO_PACKET_BODY_IOVMAX }; struct request { @@ -44,7 +43,7 @@ struct request * on where this packet originated from: the write ahead * log/snapshot, client request, or a Lua request. */ - struct iproto_header *header; + struct xrow_header *header; /** * Request type - IPROTO type code */ diff --git a/src/box/sophia_index.cc b/src/box/sophia_index.cc index 7e1c2811bfe2c76fa1c1e1b8a18e887d5a43f189..b50bf1c2c128acfe6a54323428d6387a01ac8bc0 100644 --- a/src/box/sophia_index.cc +++ b/src/box/sophia_index.cc @@ -32,11 +32,12 @@ #include "scoped_guard.h" #include "exception.h" #include "errinj.h" - #include "schema.h" #include "space.h" +#include "cfg.h" #include "engine_sophia.h" - +#include <sys/stat.h> +#include <sys/types.h> #include <sophia.h> #include <stdio.h> @@ -47,7 +48,11 @@ sophia_delete(void *db, struct key_def *key_def, struct tuple *tuple) const char *keyptr = key; mp_next(&keyptr); size_t keysize = keyptr - key; - int rc = sp_delete(db, key, keysize); + void *o = sp_object(db); + if (o == NULL) + tnt_raise(ClientError, ER_SOPHIA, sp_error(db)); + sp_set(o, "key", key, keysize); + int rc = sp_delete(db, o); if (rc == -1) tnt_raise(ClientError, ER_SOPHIA, sp_error(db)); } @@ -59,7 +64,12 @@ sophia_set(void *db, struct key_def *key_def, struct tuple *tuple) const char *keyptr = key; mp_next(&keyptr); size_t keysize = keyptr - key; - int rc = sp_set(db, key, keysize, tuple->data, tuple->bsize); + void *o = sp_object(db); + if (o == NULL) + tnt_raise(ClientError, ER_SOPHIA, sp_error(db)); + sp_set(o, "key", key, keysize); + sp_set(o, "value", tuple->data, tuple->bsize); + int rc = sp_set(db, o); if (rc == -1) tnt_raise(ClientError, ER_SOPHIA, sp_error(db)); } @@ -105,16 +115,19 @@ static struct tuple * sophia_gettuple(void *db, const char *key, size_t keysize, struct tuple_format *format) { - size_t valuesize = 0; - char *value = NULL; - int rc = sp_get(db, key, keysize, (void**)&value, &valuesize); - if (rc == -1) + void *o = sp_object(db); + if (o == NULL) tnt_raise(ClientError, ER_SOPHIA, sp_error(db)); - if (rc == 0) + sp_set(o, "key", key, keysize); + void *result = sp_get(db, o); + if (result == NULL) return NULL; - auto scoped_guard = make_scoped_guard([=] { free(value); }); + auto scoped_guard = + make_scoped_guard([=] { sp_destroy(result); }); + int valuesize = 0; + void *value = sp_get(result, "value", &valuesize); struct tuple *ret = - tuple_new(format, value, value + valuesize); + tuple_new(format, (char*)value, (char*)value + valuesize); tuple_ref(ret, 1); return ret; } @@ -128,13 +141,21 @@ SophiaIndex::SophiaIndex(struct key_def *key_def_arg __attribute__((unused))) SophiaFactory *factory = (SophiaFactory*)space->engine->factory; env = factory->env; - - db = sp_database(env); + db = sp_storage(env); if (db == NULL) tnt_raise(ClientError, ER_SOPHIA, sp_error(env)); + + const char *sophia_dir = cfg_gets("sophia_dir"); + mkdir(sophia_dir, 0755); + + char path[PATH_MAX]; + snprintf(path, sizeof(path), "%s/%" PRIu32, + sophia_dir, key_def->space_id); + void *c = sp_ctl(db, "conf"); - sp_set(c, "db.cmp", sophia_index_compare, key_def); - sp_set(c, "db.id", space->def.id); + sp_set(c, "storage.dir", path); + sp_set(c, "storage.cmp", sophia_index_compare, key_def); + sp_set(c, "storage.cmp_arg", key_def); int rc = sp_open(db); if (rc == -1) tnt_raise(ClientError, ER_SOPHIA, sp_error(env)); @@ -151,10 +172,35 @@ SophiaIndex::~SophiaIndex() int rc = sp_destroy(db); if (rc == -1) say_info("sophia space %d close error: %s", key_def->space_id, - sp_error(env)); + (char*)sp_error(env)); } } +struct tuple * +SophiaIndex::random(uint32_t rnd) const +{ + void *o = sp_object(db); + if (o == NULL) + tnt_raise(ClientError, ER_SOPHIA, sp_error(db)); + sp_set(o, "key", &rnd, sizeof(rnd)); + void *c = sp_cursor(db, "random", o); + if (c == NULL) + tnt_raise(ClientError, ER_SOPHIA, sp_error(db)); + auto scoped_guard = + make_scoped_guard([=] { sp_destroy(c); }); + o = sp_get(c); + if (o == NULL) + return NULL; + struct space *space = space_cache_find(key_def->space_id); + int valuesize; + void *value = sp_get(o, "value", &valuesize); + struct tuple *ret = + tuple_new(space->format, (char*)value, + (char*)value + valuesize); + tuple_ref(ret, 1); + return ret; +} + void SophiaIndex::endBuild() { @@ -163,9 +209,9 @@ SophiaIndex::endBuild() size_t SophiaIndex::size() const { - tnt_raise(ClientError, ER_UNSUPPORTED, - "SophiaIndex", "size operation"); - return 0; + void *profiler = sp_ctl(db, "profiler"); + uint64_t count = *(uint64_t*)sp_get(profiler, "count", NULL); + return count; } size_t @@ -228,11 +274,10 @@ SophiaIndex::replace(struct tuple *old_tuple, struct tuple *new_tuple, const char *keyptr = key; mp_next(&keyptr); size_t keysize = keyptr - key; - struct space *space = space_cache_find(key_def->space_id); + struct tuple *dup_tuple = sophia_gettuple(db, key, keysize, space->format); - uint32_t errcode = sophia_check_dup(key_def, old_tuple, dup_tuple, mode); if (errcode) { @@ -241,20 +286,25 @@ SophiaIndex::replace(struct tuple *old_tuple, struct tuple *new_tuple, tnt_raise(ClientError, errcode, index_id(this)); } - int rc = sp_set(db, key, keysize, new_tuple->data, new_tuple->bsize); + void *o = sp_object(db); + if (o == NULL) { + if (dup_tuple) + tuple_ref(dup_tuple, -1); + tnt_raise(ClientError, ER_SOPHIA, sp_error(db)); + } + sp_set(o, "key", key, keysize); + sp_set(o, "value", new_tuple->data, new_tuple->bsize); + int rc = sp_set(db, o); if (rc == -1) { if (dup_tuple) tuple_ref(dup_tuple, -1); tnt_raise(ClientError, ER_SOPHIA, sp_error(db)); } - if (dup_tuple) return dup_tuple; } - if (old_tuple) sophia_delete(db, key_def, old_tuple); - return old_tuple; } @@ -295,11 +345,11 @@ sophia_iterator_next(struct iterator *ptr) assert(ptr->next == sophia_iterator_next); struct sophia_iterator *it = (struct sophia_iterator *) ptr; assert(it->cursor != NULL); - int rc = sp_fetch(it->cursor); - if (rc == 0) + void *o = sp_get(it->cursor); + if (o == NULL) return NULL; - size_t valuesize = sp_valuesize(it->cursor); - const char *value = (const char*)sp_value(it->cursor); + int valuesize = 0; + const char *value = (const char*)sp_get(o, "value", &valuesize); struct tuple *ret = tuple_new(it->space->format, value, value + valuesize); tuple_ref(ret, 1); @@ -343,8 +393,6 @@ void SophiaIndex::initIterator(struct iterator *ptr, enum iterator_type type, const char *key, uint32_t part_count) const { - assert(part_count <= 1); - struct sophia_iterator *it = (struct sophia_iterator *) ptr; assert(it->cursor == NULL); @@ -364,7 +412,8 @@ SophiaIndex::initIterator(struct iterator *ptr, enum iterator_type type, it->space = space_cache_find(key_def->space_id); const char *compare; switch (type) { - case ITER_EQ: it->base.next = sophia_iterator_eq; + case ITER_EQ: + it->base.next = sophia_iterator_eq; return; case ITER_ALL: case ITER_GE: compare = ">="; @@ -379,7 +428,15 @@ SophiaIndex::initIterator(struct iterator *ptr, enum iterator_type type, tnt_raise(ClientError, ER_UNSUPPORTED, "SophiaIndex", "requested iterator type"); } - it->cursor = sp_cursor(db, compare, key, keysize); + it->base.next = sophia_iterator_next; + void *o = NULL; + if (key) { + o = sp_object(db); + if (o == NULL) + tnt_raise(ClientError, ER_SOPHIA, sp_error(db)); + sp_set(o, "key", key, keysize); + } + it->cursor = sp_cursor(db, compare, o); if (it->cursor == NULL) tnt_raise(ClientError, ER_SOPHIA, sp_error(db)); } diff --git a/src/box/sophia_index.h b/src/box/sophia_index.h index 063961d790843fd5f5c17a6977327f5b0ffc14c6..322db9d97b17a5f763f12b9b9fbbfeab746c8878 100644 --- a/src/box/sophia_index.h +++ b/src/box/sophia_index.h @@ -38,12 +38,11 @@ class SophiaIndex: public Index { virtual size_t size() const; virtual void endBuild(); - + virtual struct tuple *random(uint32_t rnd) const; virtual struct tuple *findByKey(const char *key, uint32_t part_count) const; virtual struct tuple *replace(struct tuple *old_tuple, struct tuple *new_tuple, enum dup_replace_mode mode); - virtual struct iterator *allocIterator() const; virtual void initIterator(struct iterator *iterator, enum iterator_type type, diff --git a/src/box/tuple.cc b/src/box/tuple.cc index 383304acec6c9566ef2e31e66ebb717eb5a4a030..69d2dff18976e64d295c490b30f27f2fb99023a1 100644 --- a/src/box/tuple.cc +++ b/src/box/tuple.cc @@ -45,9 +45,9 @@ static uint32_t formats_size, formats_capacity; uint32_t snapshot_version; -struct slab_arena tuple_arena; -static struct slab_cache tuple_slab_cache; -struct small_alloc talloc; +struct slab_arena memtx_arena; +struct slab_cache memtx_slab_cache; +struct small_alloc memtx_alloc; /** Extract all available type info from keys. */ void @@ -252,7 +252,7 @@ struct tuple * tuple_alloc(struct tuple_format *format, size_t size) { size_t total = sizeof(struct tuple) + size + format->field_map_size; - char *ptr = (char *) smalloc(&talloc, total, "tuple"); + char *ptr = (char *) smalloc(&memtx_alloc, total, "tuple"); struct tuple *tuple = (struct tuple *)(ptr + format->field_map_size); tuple->refs = 0; @@ -277,10 +277,10 @@ tuple_delete(struct tuple *tuple) struct tuple_format *format = tuple_format(tuple); char *ptr = (char *) tuple - format->field_map_size; tuple_format_ref(format, -1); - if (!talloc.is_delayed_free_mode || tuple->version == snapshot_version) - smfree(&talloc, ptr); + if (!memtx_alloc.is_delayed_free_mode || tuple->version == snapshot_version) + smfree(&memtx_alloc, ptr); else - smfree_delayed(&talloc, ptr); + smfree_delayed(&memtx_alloc, ptr); } /** @@ -545,14 +545,14 @@ tuple_init(float arena_prealloc, uint32_t objsize_min, flags = MAP_SHARED; } - if (slab_arena_create(&tuple_arena, prealloc, prealloc, + if (slab_arena_create(&memtx_arena, prealloc, prealloc, slab_size, flags)) { panic_syserror("failed to preallocate %zu bytes", prealloc); } - slab_cache_create(&tuple_slab_cache, &tuple_arena, + slab_cache_create(&memtx_slab_cache, &memtx_arena, slab_size); - small_alloc_create(&talloc, &tuple_slab_cache, + small_alloc_create(&memtx_alloc, &memtx_slab_cache, objsize_min, alloc_factor); } @@ -577,11 +577,11 @@ void tuple_begin_snapshot() { snapshot_version++; - small_alloc_setopt(&talloc, SMALL_DELAYED_FREE_MODE, true); + small_alloc_setopt(&memtx_alloc, SMALL_DELAYED_FREE_MODE, true); } void tuple_end_snapshot() { - small_alloc_setopt(&talloc, SMALL_DELAYED_FREE_MODE, false); + small_alloc_setopt(&memtx_alloc, SMALL_DELAYED_FREE_MODE, false); } diff --git a/src/box/tuple.h b/src/box/tuple.h index b07a3e4db7f11f3515e790424d45f67e800ecd3a..6e79795feed8fb28c8fefc539ae4fd5cf0833744 100644 --- a/src/box/tuple.h +++ b/src/box/tuple.h @@ -35,8 +35,9 @@ enum { FORMAT_ID_MAX = UINT16_MAX - 1, FORMAT_ID_NIL = UINT16_MAX }; struct tbuf; -extern struct small_alloc talloc; -extern struct slab_arena tuple_arena; +extern struct small_alloc memtx_alloc; +extern struct slab_cache memtx_slab_cache; +extern struct slab_arena memtx_arena; /** * @brief In-memory tuple format diff --git a/src/box/txn.cc b/src/box/txn.cc index 6a92204bb936576533ebe9d197236f64bd70c0ff..c350593c9d7ce40cfa64e91ff9b8e7a636d8780d 100644 --- a/src/box/txn.cc +++ b/src/box/txn.cc @@ -36,9 +36,17 @@ #include "request.h" /* for request_name */ #include "session.h" #include "port.h" +#include "iproto_constants.h" double too_long_threshold; +static inline void +fiber_set_txn(struct fiber *fiber, struct txn *txn) +{ + fiber_set_key(fiber, FIBER_KEY_TXN, (void *) txn); +} + + static void txn_add_redo(struct txn_stmt *stmt, struct request *request) { @@ -47,8 +55,8 @@ txn_add_redo(struct txn_stmt *stmt, struct request *request) return; /* Create a redo log row for Lua requests */ - struct iproto_header *row= (struct iproto_header *) - region_alloc0(&fiber()->gc, sizeof(struct iproto_header)); + struct xrow_header *row= (struct xrow_header *) + region_alloc0(&fiber()->gc, sizeof(struct xrow_header)); row->type = request->type; row->bodycnt = request_encode(request, row->body); stmt->row = row; @@ -131,7 +139,7 @@ txn_stmt_new(struct txn *txn) struct txn * txn_begin(bool autocommit) { - assert(! fiber_get_txn(fiber())); + assert(! in_txn()); struct txn *txn = (struct txn *) region_alloc0(&fiber()->gc, sizeof(*txn)); rlist_create(&txn->stmts); @@ -152,7 +160,7 @@ txn_begin(bool autocommit) struct txn * txn_begin_stmt(struct request *request) { - struct txn *txn = fiber_get_txn(fiber()); + struct txn *txn = in_txn(); if (txn == NULL) txn = txn_begin(true); struct txn_stmt *stmt = txn_stmt_new(txn); @@ -181,7 +189,7 @@ txn_commit_stmt(struct txn *txn, struct port *port) void txn_commit(struct txn *txn) { - assert(txn == fiber_get_txn(fiber())); + assert(txn == in_txn()); struct txn_stmt *stmt; /* if (!txn->autocommit && txn->n_stmts && engine_no_yield(txn->engine)) */ trigger_clear(&txn->fiber_on_yield); @@ -236,7 +244,7 @@ txn_finish(struct txn *txn) void txn_rollback_stmt() { - struct txn *txn = fiber_get_txn(fiber()); + struct txn *txn = in_txn(); if (txn == NULL) return; if (txn->autocommit) @@ -256,7 +264,7 @@ txn_rollback_stmt() void txn_rollback() { - struct txn *txn = fiber_get_txn(fiber()); + struct txn *txn = in_txn(); if (txn == NULL) return; struct txn_stmt *stmt; @@ -295,7 +303,7 @@ int boxffi_txn_begin() { try { - if (fiber_get_txn(fiber())) + if (in_txn()) tnt_raise(ClientError, ER_ACTIVE_TRANSACTION); (void) txn_begin(false); } catch (Exception *e) { @@ -308,7 +316,7 @@ int boxffi_txn_commit() { try { - struct txn *txn = fiber_get_txn(fiber()); + struct txn *txn = in_txn(); /** * COMMIT is like BEGIN or ROLLBACK * a "transaction-initiating statement". diff --git a/src/box/txn.h b/src/box/txn.h index 412a90a5b3b0dee41d7c9ca6b3bb7d1b66010b5f..8f8247c9314ffa1ab254925690d28c78ddc189cf 100644 --- a/src/box/txn.h +++ b/src/box/txn.h @@ -50,7 +50,7 @@ struct txn_stmt { struct tuple *new_tuple; /** Redo info: the binary log row */ - struct iproto_header *row; + struct xrow_header *row; }; struct txn { @@ -75,15 +75,9 @@ struct txn { /* Pointer to the current transaction (if any) */ static inline struct txn * -fiber_get_txn(struct fiber *fiber) +in_txn() { - return (struct txn *) fiber_get_key(fiber, FIBER_KEY_TXN); -} - -static inline void -fiber_set_txn(struct fiber *fiber, struct txn *txn) -{ - fiber_set_key(fiber, FIBER_KEY_TXN, (void *) txn); + return (struct txn *) fiber_get_key(fiber(), FIBER_KEY_TXN); } /** diff --git a/src/iproto_constants.cc b/src/box/xrow.cc similarity index 60% rename from src/iproto_constants.cc rename to src/box/xrow.cc index b9207d9eb92d475dc26f3b7e27f490404f809edb..1f5761d313d46ec91a71d6c5cb674026ba28bdda 100644 --- a/src/iproto_constants.cc +++ b/src/box/xrow.cc @@ -26,145 +26,21 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#include "iproto_constants.h" +#include "xrow.h" #include "msgpuck/msgpuck.h" #include "exception.h" #include "fiber.h" -#include "crc32.h" #include "tt_uuid.h" -#include "box/vclock.h" +#include "vclock.h" #include "scramble.h" #include "third_party/base64.h" - -const unsigned char iproto_key_type[IPROTO_KEY_MAX] = -{ - /* {{{ header */ - /* 0x00 */ MP_UINT, /* IPROTO_REQUEST_TYPE */ - /* 0x01 */ MP_UINT, /* IPROTO_SYNC */ - /* 0x02 */ MP_UINT, /* IPROTO_SERVER_ID */ - /* 0x03 */ MP_UINT, /* IPROTO_LSN */ - /* 0x04 */ MP_DOUBLE, /* IPROTO_TIMESTAMP */ - /* }}} */ - - /* {{{ unused */ - /* 0x05 */ MP_UINT, - /* 0x06 */ MP_UINT, - /* 0x07 */ MP_UINT, - /* 0x08 */ MP_UINT, - /* 0x09 */ MP_UINT, - /* 0x0a */ MP_UINT, - /* 0x0b */ MP_UINT, - /* 0x0c */ MP_UINT, - /* 0x0d */ MP_UINT, - /* 0x0e */ MP_UINT, - /* 0x0f */ MP_UINT, - /* }}} */ - - /* {{{ body -- integer keys */ - /* 0x10 */ MP_UINT, /* IPROTO_SPACE_ID */ - /* 0x11 */ MP_UINT, /* IPROTO_INDEX_ID */ - /* 0x12 */ MP_UINT, /* IPROTO_LIMIT */ - /* 0x13 */ MP_UINT, /* IPROTO_OFFSET */ - /* 0x14 */ MP_UINT, /* IPROTO_ITERATOR */ - /* }}} */ - - /* {{{ unused */ - /* 0x15 */ MP_UINT, - /* 0x16 */ MP_UINT, - /* 0x17 */ MP_UINT, - /* 0x18 */ MP_UINT, - /* 0x19 */ MP_UINT, - /* 0x1a */ MP_UINT, - /* 0x1b */ MP_UINT, - /* 0x1c */ MP_UINT, - /* 0x1d */ MP_UINT, - /* 0x1e */ MP_UINT, - /* 0x1f */ MP_UINT, - /* }}} */ - - /* {{{ body -- all keys */ - /* 0x20 */ MP_ARRAY, /* IPROTO_KEY */ - /* 0x21 */ MP_ARRAY, /* IPROTO_TUPLE */ - /* 0x22 */ MP_STR, /* IPROTO_FUNCTION_NAME */ - /* 0x23 */ MP_STR, /* IPROTO_USER_NAME */ - /* 0x24 */ MP_STR, /* IPROTO_SERVER_UUID */ - /* 0x25 */ MP_STR, /* IPROTO_CLUSTER_UUID */ - /* 0x26 */ MP_MAP, /* IPROTO_VCLOCK */ - /* }}} */ -}; - -const char *iproto_type_strs[] = -{ - NULL, - "SELECT", - "INSERT", - "REPLACE", - "UPDATE", - "DELETE", - "CALL", - "AUTH" -}; - -#define bit(c) (1ULL<<IPROTO_##c) -const uint64_t iproto_body_key_map[IPROTO_TYPE_DML_MAX] = { - 0, /* unused */ - bit(SPACE_ID) | bit(LIMIT) | bit(KEY), /* SELECT */ - bit(SPACE_ID) | bit(TUPLE), /* INSERT */ - bit(SPACE_ID) | bit(TUPLE), /* REPLACE */ - bit(SPACE_ID) | bit(KEY) | bit(TUPLE), /* UPDATE */ - bit(SPACE_ID) | bit(KEY), /* DELETE */ - bit(FUNCTION_NAME) | bit(TUPLE), /* CALL */ - bit(USER_NAME) | bit(TUPLE) /* AUTH */ -}; -#undef bit - -const char *iproto_key_strs[IPROTO_KEY_MAX] = { - "type", /* 0x00 */ - "sync", /* 0x01 */ - "server_id", /* 0x02 */ - "lsn", /* 0x03 */ - "timestamp", /* 0x04 */ - "", /* 0x05 */ - "", /* 0x06 */ - "", /* 0x07 */ - "", /* 0x08 */ - "", /* 0x09 */ - "", /* 0x0a */ - "", /* 0x0b */ - "", /* 0x0c */ - "", /* 0x0d */ - "", /* 0x0e */ - "", /* 0x0f */ - "space_id", /* 0x10 */ - "index_id", /* 0x11 */ - "limit", /* 0x12 */ - "offset", /* 0x13 */ - "iterator", /* 0x14 */ - "", /* 0x15 */ - "", /* 0x16 */ - "", /* 0x17 */ - "", /* 0x18 */ - "", /* 0x19 */ - "", /* 0x1a */ - "", /* 0x1b */ - "", /* 0x1c */ - "", /* 0x1d */ - "", /* 0x1e */ - "", /* 0x1f */ - "key", /* 0x20 */ - "tuple", /* 0x21 */ - "function name", /* 0x22 */ - "user name", /* 0x23 */ - "server UUID" /* 0x24 */ - "cluster UUID" /* 0x25 */ - "vector clock" /* 0x26 */ -}; +#include "iproto_constants.h" void -iproto_header_decode(struct iproto_header *header, const char **pos, - const char *end) +xrow_header_decode(struct xrow_header *header, const char **pos, + const char *end) { - memset(header, 0, sizeof(struct iproto_header)); + memset(header, 0, sizeof(struct xrow_header)); const char *pos2 = *pos; if (mp_check(&pos2, end) != 0) { error: @@ -215,7 +91,7 @@ iproto_header_decode(struct iproto_header *header, const char **pos, * @pre pos points at a valid msgpack */ void -iproto_decode_uuid(const char **pos, struct tt_uuid *out) +xrow_decode_uuid(const char **pos, struct tt_uuid *out) { if (mp_typeof(**pos) != MP_STR) error: @@ -228,7 +104,7 @@ iproto_decode_uuid(const char **pos, struct tt_uuid *out) } int -iproto_header_encode(const struct iproto_header *header, struct iovec *out) +xrow_header_encode(const struct xrow_header *header, struct iovec *out) { enum { HEADER_LEN_MAX = 40 }; @@ -275,69 +151,66 @@ iproto_header_encode(const struct iproto_header *header, struct iovec *out) out++; memcpy(out, header->body, sizeof(*out) * header->bodycnt); - assert(1 + header->bodycnt <= IPROTO_PACKET_IOVMAX); + assert(1 + header->bodycnt <= XROW_IOVMAX); return 1 + header->bodycnt; /* new iovcnt */ } char * -iproto_encode_uuid(char *pos, const struct tt_uuid *in) +xrow_encode_uuid(char *pos, const struct tt_uuid *in) { return mp_encode_str(pos, tt_uuid_str(in), UUID_STR_LEN); } int -iproto_row_encode(const struct iproto_header *row, - struct iovec *out) +xrow_to_iovec(const struct xrow_header *row, + struct iovec *out) { - int iovcnt = iproto_header_encode(row, out + 1) + 1; - char *fixheader = (char *) - region_alloc(&fiber()->gc, IPROTO_FIXHEADER_SIZE); + static const int iov0_len = mp_sizeof_uint(UINT32_MAX); + int iovcnt = xrow_header_encode(row, out + 1) + 1; + char *fixheader = (char *) region_alloc(&fiber()->gc, iov0_len); uint32_t len = 0; for (int i = 1; i < iovcnt; i++) len += out[i].iov_len; /* Encode length */ - assert(IPROTO_FIXHEADER_SIZE == mp_sizeof_uint(UINT32_MAX)); char *data = fixheader; *(data++) = 0xce; /* MP_UINT32 */ *(uint32_t *) data = mp_bswap_u32(len); - data += sizeof(uint32_t); - assert(data == fixheader + IPROTO_FIXHEADER_SIZE); out[0].iov_base = fixheader; - out[0].iov_len = IPROTO_FIXHEADER_SIZE; + out[0].iov_len = iov0_len; - assert(iovcnt <= IPROTO_ROW_IOVMAX); + assert(iovcnt <= XROW_IOVMAX); return iovcnt; } void -iproto_encode_auth(struct iproto_header *packet, const char *greeting, - const char *login, const char *password) +xrow_encode_auth(struct xrow_header *packet, const char *greeting, + const char *login, size_t login_len, + const char *password, size_t password_len) { + assert(login != NULL); memset(packet, 0, sizeof(*packet)); - uint32_t login_len = strlen(login); - uint32_t password_len = strlen(password); - enum { PACKET_LEN_MAX = 128 }; size_t buf_size = PACKET_LEN_MAX + login_len + SCRAMBLE_SIZE; char *buf = (char *) region_alloc(&fiber()->gc, buf_size); - char salt[SCRAMBLE_SIZE]; - char scramble[SCRAMBLE_SIZE]; - if (base64_decode(greeting + 64, SCRAMBLE_BASE64_SIZE, salt, - SCRAMBLE_SIZE) != SCRAMBLE_SIZE) - panic("invalid salt: %64s", greeting + 64); - scramble_prepare(scramble, salt, password, password_len); - char *d = buf; - d = mp_encode_map(d, 2); + d = mp_encode_map(d, password != NULL ? 2 : 1); d = mp_encode_uint(d, IPROTO_USER_NAME); d = mp_encode_str(d, login, login_len); - d = mp_encode_uint(d, IPROTO_TUPLE); - d = mp_encode_array(d, 2); - d = mp_encode_str(d, "chap-sha1", strlen("chap-sha1")); - d = mp_encode_str(d, scramble, SCRAMBLE_SIZE); + if (password != NULL) { /* password can be omitted */ + char salt[SCRAMBLE_SIZE]; + char scramble[SCRAMBLE_SIZE]; + if (base64_decode(greeting + 64, SCRAMBLE_BASE64_SIZE, salt, + SCRAMBLE_SIZE) != SCRAMBLE_SIZE) + panic("invalid salt: %64s", greeting + 64); + scramble_prepare(scramble, salt, password, password_len); + d = mp_encode_uint(d, IPROTO_TUPLE); + d = mp_encode_array(d, 2); + d = mp_encode_str(d, "chap-sha1", strlen("chap-sha1")); + d = mp_encode_str(d, scramble, SCRAMBLE_SIZE); + } assert(d <= buf + buf_size); packet->body[0].iov_base = buf; @@ -347,7 +220,7 @@ iproto_encode_auth(struct iproto_header *packet, const char *greeting, } void -iproto_decode_error(struct iproto_header *row) +xrow_decode_error(struct xrow_header *row) { uint32_t code = row->type & (IPROTO_TYPE_ERROR - 1); @@ -387,10 +260,10 @@ iproto_decode_error(struct iproto_header *row) } void -iproto_encode_subscribe(struct iproto_header *row, - const struct tt_uuid *cluster_uuid, - const struct tt_uuid *server_uuid, - const struct vclock *vclock) +xrow_encode_subscribe(struct xrow_header *row, + const struct tt_uuid *cluster_uuid, + const struct tt_uuid *server_uuid, + const struct vclock *vclock) { memset(row, 0, sizeof(*row)); uint32_t cluster_size = vclock_size(vclock); @@ -400,9 +273,9 @@ iproto_encode_subscribe(struct iproto_header *row, char *data = buf; data = mp_encode_map(data, 3); data = mp_encode_uint(data, IPROTO_CLUSTER_UUID); - data = iproto_encode_uuid(data, cluster_uuid); + data = xrow_encode_uuid(data, cluster_uuid); data = mp_encode_uint(data, IPROTO_SERVER_UUID); - data = iproto_encode_uuid(data, server_uuid); + data = xrow_encode_uuid(data, server_uuid); data = mp_encode_uint(data, IPROTO_VCLOCK); data = mp_encode_map(data, cluster_size); vclock_foreach(vclock, server) { @@ -417,7 +290,7 @@ iproto_encode_subscribe(struct iproto_header *row, } void -iproto_decode_subscribe(struct iproto_header *row, struct tt_uuid *cluster_uuid, +xrow_decode_subscribe(struct xrow_header *row, struct tt_uuid *cluster_uuid, struct tt_uuid *server_uuid, struct vclock *vclock) { if (row->bodycnt == 0) @@ -443,12 +316,12 @@ iproto_decode_subscribe(struct iproto_header *row, struct tt_uuid *cluster_uuid, case IPROTO_CLUSTER_UUID: if (cluster_uuid == NULL) goto skip; - iproto_decode_uuid(&d, cluster_uuid); + xrow_decode_uuid(&d, cluster_uuid); break; case IPROTO_SERVER_UUID: if (server_uuid == NULL) goto skip; - iproto_decode_uuid(&d, server_uuid); + xrow_decode_uuid(&d, server_uuid); break; case IPROTO_VCLOCK: if (vclock == NULL) @@ -485,7 +358,7 @@ iproto_decode_subscribe(struct iproto_header *row, struct tt_uuid *cluster_uuid, } void -iproto_encode_join(struct iproto_header *row, const struct tt_uuid *server_uuid) +xrow_encode_join(struct xrow_header *row, const struct tt_uuid *server_uuid) { memset(row, 0, sizeof(*row)); @@ -495,7 +368,7 @@ iproto_encode_join(struct iproto_header *row, const struct tt_uuid *server_uuid) data = mp_encode_map(data, 1); data = mp_encode_uint(data, IPROTO_SERVER_UUID); /* Greet the remote server with our server UUID */ - data = iproto_encode_uuid(data, server_uuid); + data = xrow_encode_uuid(data, server_uuid); assert(data <= buf + size); row->body[0].iov_base = buf; @@ -505,7 +378,7 @@ iproto_encode_join(struct iproto_header *row, const struct tt_uuid *server_uuid) } void -iproto_encode_eos(struct iproto_header *row, const struct vclock *vclock) +xrow_encode_vclock(struct xrow_header *row, const struct vclock *vclock) { memset(row, 0, sizeof(*row)); diff --git a/src/box/xrow.h b/src/box/xrow.h new file mode 100644 index 0000000000000000000000000000000000000000..9cf1327779c3f39ba2964b68510cb2fe98d3ab0d --- /dev/null +++ b/src/box/xrow.h @@ -0,0 +1,161 @@ +#ifndef TARANTOOL_XROW_H_INCLUDED +#define TARANTOOL_XROW_H_INCLUDED +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <stdint.h> +#include <stddef.h> +#include <sys/uio.h> /* struct iovec */ + +#if defined(__cplusplus) +extern "C" { +#endif + +enum { + XROW_HEADER_IOVMAX = 1, + XROW_BODY_IOVMAX = 2, + XROW_IOVMAX = XROW_HEADER_IOVMAX + XROW_BODY_IOVMAX + 1 +}; + +struct xrow_header { + uint32_t type; + uint32_t server_id; + uint64_t sync; + uint64_t lsn; + double tm; + + int bodycnt; + struct iovec body[XROW_BODY_IOVMAX]; +}; + +void +xrow_header_decode(struct xrow_header *header, + const char **pos, const char *end); +struct tt_uuid; + +void +xrow_decode_uuid(const char **pos, struct tt_uuid *out); + +char * +xrow_encode_uuid(char *pos, const struct tt_uuid *in); + +int +xrow_header_encode(const struct xrow_header *header, + struct iovec *out); + +int +xrow_to_iovec(const struct xrow_header *row, struct iovec *out); + +/** + * \brief Decode ERROR and re-throw it as ClientError exception + * \param row +*/ +void +xrow_decode_error(struct xrow_header *row); + +/** + * \brief Encode AUTH command + * \param[out] row + * \param greeting - IPROTO greeting + * \param login - user login + * \param login_len - length of \a login + * \param password - user password + * \param password_len - length of \a password +*/ +void +xrow_encode_auth(struct xrow_header *row, const char *greeting, + const char *login, size_t login_len, + const char *password, size_t password_len); + +/** + * \brief Encode SUBSCRIBE command + * \param row[out] + * \param cluster_uuid cluster uuid + * \param server_uuid server uuid + * \param vclock server vclock +*/ +void +xrow_encode_subscribe(struct xrow_header *row, + const struct tt_uuid *cluster_uuid, + const struct tt_uuid *server_uuid, + const struct vclock *vclock); + +/** + * \brief Decode SUBSCRIBE command + * \param row + * \param[out] cluster_uuid + * \param[out] server_uuid + * \param[out] vclock +*/ +void +xrow_decode_subscribe(struct xrow_header *row, struct tt_uuid *cluster_uuid, + struct tt_uuid *server_uuid, struct vclock *vclock); + +/** + * \brief Encode JOIN command + * \param[out] row + * \param server_uuid +*/ +void +xrow_encode_join(struct xrow_header *row, const struct tt_uuid *server_uuid); + +/** + * \brief Decode JOIN command + * \param row + * \param[out] server_uuid +*/ +static inline void +xrow_decode_join(struct xrow_header *row, struct tt_uuid *server_uuid) +{ + return xrow_decode_subscribe(row, NULL, server_uuid, NULL); +} + +/** + * \brief Encode end of stream command (a response to JOIN command) + * \param row[out] + * \param vclock +*/ +void +xrow_encode_vclock(struct xrow_header *row, const struct vclock *vclock); + +/** + * \brief Decode end of stream command (a response to JOIN command) + * \param row + * \param[out] vclock +*/ +static inline void +xrow_decode_vclock(struct xrow_header *row, struct vclock *vclock) +{ + return xrow_decode_subscribe(row, NULL, NULL, vclock); +} + +#if defined(__cplusplus) +} /* extern "C" */ +#endif + +#endif /* TARANTOOL_XROW_H_INCLUDED */ diff --git a/src/coeio.cc b/src/coeio.cc index 223b5223c51fbb3447d9db60a21f4899092d9351..d9de772fac2ce61efb094e3947f3ef8241e1df04 100644 --- a/src/coeio.cc +++ b/src/coeio.cc @@ -42,7 +42,7 @@ * manner, when libeio is ready to process some requests it * calls coeio_poller callback. * - * Due to libeio design, want_pall callback is called while + * Due to libeio design, want_poll callback is called while * locks are being held, so it's not possible to call any libeio * function inside this callback. Thus coeio_want_poll raises an * async event which will be dealt with normally as part of the @@ -107,6 +107,15 @@ coeio_init(void) ev_async_start(loop(), &coeio_manager.coeio_async); } +/** + * ReInit coeio subsystem (for example after 'fork') + */ +void +coeio_reinit(void) +{ + eio_init(coeio_want_poll_cb, NULL); +} + /** * A single task context. */ @@ -260,8 +269,9 @@ coeio_resolve(int socktype, const char *host, const char *port, hints.ai_protocol = 0; /* do resolving */ errno = 0; - if (coeio_custom(getaddrinfo_cb, timeout, host, port, - &hints, &result)) + /* make no difference between empty string and NULL for host */ + if (coeio_custom(getaddrinfo_cb, timeout, (host && *host) ? host : NULL, + port, &hints, &result)) return NULL; return result; } diff --git a/src/coeio.h b/src/coeio.h index e0fdc8885db464f153e1f3454d1c1d616f1a6b05..6536063c5560f2201600f96576b025de69ed76bd 100644 --- a/src/coeio.h +++ b/src/coeio.h @@ -57,6 +57,7 @@ extern "C" { */ void coeio_init(void); +void coeio_reinit(void); ssize_t coeio_custom(ssize_t (*f)(va_list ap), ev_tstamp timeout, ...); struct addrinfo * diff --git a/src/coio.cc b/src/coio.cc index e5cbe14e58fbb156c50e8f101baf8499f124d405..e3d92a0d7f7856c64c28a1f692eed6e99e7e712e 100644 --- a/src/coio.cc +++ b/src/coio.cc @@ -28,12 +28,15 @@ */ #include "coio.h" +#include <sys/socket.h> +#include <sys/un.h> #include <netinet/tcp.h> #include <stdio.h> #include "iobuf.h" #include "sio.h" #include "scoped_guard.h" +#include "coeio.h" /* coeio_resolve() */ struct CoioGuard { struct ev_io *ev_io; @@ -78,28 +81,23 @@ coio_fiber_yield_timeout(struct ev_io *coio, ev_tstamp delay) return is_timedout; } -/** - * Connect to a host. - */ -void -coio_connect(struct ev_io *coio, struct sockaddr *addr, socklen_t addr_len) -{ - coio_connect_timeout(coio, addr, addr_len, TIMEOUT_INFINITY); -} - /** * Connect to a host with a specified timeout. - * @retval true timeout - * @retval false connected + * @retval -1 timeout + * @retval 0 connected */ -bool -coio_connect_timeout(struct ev_io *coio, struct sockaddr *addr, - socklen_t len, ev_tstamp timeout) +static int +coio_connect_addr(struct ev_io *coio, struct sockaddr *addr, + socklen_t len, ev_tstamp timeout) { - if (sio_connect(coio->fd, addr, len) == 0) - return false; - assert(errno == EINPROGRESS); ev_loop *loop = loop(); + evio_socket(coio, addr->sa_family, SOCK_STREAM, 0); + auto coio_guard = make_scoped_guard([=]{ evio_close(loop, coio); }); + if (sio_connect(coio->fd, addr, len) == 0) { + coio_guard.is_active = false; + return 0; + } + assert(errno == EINPROGRESS); /* * Wait until socket is ready for writing or * timed out. @@ -111,7 +109,7 @@ coio_connect_timeout(struct ev_io *coio, struct sockaddr *addr, fiber_testcancel(); if (is_timedout) { errno = ETIMEDOUT; - return true; + return -1; } int error = EINPROGRESS; socklen_t sz = sizeof(error); @@ -121,50 +119,87 @@ coio_connect_timeout(struct ev_io *coio, struct sockaddr *addr, errno = error; tnt_raise(SocketError, coio->fd, "connect"); } - return false; + coio_guard.is_active = false; + return 0; } /** - * Connect to a first address in addrinfo list and initialize coio - * with connected socket. + * Resolve hostname:service from \a uri and connect to the first available + * address with a specified timeout. * - * If coio is already initialized, socket family, - * type and protocol must match the remote address. + * If \a addr is not NULL the function provides resolved address on success. + * In this case, \a addr_len is a value-result argument. It should be + * initialized to the size of the buffer associated with \a addr. Upon return, + * \a addr_len is updated to contain the actual size of the source address. + * The returned address is truncated if the buffer provided is too small; + * in this case, addrlen will return a value greater than was supplied to the + * call. * - * @retval true timeout - * @retval false sucess + * This function also supports UNIX domain sockets if uri->path is not NULL and + * uri->service is NULL. + * + * @retval -1 timeout + * @retval 0 connected */ -bool -coio_connect_addrinfo(struct ev_io *coio, struct addrinfo *ai, - ev_tstamp timeout) +int +coio_connect_timeout(struct ev_io *coio, const char *host, const char *service, + struct sockaddr *addr, socklen_t *addr_len, + ev_tstamp timeout) { + /* try to resolve a hostname */ + struct ev_loop *loop = loop(); ev_tstamp start, delay; - ev_loop *loop = loop(); + evio_timeout_init(loop, &start, &delay, timeout); + + assert(service != NULL); + if (strcmp(host, URI_HOST_UNIX) == 0) { + /* UNIX socket */ + struct sockaddr_un un; + snprintf(un.sun_path, sizeof(un.sun_path), "%s", service); + un.sun_family = AF_UNIX; + if (coio_connect_addr(coio, (struct sockaddr *) &un, sizeof(un), + delay) != 0) + return -1; + if (addr != NULL) { + assert(addr_len != NULL); + *addr_len = MIN(sizeof(un), *addr_len); + memcpy(addr, &un, *addr_len); + } + return 0; + } + + struct addrinfo *ai = coeio_resolve(SOCK_STREAM, host, service, delay); + if (ai == NULL) + return -1; /* timeout */ + + auto addrinfo_guard = make_scoped_guard([=]{ freeaddrinfo(ai); }); + evio_timeout_update(loop(), start, &delay); + coio_timeout_init(&start, &delay, timeout); assert(! evio_is_active(coio)); - bool res = true; while (ai) { try { - evio_socket(coio, ai->ai_family, - ai->ai_socktype, - ai->ai_protocol); - res = coio_connect_timeout(coio, ai->ai_addr, - ai->ai_addrlen, delay); - if (res) - evio_close(loop, coio); - return res; + if (coio_connect_addr(coio, ai->ai_addr, + ai->ai_addrlen, delay)) + return -1; + if (addr != NULL) { + assert(addr_len != NULL); + *addr_len = MIN(ai->ai_addrlen, *addr_len); + memcpy(addr, ai->ai_addr, *addr_len); + } + return 0; /* connected */ } catch (SocketError *e) { - if (res) - evio_close(loop, coio); - if (ai->ai_next == NULL) - throw; - ev_now_update(loop); - coio_timeout_update(start, &delay); + /* ignore */ + say_error("failed to connect to %s: %s", + sio_strfaddr(ai->ai_addr, ai->ai_addrlen), + e->errmsg()); } ai = ai->ai_next; + ev_now_update(loop); + coio_timeout_update(start, &delay); } - /* unreachable. */ - tnt_raise(SocketError, coio->fd, "connect_addrinfo()"); + + tnt_raise(SocketError, coio->fd, "connection failed"); } /** diff --git a/src/coio.h b/src/coio.h index 35d030e769942bce1d9fd13fcc3a2660dc1c95c1..876778a44cc54e321f6ae5e9210ac7acafe993d7 100644 --- a/src/coio.h +++ b/src/coio.h @@ -44,16 +44,18 @@ struct coio_service void *handler_param; }; -void -coio_connect(struct ev_io *coio, struct sockaddr *addr, socklen_t addr_len); - -bool -coio_connect_timeout(struct ev_io *coio, struct sockaddr *addr, - socklen_t len, ev_tstamp timeout); +int +coio_connect_timeout(struct ev_io *coio, const char *host, const char *service, + struct sockaddr *addr, socklen_t *addr_len, + ev_tstamp timeout); -bool -coio_connect_addrinfo(struct ev_io *coio, struct addrinfo *ai, - ev_tstamp timeout); +static inline int +coio_connect(struct ev_io *coio, const char *host, const char *service, + struct sockaddr *addr, socklen_t *addr_len) +{ + return coio_connect_timeout(coio, host, service, addr, addr_len, + TIMEOUT_INFINITY); +} void coio_bind(struct ev_io *coio, struct sockaddr *addr, diff --git a/src/errcode.h b/src/errcode.h index 26cbd753527d5ea92dca2abe0a4f2fc3edeeb6c2..355699e767524a0d84ae40f2ae13bb323151764f 100644 --- a/src/errcode.h +++ b/src/errcode.h @@ -56,7 +56,7 @@ enum { TNT_ERRMSG_MAX = 512 }; /* 4 */_(ER_TUPLE_NOT_FOUND, 2, "Tuple doesn't exist in index %u") \ /* 5 */_(ER_UNSUPPORTED, 2, "%s does not support %s") \ /* 6 */_(ER_NONMASTER, 2, "Can't modify data on a replication slave. My master is: %s") \ - /* 7 */_(ER_SECONDARY, 2, "Can't modify data upon a request on the secondary port.") \ + /* 7 */_(ER_READONLY, 2, "Can't modify data because this server in read-only mode.") \ /* 8 */_(ER_INJECTION, 2, "Error injection '%s'") \ /* 9 */_(ER_CREATE_SPACE, 2, "Failed to create space %u: %s") \ /* 10 */_(ER_SPACE_EXISTS, 2, "Space '%s' already exists") \ @@ -134,6 +134,7 @@ enum { TNT_ERRMSG_MAX = 512 }; /* 82 */_(ER_NO_SUCH_ROLE, 2, "Role '%s' is not found") \ /* 83 */_(ER_ROLE_EXISTS, 2, "Role '%s' already exists") \ /* 84 */_(ER_CREATE_ROLE, 2, "Failed to create role '%s': %s") \ + /* 85 */_(ER_INDEX_EXISTS, 2, "Index '%s' already exists") \ /* * !IMPORTANT! Please follow instructions at start of the file diff --git a/src/evio.cc b/src/evio.cc index 2d4f8249aa6c72d4ba69421c20941cc6639f0ba4..75b721161c3f8d30fa18ec00cd17ec46856bde07 100644 --- a/src/evio.cc +++ b/src/evio.cc @@ -30,37 +30,14 @@ #include "uri.h" #include "scoped_guard.h" #include <stdio.h> +#include <sys/socket.h> +#include <sys/un.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <arpa/inet.h> #define BIND_RETRY_DELAY 0.1 -/** - * Try to convert IPv4 or IPv6 addresses from text to binary form. - * sa buf must be sizeo of sizeof(sockaddr_in6). - */ -int -evio_pton(const char *addr, const char *port, struct sockaddr_storage *sa, socklen_t *salen) { - struct sockaddr_in *v4 = (struct sockaddr_in*)sa; - int rc = inet_pton(AF_INET, addr, &v4->sin_addr); - if (rc) { - v4->sin_family = AF_INET; - v4->sin_port = htons(atoi(port)); - *salen = sizeof(struct sockaddr_in); - return AF_INET; - } - struct sockaddr_in6 *v6 = (struct sockaddr_in6*)sa; - rc = inet_pton(AF_INET6, addr, &v6->sin6_addr); - if (rc) { - v6->sin6_family = AF_INET6; - v6->sin6_port = htons(atoi(port)); - *salen = sizeof(struct sockaddr_in6); - return AF_INET6; - } - return -1; -} - /** Note: this function does not throw. */ void evio_close(ev_loop *loop, struct ev_io *evio) @@ -133,37 +110,6 @@ evio_setsockopt_tcpserver(int fd) &linger, sizeof(linger)); } -/** - * Bind to a first address in addrinfo list and initialize coio - * with bound socket. - */ -void -evio_bind_addrinfo(struct ev_io *evio, struct addrinfo *ai) -{ - assert(! evio_is_active(evio)); - int fd = -1; - while (ai) { - try { - fd = sio_socket(ai->ai_family, ai->ai_socktype, - ai->ai_protocol); - evio_setsockopt_tcpserver(fd); - if (sio_bind(fd, ai->ai_addr, ai->ai_addrlen) == 0) { - evio->fd = fd; - return; /* success. */ - } - assert(errno == EADDRINUSE); - } catch (SocketError *e) { - if (ai->ai_next == NULL) { - close(fd); - throw; - } - } - close(fd); - ai = ai->ai_next; - } - tnt_raise(SocketError, evio->fd, "evio_bind_addrinfo()"); -} - static inline const char * evio_service_name(struct evio_service *service) { @@ -191,7 +137,7 @@ evio_service_accept_cb(ev_loop * /* loop */, ev_io *watcher, if (fd < 0) /* EAGAIN, EWOULDLOCK, EINTR */ return; /* set common tcp options */ - evio_setsockopt_tcp(fd, service->port.addr.sa_family); + evio_setsockopt_tcp(fd, service->addr.sa_family); /* * Invoke the callback and pass it the accepted * socket. @@ -212,23 +158,25 @@ evio_service_accept_cb(ev_loop * /* loop */, ev_io *watcher, * needs to retry binding. */ static int -evio_service_bind_and_listen(struct evio_service *service) +evio_service_bind_addr(struct evio_service *service) { + say_debug("%s: binding to %s...", evio_service_name(service), + sio_strfaddr(&service->addr, service->addr_len)); /* Create a socket. */ - int fd = sio_socket(service->port.addr.sa_family, + int fd = sio_socket(service->addr.sa_family, SOCK_STREAM, IPPROTO_TCP); try { evio_setsockopt_tcpserver(fd); - if (sio_bind(fd, &service->port.addr, - service->port.addr_len) || sio_listen(fd)) { + if (sio_bind(fd, &service->addr, service->addr_len) || + sio_listen(fd)) { assert(errno == EADDRINUSE); close(fd); return -1; } - say_info("bound to %s port %s", evio_service_name(service), - uri_to_string(&service->port)); + say_info("%s: bound to %s", evio_service_name(service), + sio_strfaddr(&service->addr, service->addr_len)); /* Invoke on_bind callback if it is set. */ if (service->on_bind) @@ -244,6 +192,50 @@ evio_service_bind_and_listen(struct evio_service *service) return 0; } +static int +evio_service_bind_and_listen(struct evio_service *service) +{ + if (strcmp(service->host, URI_HOST_UNIX) == 0) { + /* UNIX domain socket */ + struct sockaddr_un *un = (struct sockaddr_un *) &service->addr; + service->addr_len = sizeof(*un); + snprintf(un->sun_path, sizeof(un->sun_path), "%s", + service->serv); + un->sun_family = AF_UNIX; + return evio_service_bind_addr(service); + } + + /* IP socket */ + struct addrinfo hints, *res; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + + /* make no difference between empty string and NULL for host */ + if (getaddrinfo(*service->host ? service->host : NULL, service->serv, + &hints, &res) != 0 || res == NULL) + tnt_raise(SocketError, -1, "can't resolve uri for bind"); + auto addrinfo_guard = make_scoped_guard([=]{ freeaddrinfo(res); }); + + for (struct addrinfo *ai = res; ai != NULL; ai = ai->ai_next) { + memcpy(&service->addr, ai->ai_addr, ai->ai_addrlen); + service->addr_len = ai->ai_addrlen; + try { + return evio_service_bind_addr(service); + } catch (SocketError *e) { + say_error("%s: failed to bind on %s: %s", + evio_service_name(service), + sio_strfaddr(ai->ai_addr, ai->ai_addrlen), + e->errmsg()); + /* ignore */ + } + } + + tnt_raise(SocketError, -1, "%s: failed to bind", + evio_service_name(service)); +} + /** A callback invoked by libev when sleep timer expires. * * Retry binding. On success, stop the timer. If the port @@ -272,10 +264,16 @@ evio_service_init(ev_loop *loop, service->loop = loop; + struct uri u; + if (uri_parse(&u, uri) || u.service == NULL) + tnt_raise(IllegalParams, "invalid uri for bind: %s", uri); - if (uri_parse(&service->port, uri)) - tnt_raise(SocketError, -1, - "invalid address for bind: %s", uri); + snprintf(service->serv, sizeof(service->serv), "%.*s", + (int) u.service_len, u.service); + if (u.host != NULL && strncmp(u.host, "*", u.host_len) != 0) { + snprintf(service->host, sizeof(service->host), "%.*s", + (int) u.host_len, u.host); + } /* else { service->host[0] = '\0'; } */ service->on_accept = on_accept; service->on_accept_param = on_accept_param; @@ -300,10 +298,11 @@ evio_service_start(struct evio_service *service) if (evio_service_bind_and_listen(service)) { /* Try again after a delay. */ - say_warn("%s port %s is already in use, will " + say_warn("%s: %s is already in use, will " "retry binding after %lf seconds.", evio_service_name(service), - uri_to_string(&service->port), BIND_RETRY_DELAY); + sio_strfaddr(&service->addr, service->addr_len), + BIND_RETRY_DELAY); ev_timer_set(&service->timer, BIND_RETRY_DELAY, BIND_RETRY_DELAY); @@ -320,8 +319,8 @@ evio_service_stop(struct evio_service *service) } else { ev_io_stop(service->loop, &service->ev); close(service->ev.fd); - if (service->port.addr.sa_family == AF_UNIX) { - unlink(service->port.un.sun_path); + if (service->addr.sa_family == AF_UNIX) { + unlink(((struct sockaddr_un *) &service->addr)->sun_path); } } } diff --git a/src/evio.h b/src/evio.h index e2f0d44733f7839143c72c62a31cc5f8370b074b..e05c017556f487fc0a6e979311fda288f495c2a0 100644 --- a/src/evio.h +++ b/src/evio.h @@ -63,11 +63,16 @@ struct evio_service { /** Service name. E.g. 'primary', 'secondary', etc. */ char name[SERVICE_NAME_MAXLEN]; - /** Bind IP address, useful for logging */ - char host[SERVICE_NAME_MAXLEN]; + /** Bind host:service, useful for logging */ + char host[URI_MAXHOST]; + char serv[URI_MAXSERVICE]; /** Interface/port to bind to */ - struct uri port; + union { + struct sockaddr addr; + struct sockaddr_storage addrstorage; + }; + socklen_t addr_len; /** A callback invoked upon a successful bind, optional. * If on_bind callback throws an exception, it's @@ -152,10 +157,4 @@ evio_setsockopt_tcp(int fd, int family); void evio_setsockopt_tcpserver(int fd); -void -evio_bind_addrinfo(struct ev_io *coio, struct addrinfo *ai); - -int -evio_pton(const char *addr, const char *port, struct sockaddr_storage *sa, socklen_t *salen); - #endif /* TARANTOOL_EVIO_H_INCLUDED */ diff --git a/src/ffisyms.cc b/src/ffisyms.cc index c37248260ba6bc719dcfbef1c7d14a35fdb4ad09..725dddb914adbb39748ffd775e5b3541d3687160 100644 --- a/src/ffisyms.cc +++ b/src/ffisyms.cc @@ -4,6 +4,7 @@ #include <box/box.h> #include <box/tuple.h> #include <box/lua/index.h> +#include <box/lua/tuple.h> #include <box/lua/call.h> #include <lua/init.h> #include <tarantool.h> @@ -30,6 +31,7 @@ void *ffi_symbols[] = { (void *) boxffi_index_len, (void *) boxffi_index_random, (void *) boxffi_index_iterator, + (void *) boxffi_tuple_update, (void *) port_ffi_create, (void *) port_ffi_destroy, (void *) boxffi_select, @@ -45,5 +47,7 @@ void *ffi_symbols[] = { (void *) bsdsocket_local_resolve, (void *) bsdsocket_nonblock, (void *) base64_decode, + (void *) base64_encode, + (void *) base64_bufsize, (void *) SHA1internal }; diff --git a/src/lua/box_net_box.lua b/src/lua/box_net_box.lua index cef696ed4d8424f9cf912c1128b2bc463196cc2e..b8169e71f58a09859f1952440edc848facfe3b1b 100644 --- a/src/lua/box_net_box.lua +++ b/src/lua/box_net_box.lua @@ -8,6 +8,7 @@ local errno = require 'errno' local ffi = require 'ffi' local digest = require 'digest' local yaml = require 'yaml' +local urilib = require 'uri' -- packet codes local OK = 0 @@ -39,15 +40,11 @@ local GREETING_SIZE = 128 local TIMEOUT_INFINITY = 500 * 365 * 86400 - -ffi.cdef[[ - int base64_decode(const char *in_base64, int in_len, - char *out_bin, int out_len); -]] - local sequence_mt = { __serialize = 'sequence'} local mapping_mt = { __serialize = 'mapping'} +local CONSOLE_FAKESYNC = 15121974 + local function request(header, body) -- hint msgpack to always encode header and body as a map @@ -75,13 +72,6 @@ local function strxor(s1, s2) return res end -local function b64decode(str) - local so = ffi.new('char[?]', string.len(str) * 2); - local len = - ffi.C.base64_decode(str, string.len(str), so, string.len(str) * 2) - return ffi.string(so, len) -end - local function keyfy(v) if type(v) == 'table' then return v @@ -215,7 +205,7 @@ local proto = { auth = function(sync, user, password, handshake) local saltb64 = string.sub(handshake, 65) - local salt = string.sub(b64decode(saltb64), 1, 20) + local salt = string.sub(digest.base64_decode(saltb64), 1, 20) local hpassword = digest.sha1(password) local hhpassword = digest.sha1(hpassword) @@ -228,7 +218,7 @@ local proto = { ) end, - b64decode = b64decode, + b64decode = digest.base64_decode, } @@ -358,14 +348,51 @@ local remote_methods = { setmetatable(self, getmetatable(remote)) end + + -- uri as the first argument + if opts == nil then + opts = {} + if type(port) == 'table' then + opts = port + port = nil + end + + if port == nil then + + local address = urilib.parse(tostring(host)) + if address == nil or address.service == nil then + box.error(box.error.PROC_LUA, + "usage: remote:new(uri[, opts] | host, port[, opts])") + end + + host = address.host + port = address.service + + opts.user = address.login or opts.user + opts.password = address.password or opts.password + end + end + + self.is_instance = true self.host = host self.port = port self.opts = opts + if self.opts == nil then self.opts = {} end + if self.opts.user ~= nil and self.opts.password == nil then + box.error(box.error.PROC_LUA, + "net.box: password is not defined") + end + if self.opts.user == nil and self.opts.password ~= nil then + box.error(box.error.PROC_LUA, + "net.box: user is not defined") + end + + if self.host == nil then self.host = 'localhost' end @@ -391,6 +418,9 @@ local remote_methods = { ping = function(self) + if type(self) ~= 'table' then + box.error(box.error.PROC_LUA, "usage: remote:ping()") + end if not self:is_connected() then return false end @@ -411,8 +441,37 @@ local remote_methods = { end, call = function(self, proc_name, ...) + if type(self) ~= 'table' then + box.error(box.error.PROC_LUA, "usage: remote:call(proc_name, ...)") + end + proc_name = tostring(proc_name) - local res = self:_request('call', true, proc_name, {...}) + + if not self.console then + local res = self:_request('call', true, proc_name, {...}) + return res.body[DATA] + end + + local eval_str = proc_name .. '(' + for i = 1, select('#', ...) do + if i > 1 then + eval_str = eval_str .. ', ' + end + local arg = select(i, ...) + + if arg == nil then + eval_str = eval_str .. 'nil' + elseif type(arg) == 'number' then + eval_str = eval_str .. tostring(arg) + else + arg = tostring(arg) + arg = string.gsub(arg, '"', '\\"') + eval_str = eval_str .. '"' .. arg .. '"' + end + end + eval_str = eval_str .. ")\n" + + local res = self:_console_request(eval_str, true) return res.body[DATA] end, @@ -484,7 +543,7 @@ local remote_methods = { self.s = nil end - log.warn(emsg) + log.warn("%s", tostring(emsg)) self.error = emsg self.space = {} self:_switch_state('error') @@ -510,7 +569,49 @@ local remote_methods = { end end, + + _check_console_response = function(self) + while true do + local resp = string.match(self.rbuf, '.-\n[.][.][.]\r?\n') + if resp == nil then + break + end + self.rbuf = string.sub(self.rbuf, #resp + 1) + + local result = yaml.decode(resp) + if result ~= nil then + result = result[1] + end + + local hdr = { [SYNC] = CONSOLE_FAKESYNC, [TYPE] = 0 } + local body = {} + + if type(result) ~= 'table' then + result = { result } + end + + + if result.error ~= nil then + hdr[TYPE] = bit.bor(ERROR_TYPE, box.error.PROC_LUA) + body[ERROR] = result.error + else + body[DATA] = { result } + end + + if self.ch.sync[CONSOLE_FAKESYNC] ~= nil then + self.ch.sync[CONSOLE_FAKESYNC]:put({hdr = hdr, body = body }) + self.ch.sync[CONSOLE_FAKESYNC] = nil + else + log.warn("Unexpected console response: %s", resp) + end + end + end, + _check_response = function(self) + if self.console then + return self:_check_console_response(self) + end + while true do if #self.rbuf < 5 then break @@ -540,7 +641,7 @@ local remote_methods = { self.ch.sync[sync]:put({ hdr = hdr, body = body }) self.ch.sync[sync] = nil else - log.warn("Unexpected response %s", sync) + log.warn("Unexpected response %s", tostring(sync)) end end end, @@ -559,9 +660,11 @@ local remote_methods = { end for _, fid in pairs(list) do - if self.ch.fid[fid] ~= nil then - self.ch.fid[fid]:put(true) - self.ch.fid[fid] = nil + if fid ~= fiber.id() then + if self.ch.fid[fid] ~= nil then + self.ch.fid[fid]:put(true) + self.ch.fid[fid] = nil + end end end end, @@ -610,6 +713,7 @@ local remote_methods = { end end, + _connect_worker = function(self) fiber.name('net.box.connector') while true do @@ -641,24 +745,29 @@ local remote_methods = { elseif string.len(self.handshake) ~= 128 then self:_fatal("Can't read handshake") else - self.wbuf = '' self.rbuf = '' - local s, e = pcall(function() - self:_auth() - end) - if not s then - self:_fatal(e) - end - - xpcall(function() self:_load_schema() end, - function(e) - log.info("Can't load schema: %s", tostring(e)) - end) - - if self.state ~= 'error' and self.state ~= 'closed' then + if string.match(self.handshake, '^Tarantool .*console') then + self.console = true self:_switch_state('active') + else + self.console = false + local s, e = pcall(function() + self:_auth() + end) + if not s then + self:_fatal(e) + end + + xpcall(function() self:_load_schema() end, + function(e) + log.info("Can't load schema: %s", tostring(e)) + end) + + if self.state ~= 'error' and self.state ~= 'closed' then + self:_switch_state('active') + end end end end @@ -799,7 +908,7 @@ local remote_methods = { break end - if self.s:readable(.5) then + if self.s:readable() then if self.state == 'closed' then break end @@ -808,8 +917,12 @@ local remote_methods = { local data = self.s:sysread() if data ~= nil then - self.rbuf = self.rbuf .. data - self:_check_response() + if data == '' then + self:_fatal('Remote host closed connection') + else + self.rbuf = self.rbuf .. data + self:_check_response() + end else self:_fatal(errno.strerror(errno())) end @@ -893,16 +1006,20 @@ local remote_methods = { return self:_request_internal(name, raise, ...) end, - _request_internal = function(self, name, raise, ...) + _console_request = function(self, request_body, raise) + if raise == nil then + raise = true + end + return self:_request_raw(CONSOLE_FAKESYNC, request_body, raise) + end, + + _request_raw = function(self, sync, request, raise) local fid = fiber.id() if self.timeouts[fid] == nil then self.timeouts[fid] = TIMEOUT_INFINITY end - local sync = self.proto:sync() - local request = self.proto[name](sync, ...) - self.wbuf = self.wbuf .. request local wstate = self._to_wstate[self.state] @@ -938,8 +1055,11 @@ local remote_methods = { end if response.body[DATA] ~= nil then - for i, v in pairs(response.body[DATA]) do - response.body[DATA][i] = box.tuple.new(response.body[DATA][i]) + if rawget(box, 'tuple') ~= nil then + for i, v in pairs(response.body[DATA]) do + response.body[DATA][i] = + box.tuple.new(response.body[DATA][i]) + end end -- disable YAML flow output (useful for admin console) setmetatable(response.body[DATA], sequence_mt) @@ -948,6 +1068,14 @@ local remote_methods = { return response end, + _request_internal = function(self, name, raise, ...) + + local sync = self.proto:sync() + local request = self.proto[name](sync, ...) + return self:_request_raw(sync, request, raise) + + end, + -- private (low level) methods _select = function(self, spaceno, indexno, key, opts) local res = self:_request('select', true, spaceno, indexno, key, opts) @@ -983,6 +1111,9 @@ remote.self = { timeout = function(self) return self end, wait_connected = function(self) return true end, call = function(_box, proc_name, ...) + if type(_box) ~= 'table' then + box.error(box.error.PROC_LUA, "usage: remote:call(proc_name, ...)") + end proc_name = tostring(proc_name) local proc = { package.loaded['box.internal'] .call_loadproc(proc_name) } @@ -1001,7 +1132,8 @@ remote.self = { result[i] = box.tuple.new(v) end return result - end + end, + console = false } diff --git a/src/lua/bsdsocket.cc b/src/lua/bsdsocket.cc index 9e1e1693ad30c545036faeb8955df280d6bf9fe0..422571af9aef4323fe2188c44657682353a013c4 100644 --- a/src/lua/bsdsocket.cc +++ b/src/lua/bsdsocket.cc @@ -336,8 +336,8 @@ bsdsocket_local_resolve(const char *host, const char *port, } /* IPv6 */ - char ipv6[16]; - if (inet_pton(AF_INET6, host, ipv6) == 1) { + struct in6_addr ipv6; + if (inet_pton(AF_INET6, host, &ipv6) == 1) { struct sockaddr_in6 *inaddr6 = (struct sockaddr_in6 *) addr; if (*socklen < sizeof(*inaddr6)) { errno = ENOBUFS; @@ -345,8 +345,8 @@ bsdsocket_local_resolve(const char *host, const char *port, } memset(inaddr6, 0, sizeof(*inaddr6)); inaddr6->sin6_family = AF_INET6; - inaddr6->sin6_port = htonl(atol(port)); - memcpy(inaddr6->sin6_addr.s6_addr, ipv6, 16); + inaddr6->sin6_port = htons(atoi(port)); + memcpy(inaddr6->sin6_addr.s6_addr, &ipv6, sizeof(ipv6)); *socklen = sizeof(*inaddr6); return 0; } @@ -804,6 +804,24 @@ lbox_bsdsocket_peername(struct lua_State *L) return 1; } +static int +lbox_bsdsocket_accept(struct lua_State *L) +{ + int fh = lua_tointeger(L, 1); + + struct sockaddr_storage fa; + socklen_t len = sizeof(fa); + + int sc = accept(fh, (struct sockaddr*)&fa, &len); + if (sc < 0) { + lua_pushnil(L); + return 1; + } + lua_pushnumber(L, sc); + lbox_bsdsocket_push_addr(L, (struct sockaddr *)&fa, len); + return 2; +} + static int lbox_bsdsocket_recvfrom(struct lua_State *L) { @@ -860,6 +878,7 @@ tarantool_lua_bsdsocket_init(struct lua_State *L) { "peer", lbox_bsdsocket_peername }, { "recvfrom", lbox_bsdsocket_recvfrom }, { "abort", lbox_bsdsocket_abort }, + { "accept", lbox_bsdsocket_accept }, { NULL, NULL } }; diff --git a/src/lua/bsdsocket.lua b/src/lua/bsdsocket.lua index 871bdbd356a6fdf65f1d67199b3681c9b0a3dffc..3b65bc04137cb3f88591bd588ceae8fba1c939e6 100644 --- a/src/lua/bsdsocket.lua +++ b/src/lua/bsdsocket.lua @@ -6,6 +6,8 @@ local ffi = require('ffi') local boxerrno = require('errno') local internal = require('socket') local fiber = require('fiber') +local fio = require('fio') +local log = require('log') ffi.cdef[[ struct socket { @@ -75,9 +77,9 @@ local socket_mt local function bless_socket(fd) -- Make socket to be non-blocked by default if ffi.C.bsdsocket_nonblock(fd, 1) < 0 then - local errno = box.errno() + local errno = boxerrno() ffi.C.close(fd) - box.errno(errno) + boxerrno(errno) return nil end @@ -504,12 +506,12 @@ socket_methods.accept = function(self) local fd = check_socket(self) self._errno = nil - local cfd = ffi.C.accept(fd, nil, nil) - if cfd < 1 then - self._errno = box.errno() + local cfd, from = internal.accept(fd) + if cfd == nil then + self._errno = boxerrno() return nil end - return bless_socket(cfd) + return bless_socket(cfd), from end local function readchunk(self, size, timeout) @@ -950,6 +952,11 @@ local function tcp_connect(host, port, timeout) if dns == nil then return nil end + + if #dns == 0 then + boxerrno(boxerrno.EINVAL) + return nil + end for i, remote in pairs(dns) do timeout = stop - fiber.time() if timeout <= 0 then @@ -964,96 +971,117 @@ local function tcp_connect(host, port, timeout) return nil end -local function tcp_server_remote(list, prepare, handler) - local slist = {} - - -- bind/create sockets - for _, addr in pairs(list) do - local s = create_socket(addr.family, addr.type, addr.protocol) +local function tcp_server_handler(server, sc, from) + fiber.name(sprintf("%s/client/%s:%s", server.name, from.host, from.port)) + server.handler(sc, from) + sc:close() +end - local ok = false - if s ~= nil then - local backlog = prepare(s) - if s:bind(addr.host, addr.port) then - if s:listen(backlog) then - ok = true - end - end +local function tcp_server_loop(server, s, addr) + fiber.name(sprintf("%s/listen/%s:%s", server.name, addr.host, addr.port)) + while s:readable() do + local sc, from = s:accept() + if sc == nil then + break end + fiber.create(tcp_server_handler, server, sc, from) + end + if addr.family == 'AF_UNIX' and addr.port then + fio.unlink(addr.port) -- remove unix socket + end +end - -- errors - if not ok then - if s ~= nil then - s:close() - end - local save_errno = boxerrno() - for _, s in pairs(slist) do - s:close() - end - boxerrno(save_errno) - return nil - end +local function tcp_server_usage() + error('Usage: socket.tcp_server(host, port, handler | opts)') +end - table.insert(slist, s) +local function tcp_server_bind(s, addr) + if s:bind(addr.host, addr.port) then + return true end - - local server = { s = slist } - server.stop = function() - if #server.s == 0 then - return false - end - for _, s in pairs(server.s) do - s:close() - end - server.s = {} - return true + if addr.family ~= 'AF_UNIX' then + return false end - for _, s in pairs(server.s) do - fiber.create(function(s) - fiber.name(sprintf("listen_fd=%d",s:fd())) + if boxerrno() ~= boxerrno.EADDRINUSE then + return false + end - while s:readable() do - - local sc = s:accept() + local save_errno = boxerrno() - if sc == nil then - break - end + local sc = tcp_connect(addr.host, addr.port) + if sc ~= nil then + sc:close() + boxerrno(save_errno) + return false + end - fiber.create(function(sc) - pcall(handler, sc) - sc:close() - end, sc) - end - end, s) + if boxerrno() ~= boxerrno.ECONNREFUSED then + boxerrno(save_errno) + return false end - return server + log.info("tcp_server: remove dead UNIX socket: %s", addr.port) + if not fio.unlink(addr.port) then + log.warn("tcp_server: %s", boxerrno.strerror()) + boxerrno(save_errno) + return false + end + return s:bind(addr.host, addr.port) end -local function tcp_server(host, port, prepare, handler, timeout) - if handler == nil then - handler = prepare - prepare = function() end - end - if type(prepare) ~= 'function' or type(handler) ~= 'function' then - error("Usage: socket.tcp_server(host, port[, prepare], handler)") +local function tcp_server(host, port, opts, timeout) + local server = {} + if type(opts) == 'function' then + server.handler = opts + elseif type(opts) == 'table' then + if type(opts.handler) ~='function' or (opts.prepare ~= nil and + type(opts.prepare) ~= 'function') then + tcp_server_usage() + end + for k, v in pairs(opts) do + server[k] = v + end + else + tcp_server_usage() end - + server.name = server.name or 'server' + timeout = timeout and tonumber(timeout) or TIMEOUT_INFINITY + local dns if host == 'unix/' then - return tcp_server_remote({{host = host, port = port, protocol = 0, - family = 'PF_UNIX', type = 'SOCK_STREAM' }}, prepare, handler) + dns = {{host = host, port = port, family = 'AF_UNIX', protocol = 0, + type = 'SOCK_STREAM' }} + else + dns = getaddrinfo(host, port, timeout, { type = 'SOCK_STREAM' }) + if dns == nil then + return nil + end end - local dns = getaddrinfo(host, port, timeout, { type = 'SOCK_STREAM', - protocol = 'tcp' }) - if dns == nil then - return nil + for _, addr in ipairs(dns) do + local s = create_socket(addr.family, addr.type, addr.protocol) + if s ~= nil then + local backlog + if server.prepare then + backlog = server.prepare(s) + else + s:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', 1) -- ignore error + end + if not tcp_server_bind(s, addr) or not s:listen(backlog) then + local save_errno = boxerrno() + s:close() + boxerrno(save_errno) + return nil + end + fiber.create(tcp_server_loop, server, s, addr) + return s, addr + end end - return tcp_server_remote(dns, prepare, handler) + -- DNS resolved successfully, but addresss family is not supported + boxerrno(boxerrno.EAFNOSUPPORT) + return nil end socket_mt = { diff --git a/src/lua/console.lua b/src/lua/console.lua index 57d78d9f9093978fca5febda82ebba828ddd5405..7a591139111ecb596d5a780cc007e187bb32b9db 100644 --- a/src/lua/console.lua +++ b/src/lua/console.lua @@ -5,6 +5,7 @@ local fiber = require('fiber') local socket = require('socket') local log = require('log') local errno = require('errno') +local urilib = require('uri') -- admin formatter must be able to encode any Lua variable local formatter = require('yaml').new() @@ -69,6 +70,9 @@ end -- local function remote_eval(self, line) if not line then + if type(self.on_client_disconnect) == 'function' then + self:on_client_disconnect() + end pcall(self.remote.close, self.remote) self.remote = nil self.eval = nil @@ -150,7 +154,7 @@ local function client_print(self, output) elseif not output then -- disconnect peer local peer = self.client:peer() - log.info("console: client %s:%s disconnected", peer.host, peer.port) + log.info("client %s:%s disconnected", peer.host, peer.port) self.client:shutdown() self.client:close() self.client = nil @@ -178,7 +182,12 @@ local repl_mt = { -- REPL = read-eval-print-loop -- local function repl(self) + fiber.self().storage.console = self + if type(self.on_start) == 'function' then + self:on_start() + end + while self.running do local command = self:read() local output = self:eval(command) @@ -187,6 +196,22 @@ local function repl(self) fiber.self().storage.console = nil end +local function on_start(foo) + if foo == nil or type(foo) == 'function' then + repl_mt.__index.on_start = foo + return + end + error('Wrong type of on_start hook: ' .. type(foo)) +end + +local function on_client_disconnect(foo) + if foo == nil or type(foo) == 'function' then + repl_mt.__index.on_client_disconnect = foo + return + end + error('Wrong type of on_client_disconnect hook: ' .. type(foo)) +end + -- -- Set delimiter -- @@ -221,13 +246,31 @@ end -- -- Connect to remove server -- -local function connect(...) +local function connect(uri) local self = fiber.self().storage.console if self == nil then error("console.connect() need existing console") end + + local u + if uri then + u = urilib.parse(tostring(uri)) + end + if u == nil or u.service == nil then + error('Usage: console.connect("[login:password@][host:]port")') + end + -- connect to remote host - local remote = require('net.box'):new(...) + local remote = require('net.box'):new(u.host, u.service, + { user = u.login, password = u.password }) + + -- run disconnect trigger + if remote.state == 'closed' then + if type(self.on_client_disconnect) == 'function' then + self:on_client_disconnect() + end + end + -- check permissions remote:call('dostring', 'return true') -- override methods @@ -237,22 +280,19 @@ local function connect(...) log.info("connected to %s:%s", self.remote.host, self.remote.port) end -local function server_loop(server) - while server:readable() do - local client = server:accept() - if client then - local peer = client:peer() - log.info("console: client %s:%s connected", peer.host, peer.port) - local state = setmetatable({ - running = true; - read = client_read; - print = client_print; - client = client; - }, repl_mt) - fiber.create(repl, state) - end - end - log.info("console: stopped") +local function client_handler(client, peer) + log.info("client %s:%s connected", peer.host, peer.port) + local state = setmetatable({ + running = true; + read = client_read; + print = client_print; + client = client; + }, repl_mt) + state:print(string.format("%-63s\n%-63s\n", + "Tarantool ".. box.info.version.." (Lua console)", + "type 'help' for interactive help")) + repl(state) + log.info("client %s:%s disconnected", peer.host, peer.port) end -- @@ -262,46 +302,23 @@ local function listen(uri) local host, port if uri == nil then host = 'unix/' - elseif type(uri) == 'number' or uri:match("^%d+$") then - port = tonumber(uri) - elseif uri:match("^/") then - host = 'unix/' - port = uri + port = '/tmp/tarantool-console.sock' else - host, port = uri:match("^(.*):(.*)$") - if not host then - port = uri + local u = urilib.parse(tostring(uri)) + if u == nil or u.service == nil then + error('Usage: console.listen("[host:]port")') end + host = u.host + port = u.service or 3313 end - local server - if host == 'unix/' then - port = port or '/tmp/tarantool-console.sock' - os.remove(port) - server = socket('AF_UNIX', 'SOCK_STREAM', 0) - else - host = host or '127.0.0.1' - port = port or 3313 - server = socket('AF_INET', 'SOCK_STREAM', 'tcp') - end - if not server then - error(string.format('failed to create socket %s%s : %s', - host, port, errno.strerror())) - end - server:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true) - - if not server:bind(host, port) then - local msg = string.format('failed to bind: %s', server:error()) - server:close() - error(msg) - end - if not server:listen() then - local msg = string.format('failed to listen: %s', server:error()) - server:close() - error(msg) + local s, addr = socket.tcp_server(host, port, { handler = client_handler, + name = 'console'}) + if not s then + error(string.format('failed to create server %s:%s: %s', + host, port, errno.strerror())) end - log.info("console: started on %s:%s", host, port) - fiber.create(server_loop, server) - return server + log.info("started on %s:%s", addr.host, addr.port) + return s end return { @@ -310,4 +327,6 @@ return { delimiter = delimiter; connect = connect; listen = listen; + on_start = on_start; + on_client_disconnect = on_client_disconnect; } diff --git a/src/lua/digest.lua b/src/lua/digest.lua index 41b28f30b69c3ea537d2596b396e8f351e90e647..3f5653be86145e88d8f376ed21873dc58ee1faef 100644 --- a/src/lua/digest.lua +++ b/src/lua/digest.lua @@ -25,6 +25,11 @@ ffi.cdef[[ typedef uint32_t (*crc32_func)(uint32_t crc, const unsigned char *buf, unsigned int len); extern crc32_func crc32_calc; + + /* base64 */ + int base64_bufsize(int binsize); + int base64_decode(const char *in_base64, int in_len, char *out_bin, int out_len); + int base64_encode(const char *in_bin, int in_len, char *out_base64, int out_len); ]] local ssl @@ -67,6 +72,28 @@ local function tohex(r, size) end local m = { + base64_encode = function(bin) + if type(bin) ~= 'string' then + error('Usage: digest.base64_encode(string)') + end + local blen = #bin + local slen = ffi.C.base64_bufsize(blen) + local str = ffi.new('char[?]', slen) + local len = ffi.C.base64_encode(bin, blen, str, slen) + return ffi.string(str, len) + end, + + base64_decode = function(str) + if type(str) ~= 'string' then + error('Usage: digest.base64_decode(string)') + end + local slen = #str + local blen = math.ceil(slen * 3 / 4) + local bin = ffi.new('char[?]', blen) + local len = ffi.C.base64_decode(str, slen, bin, blen) + return ffi.string(bin, len) + end, + crc32 = function(str) if str == nil then str = '' diff --git a/src/lua/fiber.cc b/src/lua/fiber.cc index f8eda08a993a28ee4a8b822994d2b09435c9cb31..6d9e42201880a301fa87d2b898787edc349ffdb9 100644 --- a/src/lua/fiber.cc +++ b/src/lua/fiber.cc @@ -220,9 +220,13 @@ lbox_fiber_statof(struct fiber *f, void *cb_ctx) { struct lua_State *L = (struct lua_State *) cb_ctx; - lua_pushstring(L, fiber_name(f)); + lua_pushinteger(L, f->fid); lua_newtable(L); + lua_pushliteral(L, "name"); + lua_pushstring(L, fiber_name(f)); + lua_settable(L, -3); + lua_pushstring(L, "fid"); lua_pushnumber(L, f->fid); lua_settable(L, -3); diff --git a/src/lua/fio.lua b/src/lua/fio.lua index 48687703bdfb83e2fc42e2debde74c4815949ab9..9f6b10d92fa7efefd86f443c2c1862829b144aa0 100644 --- a/src/lua/fio.lua +++ b/src/lua/fio.lua @@ -5,6 +5,7 @@ local ffi = require('ffi') ffi.cdef[[ int umask(int mask); + char *dirname(char *path); ]] local internal = fio.internal @@ -209,18 +210,8 @@ fio.dirname = function(path) return nil end path = tostring(path) - - while true do - if path == "" or string.sub(path, -1) == "/" then - break - end - path = string.sub(path, 1, -2) - end - if path == "" then - path = "." - end - - return path + path = ffi.new('char[?]', #path, path) + return ffi.string(ffi.C.dirname(path)) end fio.umask = function(umask) diff --git a/src/lua/init.cc b/src/lua/init.cc index 633edffd93ad79407a13bb8e81109227cdc2d111..02fa51d7e6f357c9db52882451932aa0264b0a3b 100644 --- a/src/lua/init.cc +++ b/src/lua/init.cc @@ -73,6 +73,7 @@ extern char uuid_lua[], digest_lua[], init_lua[], log_lua[], + uri_lua[], bsdsocket_lua[], console_lua[], box_net_box_lua[], @@ -92,11 +93,12 @@ static const char *lua_modules[] = { "digest", digest_lua, "uuid", uuid_lua, "log", log_lua, + "uri", uri_lua, + "fio", fio_lua, "socket", bsdsocket_lua, "net.box", box_net_box_lua, "console", console_lua, "tap", tap_lua, - "fio", fio_lua, "help.en_US", help_en_US_lua, "help", help_lua, NULL @@ -291,9 +293,9 @@ tarantool_lua_init(const char *tarantool_bin, int argc, char **argv) tarantool_lua_fiber_init(L); tarantool_lua_ipc_init(L); tarantool_lua_errno_init(L); + tarantool_lua_fio_init(L); tarantool_lua_bsdsocket_init(L); tarantool_lua_pickle_init(L); - tarantool_lua_fio_init(L); luaopen_msgpack(L); lua_pop(L, 1); luaopen_yaml(L); diff --git a/src/lua/uri.lua b/src/lua/uri.lua new file mode 100644 index 0000000000000000000000000000000000000000..9f7bc7b0d9749e40be0f23a6e2a8f6af60792b58 --- /dev/null +++ b/src/lua/uri.lua @@ -0,0 +1,60 @@ +-- uri.lua (internal file) + +local ffi = require('ffi') + +ffi.cdef[[ +struct uri { + const char *scheme; + size_t scheme_len; + const char *login; + size_t login_len; + const char *password; + size_t password_len; + const char *host; + size_t host_len; + const char *service; + size_t service_len; + const char *path; + size_t path_len; + const char *query; + size_t query_len; + const char *fragment; + size_t fragment_len; + int host_hint; +}; + +int +uri_parse(struct uri *uri, const char *str); +]] + +local builtin = ffi.C; + +local uribuf = ffi.new('struct uri') + +local function parse(str) + if str == nil then + error("Usage: uri.parse(string)") + end + if builtin.uri_parse(uribuf, str) ~= 0 then + return nil + end + local result = {} + for _, k in ipairs({ 'scheme', 'login', 'password', 'host', 'service', + 'path', 'query', 'fragment'}) do + if uribuf[k] ~= nil then + result[k] = ffi.string(uribuf[k], uribuf[k..'_len']) + end + end + if uribuf.host_hint == 1 then + result.ipv4 = result.host + elseif uribuf.host_hint == 2 then + result.ipv6 = result.host + elseif uribuf.host_hint == 3 then + result.unix = result.service + end + return result +end + +return { + parse = parse; +}; diff --git a/src/lua/utils.cc b/src/lua/utils.cc index 7331bebc56ff7444be457a080d3e7ed422a8b37e..61f2786be6ec70ca79f08612844d5aad271f52b8 100644 --- a/src/lua/utils.cc +++ b/src/lua/utils.cc @@ -139,7 +139,7 @@ static struct { int type; int defvalue; } OPTIONS[] = { - OPTION(LUA_TBOOLEAN, encode_sparse_convert, 0), + OPTION(LUA_TBOOLEAN, encode_sparse_convert, 1), OPTION(LUA_TNUMBER, encode_sparse_ratio, 2), OPTION(LUA_TNUMBER, encode_sparse_safe, 10), OPTION(LUA_TNUMBER, encode_max_depth, 32), diff --git a/src/sio.cc b/src/sio.cc index 53d8469db0bd549a01e920b7837106cf87f9d419..3bafff5629503ea7d62c0d686af27bb1b08e5b7f 100644 --- a/src/sio.cc +++ b/src/sio.cc @@ -293,6 +293,33 @@ sio_writev(int fd, const struct iovec *iov, int iovcnt) return n; } +/** Blocking I/O writev */ +ssize_t +sio_writev_all(int fd, struct iovec *iov, int iovcnt) +{ + ssize_t bytes_total = 0; + struct iovec *iovend = iov + iovcnt; + while(1) { + int cnt = iovend - iov; + if (cnt > IOV_MAX) + cnt = IOV_MAX; + ssize_t bytes_written = writev(fd, iov, cnt); + if (bytes_written < 0) { + if (errno == EINTR) + continue; + tnt_raise(SocketError, fd, "writev(%d)", cnt); + } + bytes_total += bytes_written; + while (bytes_written >= iov->iov_len) + bytes_written -= (iov++)->iov_len; + if (iov == iovend) + break; + iov->iov_base = (char *) iov->iov_base + bytes_written; + iov->iov_len -= bytes_written; + } + return bytes_total; +} + ssize_t sio_readn_ahead(int fd, void *buf, size_t count, size_t buf_size) { @@ -443,26 +470,28 @@ sio_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen) const char * sio_strfaddr(struct sockaddr *addr, socklen_t addrlen) { - static __thread char name[SERVICE_NAME_MAXLEN]; + static __thread char name[NI_MAXHOST + _POSIX_PATH_MAX + 2]; switch(addr->sa_family) { case AF_UNIX: if (addrlen >= sizeof(sockaddr_un)) { - snprintf(name, sizeof(name), "unix://%s", + snprintf(name, sizeof(name), "unix/:%s", ((struct sockaddr_un *)addr)->sun_path); } else { snprintf(name, sizeof(name), - "unix://%s", ""); + "unix/:(socket)"); } break; - case AF_INET: { - struct sockaddr_in *in = (struct sockaddr_in *)addr; - snprintf(name, sizeof(name), "%s:%d", - inet_ntoa(in->sin_addr), ntohs(in->sin_port)); - break; - } - case AF_INET6: { - *name = 0; - inet_ntop(AF_INET6, addr, name, sizeof(name)); + default: { + char host[NI_MAXHOST], serv[NI_MAXSERV]; + if (getnameinfo(addr, addrlen, host, sizeof(host), + serv, sizeof(serv), + NI_NUMERICHOST | NI_NUMERICSERV) == 0) { + snprintf(name, sizeof(name), + addr->sa_family == AF_INET + ? "%s:%s" : "[%s]:%s", host, serv); + } else { + snprintf(name, sizeof(name), "(host):(port)"); + } break; } } diff --git a/src/sio.h b/src/sio.h index bcd04a2ab1a1a235448736d485ec92b47087b0b4..d527c3802650a54283f883ddae758891936165c1 100644 --- a/src/sio.h +++ b/src/sio.h @@ -118,24 +118,8 @@ ssize_t sio_writen(int fd, const void *buf, size_t count); /* Only for blocked I/O */ -static inline ssize_t -sio_writev_all(int fd, struct iovec *iov, int iovcnt) -{ - ssize_t bytes_total = 0; - struct iovec *iovend = iov + iovcnt; - while(1) { - ssize_t bytes_written = sio_writev(fd, iov, iovend - iov); - bytes_total += bytes_written; - while (bytes_written > 0 && bytes_written >= iov->iov_len) - bytes_written -= (iov++)->iov_len; - if (iov == iovend) - break; - iov->iov_base = (char *) iov->iov_base + bytes_written; - iov->iov_len -= bytes_written; - } - - return bytes_total; -} +ssize_t +sio_writev_all(int fd, struct iovec *iov, int iovcnt); /** * A wrapper over sendfile. diff --git a/src/tarantool.cc b/src/tarantool.cc index 92f360034d2fd6affd030ac8762a781422a13d12..c7c4830871c438ddc61351da2d4ce48f5b52749a 100644 --- a/src/tarantool.cc +++ b/src/tarantool.cc @@ -367,6 +367,8 @@ background() if (setsid() == -1) goto error; + /* reinit coeio after fork (because libeio required it) */ + coeio_reinit(); /* * Prints to stdout on failure, so got to be done before * we close it. diff --git a/src/uri.c b/src/uri.c new file mode 100644 index 0000000000000000000000000000000000000000..8b66299c6d887b6e257cad23b964c8f19927916b --- /dev/null +++ b/src/uri.c @@ -0,0 +1,6528 @@ + +#line 1 "../../src/uri.rl" +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "uri.h" +#include <string.h> +#include <stdio.h> /* snprintf */ +int +uri_parse(struct uri *uri, const char *p) +{ + const char *pe = p + strlen(p); + const char *eof = pe; + int cs; + memset(uri, 0, sizeof(*uri)); + + if (p == pe) + return -1; + + const char *s = NULL, *login = NULL, *scheme = NULL; + size_t login_len = 0, scheme_len = 0; + + +#line 50 "../../src/uri.c" +static const int uri_start = 144; +static const int uri_first_final = 144; +static const int uri_error = 0; + +static const int uri_en_main = 144; + + +#line 58 "../../src/uri.c" + { + cs = uri_start; + } + +#line 63 "../../src/uri.c" + { + if ( p == pe ) + goto _test_eof; + switch ( cs ) + { +case 144: + switch( (*p) ) { + case 33: goto tr150; + case 35: goto tr151; + case 37: goto tr152; + case 47: goto tr153; + case 59: goto tr150; + case 61: goto tr150; + case 63: goto tr155; + case 64: goto st204; + case 91: goto st38; + case 95: goto tr150; + case 117: goto tr158; + case 126: goto tr150; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto tr150; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr157; + } else if ( (*p) >= 65 ) + goto tr157; + } else + goto tr154; + goto st0; +st0: +cs = 0; + goto _out; +tr150: +#line 137 "../../src/uri.rl" + { s = p; } +#line 92 "../../src/uri.rl" + { s = p; } + goto st145; +st145: + if ( ++p == pe ) + goto _test_eof145; +case 145: +#line 109 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 47: goto tr161; + case 58: goto tr162; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st145; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else + goto st145; + goto st0; +tr151: +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 185 "../../src/uri.rl" + { s = p; } + goto st146; +tr159: +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 185 "../../src/uri.rl" + { s = p; } + goto st146; +tr170: +#line 68 "../../src/uri.rl" + { s = p; } +#line 69 "../../src/uri.rl" + { uri->query = s; uri->query_len = p - s; } +#line 185 "../../src/uri.rl" + { s = p; } + goto st146; +tr172: +#line 69 "../../src/uri.rl" + { uri->query = s; uri->query_len = p - s; } +#line 185 "../../src/uri.rl" + { s = p; } + goto st146; +tr175: +#line 131 "../../src/uri.rl" + { s = p; } +#line 132 "../../src/uri.rl" + { uri->service = s; uri->service_len = p - s; } +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 185 "../../src/uri.rl" + { s = p; } + goto st146; +tr185: +#line 132 "../../src/uri.rl" + { uri->service = s; uri->service_len = p - s; } +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 185 "../../src/uri.rl" + { s = p; } + goto st146; +tr200: +#line 100 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s; + uri->host_hint = 1; } +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 185 "../../src/uri.rl" + { s = p; } + goto st146; +tr209: +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 185 "../../src/uri.rl" + { s = p; } + goto st146; +tr314: +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 128 "../../src/uri.rl" + { s = p;} +#line 111 "../../src/uri.rl" + { + /* + * This action is also called for path_* terminals. + * I absolute have no idea why. Please don't blame + * and fix grammar if you have a LOT of free time. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } +#line 185 "../../src/uri.rl" + { s = p; } + goto st146; +tr318: +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 111 "../../src/uri.rl" + { + /* + * This action is also called for path_* terminals. + * I absolute have no idea why. Please don't blame + * and fix grammar if you have a LOT of free time. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } +#line 185 "../../src/uri.rl" + { s = p; } + goto st146; +tr323: +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 111 "../../src/uri.rl" + { + /* + * This action is also called for path_* terminals. + * I absolute have no idea why. Please don't blame + * and fix grammar if you have a LOT of free time. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } +#line 185 "../../src/uri.rl" + { s = p; } + goto st146; +st146: + if ( ++p == pe ) + goto _test_eof146; +case 146: +#line 281 "../../src/uri.c" + switch( (*p) ) { + case 33: goto tr165; + case 37: goto tr166; + case 61: goto tr165; + case 95: goto tr165; + case 126: goto tr165; + } + if ( (*p) < 63 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto tr165; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr165; + } else + goto tr165; + goto st0; +tr165: +#line 72 "../../src/uri.rl" + { s = p; } + goto st147; +st147: + if ( ++p == pe ) + goto _test_eof147; +case 147: +#line 306 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st147; + case 37: goto st1; + case 61: goto st147; + case 95: goto st147; + case 126: goto st147; + } + if ( (*p) < 63 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st147; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st147; + } else + goto st147; + goto st0; +tr166: +#line 72 "../../src/uri.rl" + { s = p; } + goto st1; +st1: + if ( ++p == pe ) + goto _test_eof1; +case 1: +#line 331 "../../src/uri.c" + switch( (*p) ) { + case 37: goto st147; + case 117: goto st2; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st147; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st147; + } else + goto st147; + goto st0; +st2: + if ( ++p == pe ) + goto _test_eof2; +case 2: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st3; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st3; + } else + goto st3; + goto st0; +st3: + if ( ++p == pe ) + goto _test_eof3; +case 3: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st4; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st4; + } else + goto st4; + goto st0; +st4: + if ( ++p == pe ) + goto _test_eof4; +case 4: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st5; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st5; + } else + goto st5; + goto st0; +st5: + if ( ++p == pe ) + goto _test_eof5; +case 5: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st147; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st147; + } else + goto st147; + goto st0; +tr152: +#line 137 "../../src/uri.rl" + { s = p; } +#line 92 "../../src/uri.rl" + { s = p; } + goto st6; +st6: + if ( ++p == pe ) + goto _test_eof6; +case 6: +#line 407 "../../src/uri.c" + switch( (*p) ) { + case 37: goto st145; + case 117: goto st7; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st145; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st145; + } else + goto st145; + goto st0; +st7: + if ( ++p == pe ) + goto _test_eof7; +case 7: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st8; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st8; + } else + goto st8; + goto st0; +st8: + if ( ++p == pe ) + goto _test_eof8; +case 8: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st9; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st9; + } else + goto st9; + goto st0; +st9: + if ( ++p == pe ) + goto _test_eof9; +case 9: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st10; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st10; + } else + goto st10; + goto st0; +st10: + if ( ++p == pe ) + goto _test_eof10; +case 10: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st145; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st145; + } else + goto st145; + goto st0; +tr161: +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} +#line 161 "../../src/uri.rl" + { s = p; } + goto st148; +tr177: +#line 131 "../../src/uri.rl" + { s = p; } +#line 132 "../../src/uri.rl" + { uri->service = s; uri->service_len = p - s; } +#line 161 "../../src/uri.rl" + { s = p; } + goto st148; +tr186: +#line 132 "../../src/uri.rl" + { uri->service = s; uri->service_len = p - s; } +#line 161 "../../src/uri.rl" + { s = p; } + goto st148; +tr201: +#line 100 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s; + uri->host_hint = 1; } +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} +#line 161 "../../src/uri.rl" + { s = p; } + goto st148; +tr210: +#line 161 "../../src/uri.rl" + { s = p; } + goto st148; +st148: + if ( ++p == pe ) + goto _test_eof148; +case 148: +#line 510 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st148; + case 35: goto tr151; + case 37: goto st11; + case 61: goto st148; + case 63: goto tr155; + case 95: goto st148; + case 126: goto st148; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st148; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st148; + } else + goto st148; + goto st0; +st11: + if ( ++p == pe ) + goto _test_eof11; +case 11: + switch( (*p) ) { + case 37: goto st148; + case 117: goto st12; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st148; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st148; + } else + goto st148; + goto st0; +st12: + if ( ++p == pe ) + goto _test_eof12; +case 12: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st13; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st13; + } else + goto st13; + goto st0; +st13: + if ( ++p == pe ) + goto _test_eof13; +case 13: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st14; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st14; + } else + goto st14; + goto st0; +st14: + if ( ++p == pe ) + goto _test_eof14; +case 14: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st15; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st15; + } else + goto st15; + goto st0; +st15: + if ( ++p == pe ) + goto _test_eof15; +case 15: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st148; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st148; + } else + goto st148; + goto st0; +tr155: +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 185 "../../src/uri.rl" + { s = p; } + goto st149; +tr163: +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 185 "../../src/uri.rl" + { s = p; } + goto st149; +tr179: +#line 131 "../../src/uri.rl" + { s = p; } +#line 132 "../../src/uri.rl" + { uri->service = s; uri->service_len = p - s; } +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 185 "../../src/uri.rl" + { s = p; } + goto st149; +tr188: +#line 132 "../../src/uri.rl" + { uri->service = s; uri->service_len = p - s; } +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 185 "../../src/uri.rl" + { s = p; } + goto st149; +tr204: +#line 100 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s; + uri->host_hint = 1; } +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 185 "../../src/uri.rl" + { s = p; } + goto st149; +tr212: +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 185 "../../src/uri.rl" + { s = p; } + goto st149; +tr317: +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 128 "../../src/uri.rl" + { s = p;} +#line 111 "../../src/uri.rl" + { + /* + * This action is also called for path_* terminals. + * I absolute have no idea why. Please don't blame + * and fix grammar if you have a LOT of free time. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } +#line 185 "../../src/uri.rl" + { s = p; } + goto st149; +tr320: +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 111 "../../src/uri.rl" + { + /* + * This action is also called for path_* terminals. + * I absolute have no idea why. Please don't blame + * and fix grammar if you have a LOT of free time. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } +#line 185 "../../src/uri.rl" + { s = p; } + goto st149; +tr325: +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 111 "../../src/uri.rl" + { + /* + * This action is also called for path_* terminals. + * I absolute have no idea why. Please don't blame + * and fix grammar if you have a LOT of free time. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } +#line 185 "../../src/uri.rl" + { s = p; } + goto st149; +st149: + if ( ++p == pe ) + goto _test_eof149; +case 149: +#line 734 "../../src/uri.c" + switch( (*p) ) { + case 33: goto tr169; + case 35: goto tr170; + case 37: goto tr171; + case 61: goto tr169; + case 95: goto tr169; + case 126: goto tr169; + } + if ( (*p) < 63 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto tr169; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr169; + } else + goto tr169; + goto st0; +tr169: +#line 68 "../../src/uri.rl" + { s = p; } + goto st150; +st150: + if ( ++p == pe ) + goto _test_eof150; +case 150: +#line 760 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st150; + case 35: goto tr172; + case 37: goto st16; + case 61: goto st150; + case 95: goto st150; + case 126: goto st150; + } + if ( (*p) < 63 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st150; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st150; + } else + goto st150; + goto st0; +tr171: +#line 68 "../../src/uri.rl" + { s = p; } + goto st16; +st16: + if ( ++p == pe ) + goto _test_eof16; +case 16: +#line 786 "../../src/uri.c" + switch( (*p) ) { + case 37: goto st150; + case 117: goto st17; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st150; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st150; + } else + goto st150; + goto st0; +st17: + if ( ++p == pe ) + goto _test_eof17; +case 17: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st18; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st18; + } else + goto st18; + goto st0; +st18: + if ( ++p == pe ) + goto _test_eof18; +case 18: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st19; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st19; + } else + goto st19; + goto st0; +st19: + if ( ++p == pe ) + goto _test_eof19; +case 19: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st20; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st20; + } else + goto st20; + goto st0; +st20: + if ( ++p == pe ) + goto _test_eof20; +case 20: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st150; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st150; + } else + goto st150; + goto st0; +tr162: +#line 138 "../../src/uri.rl" + { login = s; login_len = p - s; } +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} + goto st151; +tr240: +#line 138 "../../src/uri.rl" + { login = s; login_len = p - s; } +#line 100 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s; + uri->host_hint = 1; } +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} + goto st151; +st151: + if ( ++p == pe ) + goto _test_eof151; +case 151: +#line 871 "../../src/uri.c" + switch( (*p) ) { + case 33: goto tr174; + case 35: goto tr175; + case 37: goto tr176; + case 47: goto tr177; + case 59: goto tr174; + case 61: goto tr174; + case 63: goto tr179; + case 95: goto tr174; + case 126: goto tr174; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto tr174; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr180; + } else if ( (*p) >= 65 ) + goto tr180; + } else + goto tr178; + goto st0; +tr174: +#line 141 "../../src/uri.rl" + { s = p; } + goto st21; +st21: + if ( ++p == pe ) + goto _test_eof21; +case 21: +#line 903 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st21; + case 37: goto st22; + case 59: goto st21; + case 61: goto st21; + case 64: goto tr23; + case 95: goto st21; + case 126: goto st21; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st21; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st21; + } else if ( (*p) >= 65 ) + goto st21; + } else + goto st21; + goto st0; +tr176: +#line 141 "../../src/uri.rl" + { s = p; } + goto st22; +st22: + if ( ++p == pe ) + goto _test_eof22; +case 22: +#line 933 "../../src/uri.c" + switch( (*p) ) { + case 37: goto st21; + case 117: goto st23; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st21; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st21; + } else + goto st21; + goto st0; +st23: + if ( ++p == pe ) + goto _test_eof23; +case 23: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st24; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st24; + } else + goto st24; + goto st0; +st24: + if ( ++p == pe ) + goto _test_eof24; +case 24: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st25; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st25; + } else + goto st25; + goto st0; +st25: + if ( ++p == pe ) + goto _test_eof25; +case 25: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st26; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st26; + } else + goto st26; + goto st0; +st26: + if ( ++p == pe ) + goto _test_eof26; +case 26: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st21; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st21; + } else + goto st21; + goto st0; +tr23: +#line 142 "../../src/uri.rl" + { uri->password = s; uri->password_len = p - s; } +#line 146 "../../src/uri.rl" + { uri->login = login; uri->login_len = login_len; } + goto st27; +tr164: +#line 138 "../../src/uri.rl" + { login = s; login_len = p - s; } +#line 146 "../../src/uri.rl" + { uri->login = login; uri->login_len = login_len; } + goto st27; +st27: + if ( ++p == pe ) + goto _test_eof27; +case 27: +#line 1015 "../../src/uri.c" + switch( (*p) ) { + case 33: goto tr28; + case 37: goto tr29; + case 47: goto tr30; + case 59: goto tr28; + case 61: goto tr28; + case 91: goto st38; + case 95: goto tr28; + case 117: goto tr33; + case 126: goto tr28; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto tr28; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr28; + } else if ( (*p) >= 65 ) + goto tr28; + } else + goto tr31; + goto st0; +tr28: +#line 92 "../../src/uri.rl" + { s = p; } + goto st152; +st152: + if ( ++p == pe ) + goto _test_eof152; +case 152: +#line 1047 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 47: goto tr161; + case 58: goto tr182; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st152; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else + goto st152; + goto st0; +tr29: +#line 92 "../../src/uri.rl" + { s = p; } + goto st28; +st28: + if ( ++p == pe ) + goto _test_eof28; +case 28: +#line 1076 "../../src/uri.c" + switch( (*p) ) { + case 37: goto st152; + case 117: goto st29; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st152; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st152; + } else + goto st152; + goto st0; +st29: + if ( ++p == pe ) + goto _test_eof29; +case 29: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st30; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st30; + } else + goto st30; + goto st0; +st30: + if ( ++p == pe ) + goto _test_eof30; +case 30: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st31; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st31; + } else + goto st31; + goto st0; +st31: + if ( ++p == pe ) + goto _test_eof31; +case 31: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st32; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st32; + } else + goto st32; + goto st0; +st32: + if ( ++p == pe ) + goto _test_eof32; +case 32: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st152; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st152; + } else + goto st152; + goto st0; +tr182: +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} + goto st153; +tr203: +#line 100 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s; + uri->host_hint = 1; } +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} + goto st153; +st153: + if ( ++p == pe ) + goto _test_eof153; +case 153: +#line 1157 "../../src/uri.c" + switch( (*p) ) { + case 35: goto tr175; + case 47: goto tr177; + case 63: goto tr179; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr183; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr184; + } else + goto tr184; + goto st0; +tr183: +#line 131 "../../src/uri.rl" + { s = p; } + goto st154; +st154: + if ( ++p == pe ) + goto _test_eof154; +case 154: +#line 1180 "../../src/uri.c" + switch( (*p) ) { + case 35: goto tr185; + case 47: goto tr186; + case 63: goto tr188; + } + if ( 48 <= (*p) && (*p) <= 57 ) + goto st154; + goto st0; +tr184: +#line 131 "../../src/uri.rl" + { s = p; } + goto st155; +st155: + if ( ++p == pe ) + goto _test_eof155; +case 155: +#line 1197 "../../src/uri.c" + switch( (*p) ) { + case 35: goto tr185; + case 47: goto tr186; + case 63: goto tr188; + } + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st155; + } else if ( (*p) >= 65 ) + goto st155; + goto st0; +tr30: +#line 182 "../../src/uri.rl" + { s = p; } + goto st156; +st156: + if ( ++p == pe ) + goto _test_eof156; +case 156: +#line 1217 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st157; + case 37: goto st33; + case 61: goto st157; + case 95: goto st157; + case 126: goto st157; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st157; + } else if ( (*p) > 59 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st157; + } else if ( (*p) >= 64 ) + goto st157; + } else + goto st157; + goto st0; +st157: + if ( ++p == pe ) + goto _test_eof157; +case 157: + switch( (*p) ) { + case 33: goto st157; + case 37: goto st33; + case 61: goto st157; + case 95: goto st157; + case 126: goto st157; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st157; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st157; + } else + goto st157; + goto st0; +st33: + if ( ++p == pe ) + goto _test_eof33; +case 33: + switch( (*p) ) { + case 37: goto st157; + case 117: goto st34; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st157; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st157; + } else + goto st157; + goto st0; +st34: + if ( ++p == pe ) + goto _test_eof34; +case 34: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st35; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st35; + } else + goto st35; + goto st0; +st35: + if ( ++p == pe ) + goto _test_eof35; +case 35: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st36; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st36; + } else + goto st36; + goto st0; +st36: + if ( ++p == pe ) + goto _test_eof36; +case 36: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st37; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st37; + } else + goto st37; + goto st0; +st37: + if ( ++p == pe ) + goto _test_eof37; +case 37: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st157; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st157; + } else + goto st157; + goto st0; +tr31: +#line 99 "../../src/uri.rl" + { s = p; } +#line 92 "../../src/uri.rl" + { s = p; } + goto st158; +st158: + if ( ++p == pe ) + goto _test_eof158; +case 158: +#line 1336 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 46: goto st159; + case 47: goto tr161; + case 58: goto tr182; + case 59: goto st152; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st152; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else if ( (*p) >= 65 ) + goto st152; + } else + goto st171; + goto st0; +st159: + if ( ++p == pe ) + goto _test_eof159; +case 159: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 47: goto tr161; + case 58: goto tr182; + case 59: goto st152; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st152; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else if ( (*p) >= 65 ) + goto st152; + } else + goto st160; + goto st0; +st160: + if ( ++p == pe ) + goto _test_eof160; +case 160: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 46: goto st161; + case 47: goto tr161; + case 58: goto tr182; + case 59: goto st152; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st152; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else if ( (*p) >= 65 ) + goto st152; + } else + goto st169; + goto st0; +st161: + if ( ++p == pe ) + goto _test_eof161; +case 161: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 47: goto tr161; + case 58: goto tr182; + case 59: goto st152; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st152; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else if ( (*p) >= 65 ) + goto st152; + } else + goto st162; + goto st0; +st162: + if ( ++p == pe ) + goto _test_eof162; +case 162: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 46: goto st163; + case 47: goto tr161; + case 58: goto tr182; + case 59: goto st152; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st152; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else if ( (*p) >= 65 ) + goto st152; + } else + goto st167; + goto st0; +st163: + if ( ++p == pe ) + goto _test_eof163; +case 163: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 47: goto tr161; + case 58: goto tr182; + case 59: goto st152; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st152; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else if ( (*p) >= 65 ) + goto st152; + } else + goto st164; + goto st0; +st164: + if ( ++p == pe ) + goto _test_eof164; +case 164: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr200; + case 37: goto st28; + case 47: goto tr201; + case 58: goto tr203; + case 59: goto st152; + case 61: goto st152; + case 63: goto tr204; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st152; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else if ( (*p) >= 65 ) + goto st152; + } else + goto st165; + goto st0; +st165: + if ( ++p == pe ) + goto _test_eof165; +case 165: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr200; + case 37: goto st28; + case 47: goto tr201; + case 58: goto tr203; + case 59: goto st152; + case 61: goto st152; + case 63: goto tr204; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st152; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else if ( (*p) >= 65 ) + goto st152; + } else + goto st166; + goto st0; +st166: + if ( ++p == pe ) + goto _test_eof166; +case 166: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr200; + case 37: goto st28; + case 47: goto tr201; + case 58: goto tr203; + case 61: goto st152; + case 63: goto tr204; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st152; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else + goto st152; + goto st0; +st167: + if ( ++p == pe ) + goto _test_eof167; +case 167: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 46: goto st163; + case 47: goto tr161; + case 58: goto tr182; + case 59: goto st152; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st152; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else if ( (*p) >= 65 ) + goto st152; + } else + goto st168; + goto st0; +st168: + if ( ++p == pe ) + goto _test_eof168; +case 168: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 46: goto st163; + case 47: goto tr161; + case 58: goto tr182; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st152; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else + goto st152; + goto st0; +st169: + if ( ++p == pe ) + goto _test_eof169; +case 169: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 46: goto st161; + case 47: goto tr161; + case 58: goto tr182; + case 59: goto st152; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st152; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else if ( (*p) >= 65 ) + goto st152; + } else + goto st170; + goto st0; +st170: + if ( ++p == pe ) + goto _test_eof170; +case 170: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 46: goto st161; + case 47: goto tr161; + case 58: goto tr182; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st152; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else + goto st152; + goto st0; +st171: + if ( ++p == pe ) + goto _test_eof171; +case 171: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 46: goto st159; + case 47: goto tr161; + case 58: goto tr182; + case 59: goto st152; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st152; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else if ( (*p) >= 65 ) + goto st152; + } else + goto st172; + goto st0; +st172: + if ( ++p == pe ) + goto _test_eof172; +case 172: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 46: goto st159; + case 47: goto tr161; + case 58: goto tr182; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st152; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else + goto st152; + goto st0; +st38: + if ( ++p == pe ) + goto _test_eof38; +case 38: + if ( (*p) == 58 ) + goto tr45; + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto tr44; + } else if ( (*p) >= 48 ) + goto tr44; + goto st0; +tr44: +#line 106 "../../src/uri.rl" + { s = p; } + goto st39; +st39: + if ( ++p == pe ) + goto _test_eof39; +case 39: +#line 1766 "../../src/uri.c" + if ( (*p) == 58 ) + goto st43; + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st40; + } else if ( (*p) >= 48 ) + goto st40; + goto st0; +st40: + if ( ++p == pe ) + goto _test_eof40; +case 40: + if ( (*p) == 58 ) + goto st43; + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st41; + } else if ( (*p) >= 48 ) + goto st41; + goto st0; +st41: + if ( ++p == pe ) + goto _test_eof41; +case 41: + if ( (*p) == 58 ) + goto st43; + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st42; + } else if ( (*p) >= 48 ) + goto st42; + goto st0; +st42: + if ( ++p == pe ) + goto _test_eof42; +case 42: + if ( (*p) == 58 ) + goto st43; + goto st0; +st43: + if ( ++p == pe ) + goto _test_eof43; +case 43: + switch( (*p) ) { + case 58: goto st48; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st44; + } else if ( (*p) >= 48 ) + goto st44; + goto st0; +st44: + if ( ++p == pe ) + goto _test_eof44; +case 44: + switch( (*p) ) { + case 58: goto st48; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st45; + } else if ( (*p) >= 48 ) + goto st45; + goto st0; +st45: + if ( ++p == pe ) + goto _test_eof45; +case 45: + switch( (*p) ) { + case 58: goto st48; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st46; + } else if ( (*p) >= 48 ) + goto st46; + goto st0; +st46: + if ( ++p == pe ) + goto _test_eof46; +case 46: + switch( (*p) ) { + case 58: goto st48; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st47; + } else if ( (*p) >= 48 ) + goto st47; + goto st0; +st47: + if ( ++p == pe ) + goto _test_eof47; +case 47: + switch( (*p) ) { + case 58: goto st48; + case 93: goto tr52; + } + goto st0; +st48: + if ( ++p == pe ) + goto _test_eof48; +case 48: + switch( (*p) ) { + case 58: goto st53; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st49; + } else if ( (*p) >= 48 ) + goto st49; + goto st0; +st49: + if ( ++p == pe ) + goto _test_eof49; +case 49: + switch( (*p) ) { + case 58: goto st53; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st50; + } else if ( (*p) >= 48 ) + goto st50; + goto st0; +st50: + if ( ++p == pe ) + goto _test_eof50; +case 50: + switch( (*p) ) { + case 58: goto st53; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st51; + } else if ( (*p) >= 48 ) + goto st51; + goto st0; +st51: + if ( ++p == pe ) + goto _test_eof51; +case 51: + switch( (*p) ) { + case 58: goto st53; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st52; + } else if ( (*p) >= 48 ) + goto st52; + goto st0; +st52: + if ( ++p == pe ) + goto _test_eof52; +case 52: + switch( (*p) ) { + case 58: goto st53; + case 93: goto tr52; + } + goto st0; +st53: + if ( ++p == pe ) + goto _test_eof53; +case 53: + switch( (*p) ) { + case 58: goto st58; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st54; + } else if ( (*p) >= 48 ) + goto st54; + goto st0; +st54: + if ( ++p == pe ) + goto _test_eof54; +case 54: + switch( (*p) ) { + case 58: goto st58; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st55; + } else if ( (*p) >= 48 ) + goto st55; + goto st0; +st55: + if ( ++p == pe ) + goto _test_eof55; +case 55: + switch( (*p) ) { + case 58: goto st58; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st56; + } else if ( (*p) >= 48 ) + goto st56; + goto st0; +st56: + if ( ++p == pe ) + goto _test_eof56; +case 56: + switch( (*p) ) { + case 58: goto st58; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st57; + } else if ( (*p) >= 48 ) + goto st57; + goto st0; +st57: + if ( ++p == pe ) + goto _test_eof57; +case 57: + switch( (*p) ) { + case 58: goto st58; + case 93: goto tr52; + } + goto st0; +st58: + if ( ++p == pe ) + goto _test_eof58; +case 58: + switch( (*p) ) { + case 58: goto st63; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st59; + } else if ( (*p) >= 48 ) + goto st59; + goto st0; +st59: + if ( ++p == pe ) + goto _test_eof59; +case 59: + switch( (*p) ) { + case 58: goto st63; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st60; + } else if ( (*p) >= 48 ) + goto st60; + goto st0; +st60: + if ( ++p == pe ) + goto _test_eof60; +case 60: + switch( (*p) ) { + case 58: goto st63; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st61; + } else if ( (*p) >= 48 ) + goto st61; + goto st0; +st61: + if ( ++p == pe ) + goto _test_eof61; +case 61: + switch( (*p) ) { + case 58: goto st63; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st62; + } else if ( (*p) >= 48 ) + goto st62; + goto st0; +st62: + if ( ++p == pe ) + goto _test_eof62; +case 62: + switch( (*p) ) { + case 58: goto st63; + case 93: goto tr52; + } + goto st0; +st63: + if ( ++p == pe ) + goto _test_eof63; +case 63: + switch( (*p) ) { + case 58: goto st68; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st64; + } else if ( (*p) >= 48 ) + goto st64; + goto st0; +st64: + if ( ++p == pe ) + goto _test_eof64; +case 64: + switch( (*p) ) { + case 58: goto st68; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st65; + } else if ( (*p) >= 48 ) + goto st65; + goto st0; +st65: + if ( ++p == pe ) + goto _test_eof65; +case 65: + switch( (*p) ) { + case 58: goto st68; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st66; + } else if ( (*p) >= 48 ) + goto st66; + goto st0; +st66: + if ( ++p == pe ) + goto _test_eof66; +case 66: + switch( (*p) ) { + case 58: goto st68; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st67; + } else if ( (*p) >= 48 ) + goto st67; + goto st0; +st67: + if ( ++p == pe ) + goto _test_eof67; +case 67: + switch( (*p) ) { + case 58: goto st68; + case 93: goto tr52; + } + goto st0; +st68: + if ( ++p == pe ) + goto _test_eof68; +case 68: + switch( (*p) ) { + case 58: goto st73; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st69; + } else if ( (*p) >= 48 ) + goto st69; + goto st0; +st69: + if ( ++p == pe ) + goto _test_eof69; +case 69: + switch( (*p) ) { + case 58: goto st73; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st70; + } else if ( (*p) >= 48 ) + goto st70; + goto st0; +st70: + if ( ++p == pe ) + goto _test_eof70; +case 70: + switch( (*p) ) { + case 58: goto st73; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st71; + } else if ( (*p) >= 48 ) + goto st71; + goto st0; +st71: + if ( ++p == pe ) + goto _test_eof71; +case 71: + switch( (*p) ) { + case 58: goto st73; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st72; + } else if ( (*p) >= 48 ) + goto st72; + goto st0; +st72: + if ( ++p == pe ) + goto _test_eof72; +case 72: + switch( (*p) ) { + case 58: goto st73; + case 93: goto tr52; + } + goto st0; +st73: + if ( ++p == pe ) + goto _test_eof73; +case 73: + switch( (*p) ) { + case 58: goto st78; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st74; + } else if ( (*p) >= 48 ) + goto st74; + goto st0; +st74: + if ( ++p == pe ) + goto _test_eof74; +case 74: + switch( (*p) ) { + case 58: goto st78; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st75; + } else if ( (*p) >= 48 ) + goto st75; + goto st0; +st75: + if ( ++p == pe ) + goto _test_eof75; +case 75: + switch( (*p) ) { + case 58: goto st78; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st76; + } else if ( (*p) >= 48 ) + goto st76; + goto st0; +st76: + if ( ++p == pe ) + goto _test_eof76; +case 76: + switch( (*p) ) { + case 58: goto st78; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st77; + } else if ( (*p) >= 48 ) + goto st77; + goto st0; +st77: + if ( ++p == pe ) + goto _test_eof77; +case 77: + switch( (*p) ) { + case 58: goto st78; + case 93: goto tr52; + } + goto st0; +st78: + if ( ++p == pe ) + goto _test_eof78; +case 78: + if ( (*p) == 93 ) + goto tr52; + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st79; + } else if ( (*p) >= 48 ) + goto st79; + goto st0; +st79: + if ( ++p == pe ) + goto _test_eof79; +case 79: + if ( (*p) == 93 ) + goto tr52; + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st80; + } else if ( (*p) >= 48 ) + goto st80; + goto st0; +st80: + if ( ++p == pe ) + goto _test_eof80; +case 80: + if ( (*p) == 93 ) + goto tr52; + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st81; + } else if ( (*p) >= 48 ) + goto st81; + goto st0; +st81: + if ( ++p == pe ) + goto _test_eof81; +case 81: + if ( (*p) == 93 ) + goto tr52; + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st82; + } else if ( (*p) >= 48 ) + goto st82; + goto st0; +st82: + if ( ++p == pe ) + goto _test_eof82; +case 82: + if ( (*p) == 93 ) + goto tr52; + goto st0; +tr52: +#line 107 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s; + uri->host_hint = 2; } + goto st173; +st173: + if ( ++p == pe ) + goto _test_eof173; +case 173: +#line 2325 "../../src/uri.c" + switch( (*p) ) { + case 35: goto tr209; + case 47: goto tr210; + case 58: goto st153; + case 63: goto tr212; + } + goto st0; +tr45: +#line 106 "../../src/uri.rl" + { s = p; } + goto st83; +st83: + if ( ++p == pe ) + goto _test_eof83; +case 83: +#line 2341 "../../src/uri.c" + switch( (*p) ) { + case 58: goto st84; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st44; + } else if ( (*p) >= 48 ) + goto st44; + goto st0; +st84: + if ( ++p == pe ) + goto _test_eof84; +case 84: + switch( (*p) ) { + case 58: goto st53; + case 93: goto tr52; + case 102: goto st85; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 101 ) + goto st49; + } else if ( (*p) >= 48 ) + goto st49; + goto st0; +st85: + if ( ++p == pe ) + goto _test_eof85; +case 85: + switch( (*p) ) { + case 58: goto st53; + case 93: goto tr52; + case 102: goto st86; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 101 ) + goto st50; + } else if ( (*p) >= 48 ) + goto st50; + goto st0; +st86: + if ( ++p == pe ) + goto _test_eof86; +case 86: + switch( (*p) ) { + case 58: goto st53; + case 93: goto tr52; + case 102: goto st87; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 101 ) + goto st51; + } else if ( (*p) >= 48 ) + goto st51; + goto st0; +st87: + if ( ++p == pe ) + goto _test_eof87; +case 87: + switch( (*p) ) { + case 58: goto st53; + case 93: goto tr52; + case 102: goto st88; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 101 ) + goto st52; + } else if ( (*p) >= 48 ) + goto st52; + goto st0; +st88: + if ( ++p == pe ) + goto _test_eof88; +case 88: + switch( (*p) ) { + case 58: goto st89; + case 93: goto tr52; + } + goto st0; +st89: + if ( ++p == pe ) + goto _test_eof89; +case 89: + switch( (*p) ) { + case 58: goto st58; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st54; + } else if ( (*p) >= 48 ) + goto st90; + goto st0; +st90: + if ( ++p == pe ) + goto _test_eof90; +case 90: + switch( (*p) ) { + case 46: goto st91; + case 58: goto st58; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st55; + } else if ( (*p) >= 48 ) + goto st102; + goto st0; +st91: + if ( ++p == pe ) + goto _test_eof91; +case 91: + if ( 48 <= (*p) && (*p) <= 57 ) + goto st92; + goto st0; +st92: + if ( ++p == pe ) + goto _test_eof92; +case 92: + if ( (*p) == 46 ) + goto st93; + if ( 48 <= (*p) && (*p) <= 57 ) + goto st100; + goto st0; +st93: + if ( ++p == pe ) + goto _test_eof93; +case 93: + if ( 48 <= (*p) && (*p) <= 57 ) + goto st94; + goto st0; +st94: + if ( ++p == pe ) + goto _test_eof94; +case 94: + if ( (*p) == 46 ) + goto st95; + if ( 48 <= (*p) && (*p) <= 57 ) + goto st98; + goto st0; +st95: + if ( ++p == pe ) + goto _test_eof95; +case 95: + if ( 48 <= (*p) && (*p) <= 57 ) + goto st96; + goto st0; +st96: + if ( ++p == pe ) + goto _test_eof96; +case 96: + if ( (*p) == 93 ) + goto tr52; + if ( 48 <= (*p) && (*p) <= 57 ) + goto st97; + goto st0; +st97: + if ( ++p == pe ) + goto _test_eof97; +case 97: + if ( (*p) == 93 ) + goto tr52; + if ( 48 <= (*p) && (*p) <= 57 ) + goto st82; + goto st0; +st98: + if ( ++p == pe ) + goto _test_eof98; +case 98: + if ( (*p) == 46 ) + goto st95; + if ( 48 <= (*p) && (*p) <= 57 ) + goto st99; + goto st0; +st99: + if ( ++p == pe ) + goto _test_eof99; +case 99: + if ( (*p) == 46 ) + goto st95; + goto st0; +st100: + if ( ++p == pe ) + goto _test_eof100; +case 100: + if ( (*p) == 46 ) + goto st93; + if ( 48 <= (*p) && (*p) <= 57 ) + goto st101; + goto st0; +st101: + if ( ++p == pe ) + goto _test_eof101; +case 101: + if ( (*p) == 46 ) + goto st93; + goto st0; +st102: + if ( ++p == pe ) + goto _test_eof102; +case 102: + switch( (*p) ) { + case 46: goto st91; + case 58: goto st58; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st56; + } else if ( (*p) >= 48 ) + goto st103; + goto st0; +st103: + if ( ++p == pe ) + goto _test_eof103; +case 103: + switch( (*p) ) { + case 46: goto st91; + case 58: goto st58; + case 93: goto tr52; + } + if ( (*p) > 57 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st57; + } else if ( (*p) >= 48 ) + goto st57; + goto st0; +tr33: +#line 92 "../../src/uri.rl" + { s = p; } + goto st174; +st174: + if ( ++p == pe ) + goto _test_eof174; +case 174: +#line 2577 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 47: goto tr161; + case 58: goto tr182; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 110: goto st175; + case 126: goto st152; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st152; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else + goto st152; + goto st0; +st175: + if ( ++p == pe ) + goto _test_eof175; +case 175: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 47: goto tr161; + case 58: goto tr182; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 105: goto st176; + case 126: goto st152; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st152; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else + goto st152; + goto st0; +st176: + if ( ++p == pe ) + goto _test_eof176; +case 176: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 47: goto tr161; + case 58: goto tr182; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 120: goto st177; + case 126: goto st152; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st152; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else + goto st152; + goto st0; +st177: + if ( ++p == pe ) + goto _test_eof177; +case 177: + switch( (*p) ) { + case 33: goto st152; + case 35: goto tr159; + case 37: goto st28; + case 47: goto tr216; + case 58: goto tr182; + case 61: goto st152; + case 63: goto tr163; + case 95: goto st152; + case 126: goto st152; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st152; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st152; + } else + goto st152; + goto st0; +tr216: +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} +#line 161 "../../src/uri.rl" + { s = p; } + goto st178; +st178: + if ( ++p == pe ) + goto _test_eof178; +case 178: +#line 2683 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st148; + case 35: goto tr151; + case 37: goto st11; + case 58: goto st179; + case 61: goto st148; + case 63: goto tr155; + case 95: goto st148; + case 126: goto st148; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st148; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st148; + } else + goto st148; + goto st0; +st179: + if ( ++p == pe ) + goto _test_eof179; +case 179: + switch( (*p) ) { + case 33: goto tr218; + case 35: goto tr151; + case 37: goto tr219; + case 47: goto tr220; + case 58: goto tr221; + case 61: goto tr218; + case 63: goto tr155; + case 95: goto tr218; + case 126: goto tr218; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto tr218; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr218; + } else + goto tr218; + goto st0; +tr218: +#line 128 "../../src/uri.rl" + { s = p;} + goto st180; +st180: + if ( ++p == pe ) + goto _test_eof180; +case 180: +#line 2735 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st180; + case 35: goto tr151; + case 37: goto st104; + case 47: goto st181; + case 58: goto tr223; + case 61: goto st180; + case 63: goto tr155; + case 95: goto st180; + case 126: goto st180; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st180; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st180; + } else + goto st180; + goto st0; +tr219: +#line 128 "../../src/uri.rl" + { s = p;} + goto st104; +st104: + if ( ++p == pe ) + goto _test_eof104; +case 104: +#line 2764 "../../src/uri.c" + switch( (*p) ) { + case 37: goto st180; + case 117: goto st105; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st180; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st180; + } else + goto st180; + goto st0; +st105: + if ( ++p == pe ) + goto _test_eof105; +case 105: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st106; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st106; + } else + goto st106; + goto st0; +st106: + if ( ++p == pe ) + goto _test_eof106; +case 106: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st107; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st107; + } else + goto st107; + goto st0; +st107: + if ( ++p == pe ) + goto _test_eof107; +case 107: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st108; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st108; + } else + goto st108; + goto st0; +st108: + if ( ++p == pe ) + goto _test_eof108; +case 108: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st180; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st180; + } else + goto st180; + goto st0; +tr226: +#line 161 "../../src/uri.rl" + { s = p; } + goto st181; +tr220: +#line 128 "../../src/uri.rl" + { s = p;} + goto st181; +st181: + if ( ++p == pe ) + goto _test_eof181; +case 181: +#line 2842 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st181; + case 35: goto tr151; + case 37: goto st109; + case 58: goto tr225; + case 61: goto st181; + case 63: goto tr155; + case 95: goto st181; + case 126: goto st181; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st181; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st181; + } else + goto st181; + goto st0; +st109: + if ( ++p == pe ) + goto _test_eof109; +case 109: + switch( (*p) ) { + case 37: goto st181; + case 117: goto st110; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st181; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st181; + } else + goto st181; + goto st0; +st110: + if ( ++p == pe ) + goto _test_eof110; +case 110: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st111; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st111; + } else + goto st111; + goto st0; +st111: + if ( ++p == pe ) + goto _test_eof111; +case 111: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st112; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st112; + } else + goto st112; + goto st0; +st112: + if ( ++p == pe ) + goto _test_eof112; +case 112: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st113; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st113; + } else + goto st113; + goto st0; +st113: + if ( ++p == pe ) + goto _test_eof113; +case 113: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st181; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st181; + } else + goto st181; + goto st0; +tr225: +#line 111 "../../src/uri.rl" + { + /* + * This action is also called for path_* terminals. + * I absolute have no idea why. Please don't blame + * and fix grammar if you have a LOT of free time. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } + goto st182; +st182: + if ( ++p == pe ) + goto _test_eof182; +case 182: +#line 2954 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st181; + case 35: goto tr209; + case 37: goto st109; + case 47: goto tr226; + case 58: goto tr225; + case 61: goto st181; + case 63: goto tr212; + case 95: goto st181; + case 126: goto st181; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st181; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st181; + } else + goto st181; + goto st0; +tr223: +#line 111 "../../src/uri.rl" + { + /* + * This action is also called for path_* terminals. + * I absolute have no idea why. Please don't blame + * and fix grammar if you have a LOT of free time. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } + goto st183; +tr221: +#line 128 "../../src/uri.rl" + { s = p;} +#line 111 "../../src/uri.rl" + { + /* + * This action is also called for path_* terminals. + * I absolute have no idea why. Please don't blame + * and fix grammar if you have a LOT of free time. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } + goto st183; +st183: + if ( ++p == pe ) + goto _test_eof183; +case 183: +#line 3019 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st148; + case 35: goto tr209; + case 37: goto st11; + case 47: goto tr210; + case 61: goto st148; + case 63: goto tr212; + case 95: goto st148; + case 126: goto st148; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st148; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st148; + } else + goto st148; + goto st0; +tr178: +#line 141 "../../src/uri.rl" + { s = p; } +#line 131 "../../src/uri.rl" + { s = p; } + goto st184; +st184: + if ( ++p == pe ) + goto _test_eof184; +case 184: +#line 3049 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st21; + case 35: goto tr185; + case 37: goto st22; + case 47: goto tr186; + case 59: goto st21; + case 61: goto st21; + case 63: goto tr188; + case 64: goto tr23; + case 95: goto st21; + case 126: goto st21; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st21; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st21; + } else if ( (*p) >= 65 ) + goto st21; + } else + goto st184; + goto st0; +tr180: +#line 141 "../../src/uri.rl" + { s = p; } +#line 131 "../../src/uri.rl" + { s = p; } + goto st185; +st185: + if ( ++p == pe ) + goto _test_eof185; +case 185: +#line 3084 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st21; + case 35: goto tr185; + case 37: goto st22; + case 47: goto tr186; + case 59: goto st21; + case 61: goto st21; + case 63: goto tr188; + case 64: goto tr23; + case 95: goto st21; + case 126: goto st21; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 57 ) + goto st21; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st185; + } else + goto st185; + goto st0; +tr153: +#line 182 "../../src/uri.rl" + { s = p; } + goto st186; +st186: + if ( ++p == pe ) + goto _test_eof186; +case 186: +#line 3114 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st187; + case 35: goto tr151; + case 37: goto st114; + case 61: goto st187; + case 63: goto tr155; + case 95: goto st187; + case 126: goto st187; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st187; + } else if ( (*p) > 59 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st187; + } else if ( (*p) >= 64 ) + goto st187; + } else + goto st187; + goto st0; +st187: + if ( ++p == pe ) + goto _test_eof187; +case 187: + switch( (*p) ) { + case 33: goto st187; + case 35: goto tr151; + case 37: goto st114; + case 61: goto st187; + case 63: goto tr155; + case 95: goto st187; + case 126: goto st187; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st187; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st187; + } else + goto st187; + goto st0; +st114: + if ( ++p == pe ) + goto _test_eof114; +case 114: + switch( (*p) ) { + case 37: goto st187; + case 117: goto st115; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st187; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st187; + } else + goto st187; + goto st0; +st115: + if ( ++p == pe ) + goto _test_eof115; +case 115: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st116; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st116; + } else + goto st116; + goto st0; +st116: + if ( ++p == pe ) + goto _test_eof116; +case 116: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st117; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st117; + } else + goto st117; + goto st0; +st117: + if ( ++p == pe ) + goto _test_eof117; +case 117: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st118; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st118; + } else + goto st118; + goto st0; +st118: + if ( ++p == pe ) + goto _test_eof118; +case 118: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st187; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st187; + } else + goto st187; + goto st0; +tr154: +#line 137 "../../src/uri.rl" + { s = p; } +#line 99 "../../src/uri.rl" + { s = p; } +#line 92 "../../src/uri.rl" + { s = p; } +#line 178 "../../src/uri.rl" + { uri->service = p; } + goto st188; +st188: + if ( ++p == pe ) + goto _test_eof188; +case 188: +#line 3241 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 46: goto st189; + case 47: goto tr161; + case 58: goto tr162; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else if ( (*p) >= 65 ) + goto st145; + } else + goto st201; + goto st0; +st189: + if ( ++p == pe ) + goto _test_eof189; +case 189: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 47: goto tr161; + case 58: goto tr162; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else if ( (*p) >= 65 ) + goto st145; + } else + goto st190; + goto st0; +st190: + if ( ++p == pe ) + goto _test_eof190; +case 190: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 46: goto st191; + case 47: goto tr161; + case 58: goto tr162; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else if ( (*p) >= 65 ) + goto st145; + } else + goto st199; + goto st0; +st191: + if ( ++p == pe ) + goto _test_eof191; +case 191: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 47: goto tr161; + case 58: goto tr162; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else if ( (*p) >= 65 ) + goto st145; + } else + goto st192; + goto st0; +st192: + if ( ++p == pe ) + goto _test_eof192; +case 192: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 46: goto st193; + case 47: goto tr161; + case 58: goto tr162; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else if ( (*p) >= 65 ) + goto st145; + } else + goto st197; + goto st0; +st193: + if ( ++p == pe ) + goto _test_eof193; +case 193: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 47: goto tr161; + case 58: goto tr162; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else if ( (*p) >= 65 ) + goto st145; + } else + goto st194; + goto st0; +st194: + if ( ++p == pe ) + goto _test_eof194; +case 194: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr200; + case 37: goto st6; + case 47: goto tr201; + case 58: goto tr240; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr204; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else if ( (*p) >= 65 ) + goto st145; + } else + goto st195; + goto st0; +st195: + if ( ++p == pe ) + goto _test_eof195; +case 195: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr200; + case 37: goto st6; + case 47: goto tr201; + case 58: goto tr240; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr204; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else if ( (*p) >= 65 ) + goto st145; + } else + goto st196; + goto st0; +st196: + if ( ++p == pe ) + goto _test_eof196; +case 196: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr200; + case 37: goto st6; + case 47: goto tr201; + case 58: goto tr240; + case 61: goto st145; + case 63: goto tr204; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st145; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else + goto st145; + goto st0; +st197: + if ( ++p == pe ) + goto _test_eof197; +case 197: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 46: goto st193; + case 47: goto tr161; + case 58: goto tr162; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else if ( (*p) >= 65 ) + goto st145; + } else + goto st198; + goto st0; +st198: + if ( ++p == pe ) + goto _test_eof198; +case 198: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 46: goto st193; + case 47: goto tr161; + case 58: goto tr162; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st145; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else + goto st145; + goto st0; +st199: + if ( ++p == pe ) + goto _test_eof199; +case 199: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 46: goto st191; + case 47: goto tr161; + case 58: goto tr162; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else if ( (*p) >= 65 ) + goto st145; + } else + goto st200; + goto st0; +st200: + if ( ++p == pe ) + goto _test_eof200; +case 200: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 46: goto st191; + case 47: goto tr161; + case 58: goto tr162; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st145; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else + goto st145; + goto st0; +st201: + if ( ++p == pe ) + goto _test_eof201; +case 201: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 46: goto st189; + case 47: goto tr161; + case 58: goto tr162; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else if ( (*p) >= 65 ) + goto st145; + } else + goto st202; + goto st0; +st202: + if ( ++p == pe ) + goto _test_eof202; +case 202: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 46: goto st189; + case 47: goto tr161; + case 58: goto tr162; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else if ( (*p) >= 65 ) + goto st145; + } else + goto st203; + goto st0; +st203: + if ( ++p == pe ) + goto _test_eof203; +case 203: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 47: goto tr161; + case 58: goto tr162; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st145; + } else if ( (*p) >= 65 ) + goto st145; + } else + goto st203; + goto st0; +st204: + if ( ++p == pe ) + goto _test_eof204; +case 204: + switch( (*p) ) { + case 35: goto tr151; + case 47: goto st148; + case 63: goto tr155; + } + goto st0; +tr157: +#line 151 "../../src/uri.rl" + { s = p; } +#line 137 "../../src/uri.rl" + { s = p; } +#line 92 "../../src/uri.rl" + { s = p; } + goto st205; +st205: + if ( ++p == pe ) + goto _test_eof205; +case 205: +#line 3721 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 43: goto st205; + case 47: goto tr161; + case 58: goto tr247; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 45 ) { + if ( 36 <= (*p) && (*p) <= 44 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st205; + } else if ( (*p) >= 65 ) + goto st205; + } else + goto st205; + goto st0; +tr247: +#line 153 "../../src/uri.rl" + {scheme = s; scheme_len = p - s; } +#line 138 "../../src/uri.rl" + { login = s; login_len = p - s; } +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} + goto st206; +st206: + if ( ++p == pe ) + goto _test_eof206; +case 206: +#line 3760 "../../src/uri.c" + switch( (*p) ) { + case 33: goto tr174; + case 35: goto tr175; + case 37: goto tr176; + case 47: goto tr248; + case 59: goto tr174; + case 61: goto tr174; + case 63: goto tr179; + case 95: goto tr174; + case 126: goto tr174; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto tr174; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr180; + } else if ( (*p) >= 65 ) + goto tr180; + } else + goto tr178; + goto st0; +tr248: +#line 169 "../../src/uri.rl" + { uri->scheme = scheme; uri->scheme_len = scheme_len;} +#line 131 "../../src/uri.rl" + { s = p; } +#line 132 "../../src/uri.rl" + { uri->service = s; uri->service_len = p - s; } +#line 161 "../../src/uri.rl" + { s = p; } + goto st207; +st207: + if ( ++p == pe ) + goto _test_eof207; +case 207: +#line 3798 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st148; + case 35: goto tr151; + case 37: goto st11; + case 47: goto st208; + case 61: goto st148; + case 63: goto tr155; + case 95: goto st148; + case 126: goto st148; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st148; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st148; + } else + goto st148; + goto st0; +st208: + if ( ++p == pe ) + goto _test_eof208; +case 208: + switch( (*p) ) { + case 33: goto tr250; + case 35: goto tr151; + case 37: goto tr251; + case 47: goto st148; + case 58: goto st148; + case 59: goto tr250; + case 61: goto tr250; + case 63: goto tr155; + case 64: goto st148; + case 91: goto st38; + case 95: goto tr250; + case 117: goto tr253; + case 126: goto tr250; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto tr250; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr250; + } else if ( (*p) >= 65 ) + goto tr250; + } else + goto tr252; + goto st0; +tr250: +#line 137 "../../src/uri.rl" + { s = p; } +#line 92 "../../src/uri.rl" + { s = p; } + goto st209; +st209: + if ( ++p == pe ) + goto _test_eof209; +case 209: +#line 3859 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 47: goto tr161; + case 58: goto tr255; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st209; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else + goto st209; + goto st0; +tr251: +#line 137 "../../src/uri.rl" + { s = p; } +#line 92 "../../src/uri.rl" + { s = p; } + goto st119; +st119: + if ( ++p == pe ) + goto _test_eof119; +case 119: +#line 3891 "../../src/uri.c" + switch( (*p) ) { + case 37: goto st209; + case 117: goto st120; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st209; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st209; + } else + goto st209; + goto st0; +st120: + if ( ++p == pe ) + goto _test_eof120; +case 120: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st121; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st121; + } else + goto st121; + goto st0; +st121: + if ( ++p == pe ) + goto _test_eof121; +case 121: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st122; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st122; + } else + goto st122; + goto st0; +st122: + if ( ++p == pe ) + goto _test_eof122; +case 122: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st123; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st123; + } else + goto st123; + goto st0; +st123: + if ( ++p == pe ) + goto _test_eof123; +case 123: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st209; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st209; + } else + goto st209; + goto st0; +tr255: +#line 138 "../../src/uri.rl" + { login = s; login_len = p - s; } +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} + goto st210; +tr303: +#line 138 "../../src/uri.rl" + { login = s; login_len = p - s; } +#line 100 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s; + uri->host_hint = 1; } +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} + goto st210; +st210: + if ( ++p == pe ) + goto _test_eof210; +case 210: +#line 3976 "../../src/uri.c" + switch( (*p) ) { + case 33: goto tr257; + case 35: goto tr175; + case 37: goto tr258; + case 47: goto tr177; + case 58: goto st148; + case 59: goto tr257; + case 61: goto tr257; + case 63: goto tr179; + case 64: goto st148; + case 95: goto tr257; + case 126: goto tr257; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto tr257; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr260; + } else if ( (*p) >= 65 ) + goto tr260; + } else + goto tr259; + goto st0; +tr257: +#line 141 "../../src/uri.rl" + { s = p; } + goto st211; +st211: + if ( ++p == pe ) + goto _test_eof211; +case 211: +#line 4010 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st211; + case 35: goto tr151; + case 37: goto st124; + case 47: goto st148; + case 58: goto st148; + case 61: goto st211; + case 63: goto tr155; + case 64: goto tr262; + case 95: goto st211; + case 126: goto st211; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st211; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st211; + } else + goto st211; + goto st0; +tr258: +#line 141 "../../src/uri.rl" + { s = p; } + goto st124; +st124: + if ( ++p == pe ) + goto _test_eof124; +case 124: +#line 4040 "../../src/uri.c" + switch( (*p) ) { + case 37: goto st211; + case 117: goto st125; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st211; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st211; + } else + goto st211; + goto st0; +st125: + if ( ++p == pe ) + goto _test_eof125; +case 125: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st126; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st126; + } else + goto st126; + goto st0; +st126: + if ( ++p == pe ) + goto _test_eof126; +case 126: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st127; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st127; + } else + goto st127; + goto st0; +st127: + if ( ++p == pe ) + goto _test_eof127; +case 127: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st128; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st128; + } else + goto st128; + goto st0; +st128: + if ( ++p == pe ) + goto _test_eof128; +case 128: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st211; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st211; + } else + goto st211; + goto st0; +tr262: +#line 142 "../../src/uri.rl" + { uri->password = s; uri->password_len = p - s; } +#line 146 "../../src/uri.rl" + { uri->login = login; uri->login_len = login_len; } + goto st212; +tr256: +#line 138 "../../src/uri.rl" + { login = s; login_len = p - s; } +#line 146 "../../src/uri.rl" + { uri->login = login; uri->login_len = login_len; } + goto st212; +st212: + if ( ++p == pe ) + goto _test_eof212; +case 212: +#line 4122 "../../src/uri.c" + switch( (*p) ) { + case 33: goto tr263; + case 35: goto tr151; + case 37: goto tr264; + case 47: goto st148; + case 58: goto st148; + case 59: goto tr263; + case 61: goto tr263; + case 63: goto tr155; + case 64: goto st148; + case 91: goto st38; + case 95: goto tr263; + case 117: goto tr266; + case 126: goto tr263; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto tr263; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr263; + } else if ( (*p) >= 65 ) + goto tr263; + } else + goto tr265; + goto st0; +tr263: +#line 92 "../../src/uri.rl" + { s = p; } + goto st213; +st213: + if ( ++p == pe ) + goto _test_eof213; +case 213: +#line 4158 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 47: goto tr161; + case 58: goto tr268; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st213; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else + goto st213; + goto st0; +tr264: +#line 92 "../../src/uri.rl" + { s = p; } + goto st129; +st129: + if ( ++p == pe ) + goto _test_eof129; +case 129: +#line 4188 "../../src/uri.c" + switch( (*p) ) { + case 37: goto st213; + case 117: goto st130; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st213; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st213; + } else + goto st213; + goto st0; +st130: + if ( ++p == pe ) + goto _test_eof130; +case 130: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st131; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st131; + } else + goto st131; + goto st0; +st131: + if ( ++p == pe ) + goto _test_eof131; +case 131: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st132; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st132; + } else + goto st132; + goto st0; +st132: + if ( ++p == pe ) + goto _test_eof132; +case 132: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st133; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st133; + } else + goto st133; + goto st0; +st133: + if ( ++p == pe ) + goto _test_eof133; +case 133: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st213; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st213; + } else + goto st213; + goto st0; +tr268: +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} + goto st214; +tr283: +#line 100 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s; + uri->host_hint = 1; } +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} + goto st214; +st214: + if ( ++p == pe ) + goto _test_eof214; +case 214: +#line 4269 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st148; + case 35: goto tr175; + case 37: goto st11; + case 47: goto tr177; + case 61: goto st148; + case 63: goto tr179; + case 64: goto st148; + case 95: goto st148; + case 126: goto st148; + } + if ( (*p) < 58 ) { + if ( (*p) > 46 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr269; + } else if ( (*p) >= 36 ) + goto st148; + } else if ( (*p) > 59 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr270; + } else if ( (*p) >= 65 ) + goto tr270; + } else + goto st148; + goto st0; +tr269: +#line 131 "../../src/uri.rl" + { s = p; } + goto st215; +st215: + if ( ++p == pe ) + goto _test_eof215; +case 215: +#line 4304 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st148; + case 35: goto tr185; + case 37: goto st11; + case 47: goto tr186; + case 61: goto st148; + case 63: goto tr188; + case 95: goto st148; + case 126: goto st148; + } + if ( (*p) < 58 ) { + if ( (*p) > 46 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st215; + } else if ( (*p) >= 36 ) + goto st148; + } else if ( (*p) > 59 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st148; + } else if ( (*p) >= 64 ) + goto st148; + } else + goto st148; + goto st0; +tr270: +#line 131 "../../src/uri.rl" + { s = p; } + goto st216; +st216: + if ( ++p == pe ) + goto _test_eof216; +case 216: +#line 4338 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st148; + case 35: goto tr185; + case 37: goto st11; + case 47: goto tr186; + case 61: goto st148; + case 63: goto tr188; + case 64: goto st148; + case 95: goto st148; + case 126: goto st148; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st148; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st216; + } else + goto st216; + goto st0; +tr265: +#line 99 "../../src/uri.rl" + { s = p; } +#line 92 "../../src/uri.rl" + { s = p; } + goto st217; +st217: + if ( ++p == pe ) + goto _test_eof217; +case 217: +#line 4369 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 46: goto st218; + case 47: goto tr161; + case 58: goto tr268; + case 59: goto st213; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st213; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else if ( (*p) >= 65 ) + goto st213; + } else + goto st230; + goto st0; +st218: + if ( ++p == pe ) + goto _test_eof218; +case 218: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 47: goto tr161; + case 58: goto tr268; + case 59: goto st213; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st213; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else if ( (*p) >= 65 ) + goto st213; + } else + goto st219; + goto st0; +st219: + if ( ++p == pe ) + goto _test_eof219; +case 219: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 46: goto st220; + case 47: goto tr161; + case 58: goto tr268; + case 59: goto st213; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st213; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else if ( (*p) >= 65 ) + goto st213; + } else + goto st228; + goto st0; +st220: + if ( ++p == pe ) + goto _test_eof220; +case 220: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 47: goto tr161; + case 58: goto tr268; + case 59: goto st213; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st213; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else if ( (*p) >= 65 ) + goto st213; + } else + goto st221; + goto st0; +st221: + if ( ++p == pe ) + goto _test_eof221; +case 221: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 46: goto st222; + case 47: goto tr161; + case 58: goto tr268; + case 59: goto st213; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st213; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else if ( (*p) >= 65 ) + goto st213; + } else + goto st226; + goto st0; +st222: + if ( ++p == pe ) + goto _test_eof222; +case 222: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 47: goto tr161; + case 58: goto tr268; + case 59: goto st213; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st213; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else if ( (*p) >= 65 ) + goto st213; + } else + goto st223; + goto st0; +st223: + if ( ++p == pe ) + goto _test_eof223; +case 223: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr200; + case 37: goto st129; + case 47: goto tr201; + case 58: goto tr283; + case 59: goto st213; + case 61: goto st213; + case 63: goto tr204; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st213; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else if ( (*p) >= 65 ) + goto st213; + } else + goto st224; + goto st0; +st224: + if ( ++p == pe ) + goto _test_eof224; +case 224: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr200; + case 37: goto st129; + case 47: goto tr201; + case 58: goto tr283; + case 59: goto st213; + case 61: goto st213; + case 63: goto tr204; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st213; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else if ( (*p) >= 65 ) + goto st213; + } else + goto st225; + goto st0; +st225: + if ( ++p == pe ) + goto _test_eof225; +case 225: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr200; + case 37: goto st129; + case 47: goto tr201; + case 58: goto tr283; + case 61: goto st213; + case 63: goto tr204; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st213; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else + goto st213; + goto st0; +st226: + if ( ++p == pe ) + goto _test_eof226; +case 226: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 46: goto st222; + case 47: goto tr161; + case 58: goto tr268; + case 59: goto st213; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st213; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else if ( (*p) >= 65 ) + goto st213; + } else + goto st227; + goto st0; +st227: + if ( ++p == pe ) + goto _test_eof227; +case 227: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 46: goto st222; + case 47: goto tr161; + case 58: goto tr268; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st213; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else + goto st213; + goto st0; +st228: + if ( ++p == pe ) + goto _test_eof228; +case 228: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 46: goto st220; + case 47: goto tr161; + case 58: goto tr268; + case 59: goto st213; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st213; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else if ( (*p) >= 65 ) + goto st213; + } else + goto st229; + goto st0; +st229: + if ( ++p == pe ) + goto _test_eof229; +case 229: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 46: goto st220; + case 47: goto tr161; + case 58: goto tr268; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st213; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else + goto st213; + goto st0; +st230: + if ( ++p == pe ) + goto _test_eof230; +case 230: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 46: goto st218; + case 47: goto tr161; + case 58: goto tr268; + case 59: goto st213; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st213; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else if ( (*p) >= 65 ) + goto st213; + } else + goto st231; + goto st0; +st231: + if ( ++p == pe ) + goto _test_eof231; +case 231: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 46: goto st218; + case 47: goto tr161; + case 58: goto tr268; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st213; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else + goto st213; + goto st0; +tr266: +#line 92 "../../src/uri.rl" + { s = p; } + goto st232; +st232: + if ( ++p == pe ) + goto _test_eof232; +case 232: +#line 4802 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 47: goto tr161; + case 58: goto tr268; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 110: goto st233; + case 126: goto st213; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st213; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else + goto st213; + goto st0; +st233: + if ( ++p == pe ) + goto _test_eof233; +case 233: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 47: goto tr161; + case 58: goto tr268; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 105: goto st234; + case 126: goto st213; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st213; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else + goto st213; + goto st0; +st234: + if ( ++p == pe ) + goto _test_eof234; +case 234: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 47: goto tr161; + case 58: goto tr268; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 120: goto st235; + case 126: goto st213; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st213; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else + goto st213; + goto st0; +st235: + if ( ++p == pe ) + goto _test_eof235; +case 235: + switch( (*p) ) { + case 33: goto st213; + case 35: goto tr159; + case 37: goto st129; + case 47: goto tr216; + case 58: goto tr268; + case 61: goto st213; + case 63: goto tr163; + case 64: goto st148; + case 95: goto st213; + case 126: goto st213; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st213; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st213; + } else + goto st213; + goto st0; +tr259: +#line 141 "../../src/uri.rl" + { s = p; } +#line 131 "../../src/uri.rl" + { s = p; } + goto st236; +st236: + if ( ++p == pe ) + goto _test_eof236; +case 236: +#line 4912 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st211; + case 35: goto tr185; + case 37: goto st124; + case 47: goto tr186; + case 58: goto st148; + case 59: goto st211; + case 61: goto st211; + case 63: goto tr188; + case 64: goto tr262; + case 95: goto st211; + case 126: goto st211; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st211; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st211; + } else if ( (*p) >= 65 ) + goto st211; + } else + goto st236; + goto st0; +tr260: +#line 141 "../../src/uri.rl" + { s = p; } +#line 131 "../../src/uri.rl" + { s = p; } + goto st237; +st237: + if ( ++p == pe ) + goto _test_eof237; +case 237: +#line 4948 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st211; + case 35: goto tr185; + case 37: goto st124; + case 47: goto tr186; + case 58: goto st148; + case 61: goto st211; + case 63: goto tr188; + case 64: goto tr262; + case 95: goto st211; + case 126: goto st211; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st211; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st237; + } else + goto st237; + goto st0; +tr252: +#line 137 "../../src/uri.rl" + { s = p; } +#line 99 "../../src/uri.rl" + { s = p; } +#line 92 "../../src/uri.rl" + { s = p; } + goto st238; +st238: + if ( ++p == pe ) + goto _test_eof238; +case 238: +#line 4982 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 46: goto st239; + case 47: goto tr161; + case 58: goto tr255; + case 59: goto st209; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st209; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else if ( (*p) >= 65 ) + goto st209; + } else + goto st251; + goto st0; +st239: + if ( ++p == pe ) + goto _test_eof239; +case 239: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 47: goto tr161; + case 58: goto tr255; + case 59: goto st209; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st209; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else if ( (*p) >= 65 ) + goto st209; + } else + goto st240; + goto st0; +st240: + if ( ++p == pe ) + goto _test_eof240; +case 240: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 46: goto st241; + case 47: goto tr161; + case 58: goto tr255; + case 59: goto st209; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st209; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else if ( (*p) >= 65 ) + goto st209; + } else + goto st249; + goto st0; +st241: + if ( ++p == pe ) + goto _test_eof241; +case 241: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 47: goto tr161; + case 58: goto tr255; + case 59: goto st209; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st209; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else if ( (*p) >= 65 ) + goto st209; + } else + goto st242; + goto st0; +st242: + if ( ++p == pe ) + goto _test_eof242; +case 242: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 46: goto st243; + case 47: goto tr161; + case 58: goto tr255; + case 59: goto st209; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st209; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else if ( (*p) >= 65 ) + goto st209; + } else + goto st247; + goto st0; +st243: + if ( ++p == pe ) + goto _test_eof243; +case 243: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 47: goto tr161; + case 58: goto tr255; + case 59: goto st209; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st209; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else if ( (*p) >= 65 ) + goto st209; + } else + goto st244; + goto st0; +st244: + if ( ++p == pe ) + goto _test_eof244; +case 244: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr200; + case 37: goto st119; + case 47: goto tr201; + case 58: goto tr303; + case 59: goto st209; + case 61: goto st209; + case 63: goto tr204; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st209; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else if ( (*p) >= 65 ) + goto st209; + } else + goto st245; + goto st0; +st245: + if ( ++p == pe ) + goto _test_eof245; +case 245: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr200; + case 37: goto st119; + case 47: goto tr201; + case 58: goto tr303; + case 59: goto st209; + case 61: goto st209; + case 63: goto tr204; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 46 ) + goto st209; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else if ( (*p) >= 65 ) + goto st209; + } else + goto st246; + goto st0; +st246: + if ( ++p == pe ) + goto _test_eof246; +case 246: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr200; + case 37: goto st119; + case 47: goto tr201; + case 58: goto tr303; + case 61: goto st209; + case 63: goto tr204; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st209; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else + goto st209; + goto st0; +st247: + if ( ++p == pe ) + goto _test_eof247; +case 247: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 46: goto st243; + case 47: goto tr161; + case 58: goto tr255; + case 59: goto st209; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st209; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else if ( (*p) >= 65 ) + goto st209; + } else + goto st248; + goto st0; +st248: + if ( ++p == pe ) + goto _test_eof248; +case 248: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 46: goto st243; + case 47: goto tr161; + case 58: goto tr255; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st209; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else + goto st209; + goto st0; +st249: + if ( ++p == pe ) + goto _test_eof249; +case 249: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 46: goto st241; + case 47: goto tr161; + case 58: goto tr255; + case 59: goto st209; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st209; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else if ( (*p) >= 65 ) + goto st209; + } else + goto st250; + goto st0; +st250: + if ( ++p == pe ) + goto _test_eof250; +case 250: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 46: goto st241; + case 47: goto tr161; + case 58: goto tr255; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st209; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else + goto st209; + goto st0; +st251: + if ( ++p == pe ) + goto _test_eof251; +case 251: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 46: goto st239; + case 47: goto tr161; + case 58: goto tr255; + case 59: goto st209; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 48 ) { + if ( 36 <= (*p) && (*p) <= 45 ) + goto st209; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else if ( (*p) >= 65 ) + goto st209; + } else + goto st252; + goto st0; +st252: + if ( ++p == pe ) + goto _test_eof252; +case 252: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 46: goto st239; + case 47: goto tr161; + case 58: goto tr255; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st209; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else + goto st209; + goto st0; +tr253: +#line 137 "../../src/uri.rl" + { s = p; } +#line 92 "../../src/uri.rl" + { s = p; } + goto st253; +st253: + if ( ++p == pe ) + goto _test_eof253; +case 253: +#line 5417 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 47: goto tr161; + case 58: goto tr255; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 110: goto st254; + case 126: goto st209; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st209; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else + goto st209; + goto st0; +st254: + if ( ++p == pe ) + goto _test_eof254; +case 254: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 47: goto tr161; + case 58: goto tr255; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 105: goto st255; + case 126: goto st209; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st209; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else + goto st209; + goto st0; +st255: + if ( ++p == pe ) + goto _test_eof255; +case 255: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 47: goto tr161; + case 58: goto tr255; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 120: goto st256; + case 126: goto st209; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st209; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else + goto st209; + goto st0; +st256: + if ( ++p == pe ) + goto _test_eof256; +case 256: + switch( (*p) ) { + case 33: goto st209; + case 35: goto tr159; + case 37: goto st119; + case 47: goto tr311; + case 58: goto tr255; + case 61: goto st209; + case 63: goto tr163; + case 64: goto tr256; + case 95: goto st209; + case 126: goto st209; + } + if ( (*p) < 65 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st209; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st209; + } else + goto st209; + goto st0; +tr311: +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} +#line 161 "../../src/uri.rl" + { s = p; } + goto st257; +st257: + if ( ++p == pe ) + goto _test_eof257; +case 257: +#line 5527 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st148; + case 35: goto tr151; + case 37: goto st11; + case 58: goto st258; + case 61: goto st148; + case 63: goto tr155; + case 95: goto st148; + case 126: goto st148; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st148; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st148; + } else + goto st148; + goto st0; +st258: + if ( ++p == pe ) + goto _test_eof258; +case 258: + switch( (*p) ) { + case 33: goto tr313; + case 35: goto tr314; + case 37: goto tr315; + case 47: goto tr316; + case 58: goto tr221; + case 61: goto tr313; + case 63: goto tr317; + case 95: goto tr313; + case 126: goto tr313; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto tr313; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr313; + } else + goto tr313; + goto st0; +tr313: +#line 128 "../../src/uri.rl" + { s = p;} + goto st259; +st259: + if ( ++p == pe ) + goto _test_eof259; +case 259: +#line 5579 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st259; + case 35: goto tr318; + case 37: goto st134; + case 47: goto st260; + case 58: goto tr223; + case 61: goto st259; + case 63: goto tr320; + case 95: goto st259; + case 126: goto st259; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st259; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st259; + } else + goto st259; + goto st0; +tr315: +#line 128 "../../src/uri.rl" + { s = p;} + goto st134; +st134: + if ( ++p == pe ) + goto _test_eof134; +case 134: +#line 5608 "../../src/uri.c" + switch( (*p) ) { + case 37: goto st259; + case 117: goto st135; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st259; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st259; + } else + goto st259; + goto st0; +st135: + if ( ++p == pe ) + goto _test_eof135; +case 135: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st136; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st136; + } else + goto st136; + goto st0; +st136: + if ( ++p == pe ) + goto _test_eof136; +case 136: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st137; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st137; + } else + goto st137; + goto st0; +st137: + if ( ++p == pe ) + goto _test_eof137; +case 137: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st138; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st138; + } else + goto st138; + goto st0; +st138: + if ( ++p == pe ) + goto _test_eof138; +case 138: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st259; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st259; + } else + goto st259; + goto st0; +tr324: +#line 161 "../../src/uri.rl" + { s = p; } + goto st260; +tr316: +#line 128 "../../src/uri.rl" + { s = p;} + goto st260; +st260: + if ( ++p == pe ) + goto _test_eof260; +case 260: +#line 5686 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st260; + case 35: goto tr318; + case 37: goto st139; + case 58: goto tr322; + case 61: goto st260; + case 63: goto tr320; + case 95: goto st260; + case 126: goto st260; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st260; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st260; + } else + goto st260; + goto st0; +st139: + if ( ++p == pe ) + goto _test_eof139; +case 139: + switch( (*p) ) { + case 37: goto st260; + case 117: goto st140; + } + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st260; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st260; + } else + goto st260; + goto st0; +st140: + if ( ++p == pe ) + goto _test_eof140; +case 140: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st141; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st141; + } else + goto st141; + goto st0; +st141: + if ( ++p == pe ) + goto _test_eof141; +case 141: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st142; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st142; + } else + goto st142; + goto st0; +st142: + if ( ++p == pe ) + goto _test_eof142; +case 142: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st143; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st143; + } else + goto st143; + goto st0; +st143: + if ( ++p == pe ) + goto _test_eof143; +case 143: + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st260; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st260; + } else + goto st260; + goto st0; +tr322: +#line 111 "../../src/uri.rl" + { + /* + * This action is also called for path_* terminals. + * I absolute have no idea why. Please don't blame + * and fix grammar if you have a LOT of free time. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } + goto st261; +st261: + if ( ++p == pe ) + goto _test_eof261; +case 261: +#line 5798 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st260; + case 35: goto tr323; + case 37: goto st139; + case 47: goto tr324; + case 58: goto tr322; + case 61: goto st260; + case 63: goto tr325; + case 95: goto st260; + case 126: goto st260; + } + if ( (*p) < 64 ) { + if ( 36 <= (*p) && (*p) <= 59 ) + goto st260; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st260; + } else + goto st260; + goto st0; +tr158: +#line 151 "../../src/uri.rl" + { s = p; } +#line 137 "../../src/uri.rl" + { s = p; } +#line 92 "../../src/uri.rl" + { s = p; } + goto st262; +st262: + if ( ++p == pe ) + goto _test_eof262; +case 262: +#line 5831 "../../src/uri.c" + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 43: goto st205; + case 47: goto tr161; + case 58: goto tr247; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 110: goto st263; + case 126: goto st145; + } + if ( (*p) < 45 ) { + if ( 36 <= (*p) && (*p) <= 44 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st205; + } else if ( (*p) >= 65 ) + goto st205; + } else + goto st205; + goto st0; +st263: + if ( ++p == pe ) + goto _test_eof263; +case 263: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 43: goto st205; + case 47: goto tr161; + case 58: goto tr247; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 105: goto st264; + case 126: goto st145; + } + if ( (*p) < 45 ) { + if ( 36 <= (*p) && (*p) <= 44 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st205; + } else if ( (*p) >= 65 ) + goto st205; + } else + goto st205; + goto st0; +st264: + if ( ++p == pe ) + goto _test_eof264; +case 264: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 43: goto st205; + case 47: goto tr161; + case 58: goto tr247; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 120: goto st265; + case 126: goto st145; + } + if ( (*p) < 45 ) { + if ( 36 <= (*p) && (*p) <= 44 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st205; + } else if ( (*p) >= 65 ) + goto st205; + } else + goto st205; + goto st0; +st265: + if ( ++p == pe ) + goto _test_eof265; +case 265: + switch( (*p) ) { + case 33: goto st145; + case 35: goto tr159; + case 37: goto st6; + case 43: goto st205; + case 47: goto tr311; + case 58: goto tr247; + case 59: goto st145; + case 61: goto st145; + case 63: goto tr163; + case 64: goto tr164; + case 95: goto st145; + case 126: goto st145; + } + if ( (*p) < 45 ) { + if ( 36 <= (*p) && (*p) <= 44 ) + goto st145; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st205; + } else if ( (*p) >= 65 ) + goto st205; + } else + goto st205; + goto st0; + } + _test_eof145: cs = 145; goto _test_eof; + _test_eof146: cs = 146; goto _test_eof; + _test_eof147: cs = 147; goto _test_eof; + _test_eof1: cs = 1; goto _test_eof; + _test_eof2: cs = 2; goto _test_eof; + _test_eof3: cs = 3; goto _test_eof; + _test_eof4: cs = 4; goto _test_eof; + _test_eof5: cs = 5; goto _test_eof; + _test_eof6: cs = 6; goto _test_eof; + _test_eof7: cs = 7; goto _test_eof; + _test_eof8: cs = 8; goto _test_eof; + _test_eof9: cs = 9; goto _test_eof; + _test_eof10: cs = 10; goto _test_eof; + _test_eof148: cs = 148; goto _test_eof; + _test_eof11: cs = 11; goto _test_eof; + _test_eof12: cs = 12; goto _test_eof; + _test_eof13: cs = 13; goto _test_eof; + _test_eof14: cs = 14; goto _test_eof; + _test_eof15: cs = 15; goto _test_eof; + _test_eof149: cs = 149; goto _test_eof; + _test_eof150: cs = 150; goto _test_eof; + _test_eof16: cs = 16; goto _test_eof; + _test_eof17: cs = 17; goto _test_eof; + _test_eof18: cs = 18; goto _test_eof; + _test_eof19: cs = 19; goto _test_eof; + _test_eof20: cs = 20; goto _test_eof; + _test_eof151: cs = 151; goto _test_eof; + _test_eof21: cs = 21; goto _test_eof; + _test_eof22: cs = 22; goto _test_eof; + _test_eof23: cs = 23; goto _test_eof; + _test_eof24: cs = 24; goto _test_eof; + _test_eof25: cs = 25; goto _test_eof; + _test_eof26: cs = 26; goto _test_eof; + _test_eof27: cs = 27; goto _test_eof; + _test_eof152: cs = 152; goto _test_eof; + _test_eof28: cs = 28; goto _test_eof; + _test_eof29: cs = 29; goto _test_eof; + _test_eof30: cs = 30; goto _test_eof; + _test_eof31: cs = 31; goto _test_eof; + _test_eof32: cs = 32; goto _test_eof; + _test_eof153: cs = 153; goto _test_eof; + _test_eof154: cs = 154; goto _test_eof; + _test_eof155: cs = 155; goto _test_eof; + _test_eof156: cs = 156; goto _test_eof; + _test_eof157: cs = 157; goto _test_eof; + _test_eof33: cs = 33; goto _test_eof; + _test_eof34: cs = 34; goto _test_eof; + _test_eof35: cs = 35; goto _test_eof; + _test_eof36: cs = 36; goto _test_eof; + _test_eof37: cs = 37; goto _test_eof; + _test_eof158: cs = 158; goto _test_eof; + _test_eof159: cs = 159; goto _test_eof; + _test_eof160: cs = 160; goto _test_eof; + _test_eof161: cs = 161; goto _test_eof; + _test_eof162: cs = 162; goto _test_eof; + _test_eof163: cs = 163; goto _test_eof; + _test_eof164: cs = 164; goto _test_eof; + _test_eof165: cs = 165; goto _test_eof; + _test_eof166: cs = 166; goto _test_eof; + _test_eof167: cs = 167; goto _test_eof; + _test_eof168: cs = 168; goto _test_eof; + _test_eof169: cs = 169; goto _test_eof; + _test_eof170: cs = 170; goto _test_eof; + _test_eof171: cs = 171; goto _test_eof; + _test_eof172: cs = 172; goto _test_eof; + _test_eof38: cs = 38; goto _test_eof; + _test_eof39: cs = 39; goto _test_eof; + _test_eof40: cs = 40; goto _test_eof; + _test_eof41: cs = 41; goto _test_eof; + _test_eof42: cs = 42; goto _test_eof; + _test_eof43: cs = 43; goto _test_eof; + _test_eof44: cs = 44; goto _test_eof; + _test_eof45: cs = 45; goto _test_eof; + _test_eof46: cs = 46; goto _test_eof; + _test_eof47: cs = 47; goto _test_eof; + _test_eof48: cs = 48; goto _test_eof; + _test_eof49: cs = 49; goto _test_eof; + _test_eof50: cs = 50; goto _test_eof; + _test_eof51: cs = 51; goto _test_eof; + _test_eof52: cs = 52; goto _test_eof; + _test_eof53: cs = 53; goto _test_eof; + _test_eof54: cs = 54; goto _test_eof; + _test_eof55: cs = 55; goto _test_eof; + _test_eof56: cs = 56; goto _test_eof; + _test_eof57: cs = 57; goto _test_eof; + _test_eof58: cs = 58; goto _test_eof; + _test_eof59: cs = 59; goto _test_eof; + _test_eof60: cs = 60; goto _test_eof; + _test_eof61: cs = 61; goto _test_eof; + _test_eof62: cs = 62; goto _test_eof; + _test_eof63: cs = 63; goto _test_eof; + _test_eof64: cs = 64; goto _test_eof; + _test_eof65: cs = 65; goto _test_eof; + _test_eof66: cs = 66; goto _test_eof; + _test_eof67: cs = 67; goto _test_eof; + _test_eof68: cs = 68; goto _test_eof; + _test_eof69: cs = 69; goto _test_eof; + _test_eof70: cs = 70; goto _test_eof; + _test_eof71: cs = 71; goto _test_eof; + _test_eof72: cs = 72; goto _test_eof; + _test_eof73: cs = 73; goto _test_eof; + _test_eof74: cs = 74; goto _test_eof; + _test_eof75: cs = 75; goto _test_eof; + _test_eof76: cs = 76; goto _test_eof; + _test_eof77: cs = 77; goto _test_eof; + _test_eof78: cs = 78; goto _test_eof; + _test_eof79: cs = 79; goto _test_eof; + _test_eof80: cs = 80; goto _test_eof; + _test_eof81: cs = 81; goto _test_eof; + _test_eof82: cs = 82; goto _test_eof; + _test_eof173: cs = 173; goto _test_eof; + _test_eof83: cs = 83; goto _test_eof; + _test_eof84: cs = 84; goto _test_eof; + _test_eof85: cs = 85; goto _test_eof; + _test_eof86: cs = 86; goto _test_eof; + _test_eof87: cs = 87; goto _test_eof; + _test_eof88: cs = 88; goto _test_eof; + _test_eof89: cs = 89; goto _test_eof; + _test_eof90: cs = 90; goto _test_eof; + _test_eof91: cs = 91; goto _test_eof; + _test_eof92: cs = 92; goto _test_eof; + _test_eof93: cs = 93; goto _test_eof; + _test_eof94: cs = 94; goto _test_eof; + _test_eof95: cs = 95; goto _test_eof; + _test_eof96: cs = 96; goto _test_eof; + _test_eof97: cs = 97; goto _test_eof; + _test_eof98: cs = 98; goto _test_eof; + _test_eof99: cs = 99; goto _test_eof; + _test_eof100: cs = 100; goto _test_eof; + _test_eof101: cs = 101; goto _test_eof; + _test_eof102: cs = 102; goto _test_eof; + _test_eof103: cs = 103; goto _test_eof; + _test_eof174: cs = 174; goto _test_eof; + _test_eof175: cs = 175; goto _test_eof; + _test_eof176: cs = 176; goto _test_eof; + _test_eof177: cs = 177; goto _test_eof; + _test_eof178: cs = 178; goto _test_eof; + _test_eof179: cs = 179; goto _test_eof; + _test_eof180: cs = 180; goto _test_eof; + _test_eof104: cs = 104; goto _test_eof; + _test_eof105: cs = 105; goto _test_eof; + _test_eof106: cs = 106; goto _test_eof; + _test_eof107: cs = 107; goto _test_eof; + _test_eof108: cs = 108; goto _test_eof; + _test_eof181: cs = 181; goto _test_eof; + _test_eof109: cs = 109; goto _test_eof; + _test_eof110: cs = 110; goto _test_eof; + _test_eof111: cs = 111; goto _test_eof; + _test_eof112: cs = 112; goto _test_eof; + _test_eof113: cs = 113; goto _test_eof; + _test_eof182: cs = 182; goto _test_eof; + _test_eof183: cs = 183; goto _test_eof; + _test_eof184: cs = 184; goto _test_eof; + _test_eof185: cs = 185; goto _test_eof; + _test_eof186: cs = 186; goto _test_eof; + _test_eof187: cs = 187; goto _test_eof; + _test_eof114: cs = 114; goto _test_eof; + _test_eof115: cs = 115; goto _test_eof; + _test_eof116: cs = 116; goto _test_eof; + _test_eof117: cs = 117; goto _test_eof; + _test_eof118: cs = 118; goto _test_eof; + _test_eof188: cs = 188; goto _test_eof; + _test_eof189: cs = 189; goto _test_eof; + _test_eof190: cs = 190; goto _test_eof; + _test_eof191: cs = 191; goto _test_eof; + _test_eof192: cs = 192; goto _test_eof; + _test_eof193: cs = 193; goto _test_eof; + _test_eof194: cs = 194; goto _test_eof; + _test_eof195: cs = 195; goto _test_eof; + _test_eof196: cs = 196; goto _test_eof; + _test_eof197: cs = 197; goto _test_eof; + _test_eof198: cs = 198; goto _test_eof; + _test_eof199: cs = 199; goto _test_eof; + _test_eof200: cs = 200; goto _test_eof; + _test_eof201: cs = 201; goto _test_eof; + _test_eof202: cs = 202; goto _test_eof; + _test_eof203: cs = 203; goto _test_eof; + _test_eof204: cs = 204; goto _test_eof; + _test_eof205: cs = 205; goto _test_eof; + _test_eof206: cs = 206; goto _test_eof; + _test_eof207: cs = 207; goto _test_eof; + _test_eof208: cs = 208; goto _test_eof; + _test_eof209: cs = 209; goto _test_eof; + _test_eof119: cs = 119; goto _test_eof; + _test_eof120: cs = 120; goto _test_eof; + _test_eof121: cs = 121; goto _test_eof; + _test_eof122: cs = 122; goto _test_eof; + _test_eof123: cs = 123; goto _test_eof; + _test_eof210: cs = 210; goto _test_eof; + _test_eof211: cs = 211; goto _test_eof; + _test_eof124: cs = 124; goto _test_eof; + _test_eof125: cs = 125; goto _test_eof; + _test_eof126: cs = 126; goto _test_eof; + _test_eof127: cs = 127; goto _test_eof; + _test_eof128: cs = 128; goto _test_eof; + _test_eof212: cs = 212; goto _test_eof; + _test_eof213: cs = 213; goto _test_eof; + _test_eof129: cs = 129; goto _test_eof; + _test_eof130: cs = 130; goto _test_eof; + _test_eof131: cs = 131; goto _test_eof; + _test_eof132: cs = 132; goto _test_eof; + _test_eof133: cs = 133; goto _test_eof; + _test_eof214: cs = 214; goto _test_eof; + _test_eof215: cs = 215; goto _test_eof; + _test_eof216: cs = 216; goto _test_eof; + _test_eof217: cs = 217; goto _test_eof; + _test_eof218: cs = 218; goto _test_eof; + _test_eof219: cs = 219; goto _test_eof; + _test_eof220: cs = 220; goto _test_eof; + _test_eof221: cs = 221; goto _test_eof; + _test_eof222: cs = 222; goto _test_eof; + _test_eof223: cs = 223; goto _test_eof; + _test_eof224: cs = 224; goto _test_eof; + _test_eof225: cs = 225; goto _test_eof; + _test_eof226: cs = 226; goto _test_eof; + _test_eof227: cs = 227; goto _test_eof; + _test_eof228: cs = 228; goto _test_eof; + _test_eof229: cs = 229; goto _test_eof; + _test_eof230: cs = 230; goto _test_eof; + _test_eof231: cs = 231; goto _test_eof; + _test_eof232: cs = 232; goto _test_eof; + _test_eof233: cs = 233; goto _test_eof; + _test_eof234: cs = 234; goto _test_eof; + _test_eof235: cs = 235; goto _test_eof; + _test_eof236: cs = 236; goto _test_eof; + _test_eof237: cs = 237; goto _test_eof; + _test_eof238: cs = 238; goto _test_eof; + _test_eof239: cs = 239; goto _test_eof; + _test_eof240: cs = 240; goto _test_eof; + _test_eof241: cs = 241; goto _test_eof; + _test_eof242: cs = 242; goto _test_eof; + _test_eof243: cs = 243; goto _test_eof; + _test_eof244: cs = 244; goto _test_eof; + _test_eof245: cs = 245; goto _test_eof; + _test_eof246: cs = 246; goto _test_eof; + _test_eof247: cs = 247; goto _test_eof; + _test_eof248: cs = 248; goto _test_eof; + _test_eof249: cs = 249; goto _test_eof; + _test_eof250: cs = 250; goto _test_eof; + _test_eof251: cs = 251; goto _test_eof; + _test_eof252: cs = 252; goto _test_eof; + _test_eof253: cs = 253; goto _test_eof; + _test_eof254: cs = 254; goto _test_eof; + _test_eof255: cs = 255; goto _test_eof; + _test_eof256: cs = 256; goto _test_eof; + _test_eof257: cs = 257; goto _test_eof; + _test_eof258: cs = 258; goto _test_eof; + _test_eof259: cs = 259; goto _test_eof; + _test_eof134: cs = 134; goto _test_eof; + _test_eof135: cs = 135; goto _test_eof; + _test_eof136: cs = 136; goto _test_eof; + _test_eof137: cs = 137; goto _test_eof; + _test_eof138: cs = 138; goto _test_eof; + _test_eof260: cs = 260; goto _test_eof; + _test_eof139: cs = 139; goto _test_eof; + _test_eof140: cs = 140; goto _test_eof; + _test_eof141: cs = 141; goto _test_eof; + _test_eof142: cs = 142; goto _test_eof; + _test_eof143: cs = 143; goto _test_eof; + _test_eof261: cs = 261; goto _test_eof; + _test_eof262: cs = 262; goto _test_eof; + _test_eof263: cs = 263; goto _test_eof; + _test_eof264: cs = 264; goto _test_eof; + _test_eof265: cs = 265; goto _test_eof; + + _test_eof: {} + if ( p == eof ) + { + switch ( cs ) { + case 150: +#line 69 "../../src/uri.rl" + { uri->query = s; uri->query_len = p - s; } + break; + case 147: +#line 73 "../../src/uri.rl" + { uri->fragment = s; uri->fragment_len = p - s; } + break; + case 156: + case 157: +#line 111 "../../src/uri.rl" + { + /* + * This action is also called for path_* terminals. + * I absolute have no idea why. Please don't blame + * and fix grammar if you have a LOT of free time. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } + break; + case 144: + case 148: + case 178: + case 179: + case 180: + case 181: + case 204: + case 207: + case 208: + case 211: + case 212: + case 257: +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } + break; + case 149: +#line 68 "../../src/uri.rl" + { s = p; } +#line 69 "../../src/uri.rl" + { uri->query = s; uri->query_len = p - s; } + break; + case 146: +#line 72 "../../src/uri.rl" + { s = p; } +#line 73 "../../src/uri.rl" + { uri->fragment = s; uri->fragment_len = p - s; } + break; + case 173: + case 182: + case 183: +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } + break; + case 186: + case 187: + case 259: + case 260: +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 111 "../../src/uri.rl" + { + /* + * This action is also called for path_* terminals. + * I absolute have no idea why. Please don't blame + * and fix grammar if you have a LOT of free time. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } + break; + case 145: + case 152: + case 158: + case 159: + case 160: + case 161: + case 162: + case 163: + case 167: + case 168: + case 169: + case 170: + case 171: + case 172: + case 174: + case 175: + case 176: + case 177: + case 189: + case 190: + case 191: + case 192: + case 193: + case 197: + case 198: + case 199: + case 200: + case 205: + case 209: + case 213: + case 217: + case 218: + case 219: + case 220: + case 221: + case 222: + case 226: + case 227: + case 228: + case 229: + case 230: + case 231: + case 232: + case 233: + case 234: + case 235: + case 238: + case 239: + case 240: + case 241: + case 242: + case 243: + case 247: + case 248: + case 249: + case 250: + case 251: + case 252: + case 253: + case 254: + case 255: + case 256: + case 262: + case 263: + case 264: + case 265: +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } + break; + case 154: + case 155: + case 184: + case 185: + case 215: + case 216: + case 236: + case 237: +#line 132 "../../src/uri.rl" + { uri->service = s; uri->service_len = p - s; } +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } + break; + case 261: +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 111 "../../src/uri.rl" + { + /* + * This action is also called for path_* terminals. + * I absolute have no idea why. Please don't blame + * and fix grammar if you have a LOT of free time. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } + break; + case 258: +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 128 "../../src/uri.rl" + { s = p;} +#line 111 "../../src/uri.rl" + { + /* + * This action is also called for path_* terminals. + * I absolute have no idea why. Please don't blame + * and fix grammar if you have a LOT of free time. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } + break; + case 188: + case 201: + case 202: + case 203: +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } +#line 179 "../../src/uri.rl" + { uri->service_len = p - uri->service; + uri->host = NULL; uri->host_len = 0; } + break; + case 164: + case 165: + case 166: + case 194: + case 195: + case 196: + case 223: + case 224: + case 225: + case 244: + case 245: + case 246: +#line 100 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s; + uri->host_hint = 1; } +#line 93 "../../src/uri.rl" + { uri->host = s; uri->host_len = p - s;} +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } + break; + case 151: + case 153: + case 206: + case 210: + case 214: +#line 131 "../../src/uri.rl" + { s = p; } +#line 132 "../../src/uri.rl" + { uri->service = s; uri->service_len = p - s; } +#line 161 "../../src/uri.rl" + { s = p; } +#line 165 "../../src/uri.rl" + { uri->path = s; uri->path_len = p - s; } + break; +#line 6492 "../../src/uri.c" + } + } + + _out: {} + } + +#line 192 "../../src/uri.rl" + + + if (uri->path_len == 0) + uri->path = NULL; + if (uri->service_len == 0) + uri->service = NULL; + if (uri->service_len >= URI_MAXSERVICE) + return -1; + if (uri->host_len >= URI_MAXHOST) + return -1; + + (void)uri_first_final; + (void)uri_error; + (void)uri_en_main; + (void)eof; + + return cs >= uri_first_final ? 0 : -1; +} + +char * +uri_format(const struct uri *uri) +{ + static char buf[1024]; + /* very primitive implementation suitable for our needs */ + snprintf(buf, sizeof(buf), "%.*s:%.*s", + (int) uri->host_len, uri->host != NULL ? uri->host : "*", + (int) uri->service_len, uri->service); + return buf; +} +/* vim: set ft=ragel: */ diff --git a/src/uri.cc b/src/uri.cc deleted file mode 100644 index d970ef6ee7c4298af81a356ef1d1c84e854848fb..0000000000000000000000000000000000000000 --- a/src/uri.cc +++ /dev/null @@ -1,5538 +0,0 @@ - -#line 1 "src/uri.rl" -/* - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#include "uri.h" -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <assert.h> -#include <sys/socket.h> -#include <netinet/ip.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/un.h> -#include <netdb.h> - -const char * -uri_to_string(const struct uri * uri) -{ - static __thread char - str[NI_MAXSERV + NI_MAXHOST + sizeof(uri->schema)]; - - if (!uri || !uri->addr_len) { - snprintf(str, sizeof(str), "unknown address"); - return str; - } - - switch (uri->addr.sa_family) { - case AF_INET6: - case AF_INET: - { - char shost[NI_MAXHOST]; - char sservice[NI_MAXSERV]; - getnameinfo( - (struct sockaddr *)&uri->addr, - uri->addr_len, - shost, sizeof(shost), - sservice, sizeof(sservice), - NI_NUMERICHOST|NI_NUMERICSERV); - if (uri->addr.sa_family == AF_INET) { - if (strncmp(uri->schema, "tcp", 3) == 0) { - snprintf(str, sizeof(str), "%s:%s", - shost, sservice); - } else { - snprintf(str, sizeof(str), "%s://%s:%s", - uri->schema, shost, sservice); - } - } else { - if (strncmp(uri->schema, "tcp", 3) == 0) { - snprintf(str, sizeof(str), "%s:%s", - shost, sservice); - } else { - snprintf(str, sizeof(str), "%s://[%s]:%s", - uri->schema, shost, sservice); - } - } - break; - } - case AF_UNIX: - { - struct sockaddr_un *un = - (struct sockaddr_un *)&uri->addr; - snprintf(str, sizeof(str), "unix://%.*s", - (int) sizeof(un->sun_path), un->sun_path); - break; - } - default: - snprintf(str, sizeof(str), "unknown address"); - break; - } - return str; -} - -int -uri_parse(struct uri *uri, const char *p) -{ - (void) uri; - const char *pe = p + strlen(p); - const char *eof = pe; - int cs; - memset(uri, 0, sizeof(*uri)); - - struct { - const char *start; - const char *end; - } schema = { 0, 0 }, - host = { 0, 0 }, - service = { 0, 0 }, - sport = { 0, 0 }, - login = { 0, 0 }, - password = { 0, 0 }, - ip4 = { 0, 0 }, - ip6 = { 0, 0 }, - path = { 0, 0 }, - dport = { 0, 0 } - ; - - unsigned port = 0; - - -#line 128 "src/uri.cc" -static const int uri_start = 1; -static const int uri_first_final = 74; -static const int uri_error = 0; - -static const int uri_en_main = 1; - - -#line 136 "src/uri.cc" - { - cs = uri_start; - } - -#line 141 "src/uri.cc" - { - if ( p == pe ) - goto _test_eof; - switch ( cs ) - { -case 1: - switch( (*p) ) { - case 47: goto tr1; - case 48: goto tr2; - case 58: goto st0; - case 63: goto st0; - case 91: goto tr6; - case 117: goto tr7; - } - if ( (*p) < 65 ) { - if ( 49 <= (*p) && (*p) <= 57 ) - goto tr3; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto tr5; - } else - goto tr5; - goto tr0; -tr0: -#line 157 "src/uri.rl" - { host.start = p; } - goto st74; -tr82: -#line 133 "src/uri.rl" - { schema.end = p - 3; } -#line 157 "src/uri.rl" - { host.start = p; } - goto st74; -st74: - if ( ++p == pe ) - goto _test_eof74; -case 74: -#line 179 "src/uri.cc" - switch( (*p) ) { - case 58: goto tr94; - case 63: goto st0; - } - goto st74; -tr94: -#line 158 "src/uri.rl" - { host.end = p; } - goto st2; -tr144: -#line 145 "src/uri.rl" - { ip4.end = p; } -#line 158 "src/uri.rl" - { host.end = p; } - goto st2; -tr157: -#line 154 "src/uri.rl" - { ip6.end = p - 1; } -#line 158 "src/uri.rl" - { host.end = p; } - goto st2; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: -#line 205 "src/uri.cc" - if ( (*p) < 65 ) { - if ( 49 <= (*p) && (*p) <= 57 ) - goto tr8; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto tr9; - } else - goto tr9; - goto st0; -st0: -cs = 0; - goto _out; -tr8: -#line 166 "src/uri.rl" - { service.start = p; } -#line 161 "src/uri.rl" - { dport.start = p; port = 0; } -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st75; -tr95: -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st75; -st75: - if ( ++p == pe ) - goto _test_eof75; -case 75: -#line 234 "src/uri.cc" - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr95; - goto st0; -tr9: -#line 166 "src/uri.rl" - { service.start = p; } - goto st76; -st76: - if ( ++p == pe ) - goto _test_eof76; -case 76: -#line 246 "src/uri.cc" - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st77; - } else if ( (*p) >= 65 ) - goto st77; - goto st0; -st77: - if ( ++p == pe ) - goto _test_eof77; -case 77: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st78; - } else if ( (*p) >= 65 ) - goto st78; - goto st0; -st78: - if ( ++p == pe ) - goto _test_eof78; -case 78: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st79; - } else if ( (*p) >= 65 ) - goto st79; - goto st0; -st79: - if ( ++p == pe ) - goto _test_eof79; -case 79: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st80; - } else if ( (*p) >= 65 ) - goto st80; - goto st0; -st80: - if ( ++p == pe ) - goto _test_eof80; -case 80: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st81; - } else if ( (*p) >= 65 ) - goto st81; - goto st0; -st81: - if ( ++p == pe ) - goto _test_eof81; -case 81: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st82; - } else if ( (*p) >= 65 ) - goto st82; - goto st0; -st82: - if ( ++p == pe ) - goto _test_eof82; -case 82: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st83; - } else if ( (*p) >= 65 ) - goto st83; - goto st0; -st83: - if ( ++p == pe ) - goto _test_eof83; -case 83: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st84; - } else if ( (*p) >= 65 ) - goto st84; - goto st0; -st84: - if ( ++p == pe ) - goto _test_eof84; -case 84: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st85; - } else if ( (*p) >= 65 ) - goto st85; - goto st0; -st85: - if ( ++p == pe ) - goto _test_eof85; -case 85: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st86; - } else if ( (*p) >= 65 ) - goto st86; - goto st0; -st86: - if ( ++p == pe ) - goto _test_eof86; -case 86: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st87; - } else if ( (*p) >= 65 ) - goto st87; - goto st0; -st87: - if ( ++p == pe ) - goto _test_eof87; -case 87: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st88; - } else if ( (*p) >= 65 ) - goto st88; - goto st0; -st88: - if ( ++p == pe ) - goto _test_eof88; -case 88: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st89; - } else if ( (*p) >= 65 ) - goto st89; - goto st0; -st89: - if ( ++p == pe ) - goto _test_eof89; -case 89: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st90; - } else if ( (*p) >= 65 ) - goto st90; - goto st0; -st90: - if ( ++p == pe ) - goto _test_eof90; -case 90: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st91; - } else if ( (*p) >= 65 ) - goto st91; - goto st0; -st91: - if ( ++p == pe ) - goto _test_eof91; -case 91: - goto st0; -tr1: -#line 157 "src/uri.rl" - { host.start = p; } -#line 176 "src/uri.rl" - { path.start = p; } - goto st92; -st92: - if ( ++p == pe ) - goto _test_eof92; -case 92: -#line 408 "src/uri.cc" - switch( (*p) ) { - case 58: goto tr112; - case 63: goto st95; - } - goto st93; -st93: - if ( ++p == pe ) - goto _test_eof93; -case 93: - switch( (*p) ) { - case 58: goto tr112; - case 63: goto st95; - } - goto st93; -tr112: -#line 158 "src/uri.rl" - { host.end = p; } - goto st94; -st94: - if ( ++p == pe ) - goto _test_eof94; -case 94: -#line 431 "src/uri.cc" - if ( (*p) < 65 ) { - if ( 49 <= (*p) && (*p) <= 57 ) - goto tr114; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto tr115; - } else - goto tr115; - goto st95; -st95: - if ( ++p == pe ) - goto _test_eof95; -case 95: - goto st95; -tr114: -#line 166 "src/uri.rl" - { service.start = p; } -#line 161 "src/uri.rl" - { dport.start = p; port = 0; } -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st96; -tr116: -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st96; -st96: - if ( ++p == pe ) - goto _test_eof96; -case 96: -#line 462 "src/uri.cc" - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr116; - goto st95; -tr115: -#line 166 "src/uri.rl" - { service.start = p; } - goto st97; -st97: - if ( ++p == pe ) - goto _test_eof97; -case 97: -#line 474 "src/uri.cc" - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st98; - } else if ( (*p) >= 65 ) - goto st98; - goto st95; -st98: - if ( ++p == pe ) - goto _test_eof98; -case 98: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st99; - } else if ( (*p) >= 65 ) - goto st99; - goto st95; -st99: - if ( ++p == pe ) - goto _test_eof99; -case 99: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st100; - } else if ( (*p) >= 65 ) - goto st100; - goto st95; -st100: - if ( ++p == pe ) - goto _test_eof100; -case 100: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st101; - } else if ( (*p) >= 65 ) - goto st101; - goto st95; -st101: - if ( ++p == pe ) - goto _test_eof101; -case 101: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st102; - } else if ( (*p) >= 65 ) - goto st102; - goto st95; -st102: - if ( ++p == pe ) - goto _test_eof102; -case 102: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st103; - } else if ( (*p) >= 65 ) - goto st103; - goto st95; -st103: - if ( ++p == pe ) - goto _test_eof103; -case 103: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st104; - } else if ( (*p) >= 65 ) - goto st104; - goto st95; -st104: - if ( ++p == pe ) - goto _test_eof104; -case 104: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st105; - } else if ( (*p) >= 65 ) - goto st105; - goto st95; -st105: - if ( ++p == pe ) - goto _test_eof105; -case 105: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st106; - } else if ( (*p) >= 65 ) - goto st106; - goto st95; -st106: - if ( ++p == pe ) - goto _test_eof106; -case 106: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st107; - } else if ( (*p) >= 65 ) - goto st107; - goto st95; -st107: - if ( ++p == pe ) - goto _test_eof107; -case 107: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st108; - } else if ( (*p) >= 65 ) - goto st108; - goto st95; -st108: - if ( ++p == pe ) - goto _test_eof108; -case 108: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st109; - } else if ( (*p) >= 65 ) - goto st109; - goto st95; -st109: - if ( ++p == pe ) - goto _test_eof109; -case 109: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st110; - } else if ( (*p) >= 65 ) - goto st110; - goto st95; -st110: - if ( ++p == pe ) - goto _test_eof110; -case 110: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st111; - } else if ( (*p) >= 65 ) - goto st111; - goto st95; -st111: - if ( ++p == pe ) - goto _test_eof111; -case 111: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st112; - } else if ( (*p) >= 65 ) - goto st112; - goto st95; -st112: - if ( ++p == pe ) - goto _test_eof112; -case 112: - goto st95; -tr2: -#line 136 "src/uri.rl" - { login.start = p; } -#line 157 "src/uri.rl" - { host.start = p; } -#line 144 "src/uri.rl" - { ip4.start = p; } - goto st113; -tr83: -#line 133 "src/uri.rl" - { schema.end = p - 3; } -#line 136 "src/uri.rl" - { login.start = p; } -#line 157 "src/uri.rl" - { host.start = p; } -#line 144 "src/uri.rl" - { ip4.start = p; } - goto st113; -st113: - if ( ++p == pe ) - goto _test_eof113; -case 113: -#line 648 "src/uri.cc" - switch( (*p) ) { - case 46: goto st114; - case 58: goto tr134; - case 63: goto st0; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st126; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st128; - } else - goto st128; - goto st74; -st114: - if ( ++p == pe ) - goto _test_eof114; -case 114: - switch( (*p) ) { - case 58: goto tr94; - case 63: goto st0; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st115; - goto st74; -st115: - if ( ++p == pe ) - goto _test_eof115; -case 115: - switch( (*p) ) { - case 46: goto st116; - case 58: goto tr94; - case 63: goto st0; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st124; - goto st74; -st116: - if ( ++p == pe ) - goto _test_eof116; -case 116: - switch( (*p) ) { - case 58: goto tr94; - case 63: goto st0; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st117; - goto st74; -st117: - if ( ++p == pe ) - goto _test_eof117; -case 117: - switch( (*p) ) { - case 46: goto st118; - case 58: goto tr94; - case 63: goto st0; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st122; - goto st74; -st118: - if ( ++p == pe ) - goto _test_eof118; -case 118: - switch( (*p) ) { - case 58: goto tr94; - case 63: goto st0; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st119; - goto st74; -st119: - if ( ++p == pe ) - goto _test_eof119; -case 119: - switch( (*p) ) { - case 58: goto tr144; - case 63: goto st0; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st120; - goto st74; -st120: - if ( ++p == pe ) - goto _test_eof120; -case 120: - switch( (*p) ) { - case 58: goto tr144; - case 63: goto st0; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st121; - goto st74; -st121: - if ( ++p == pe ) - goto _test_eof121; -case 121: - switch( (*p) ) { - case 58: goto tr144; - case 63: goto st0; - } - goto st74; -st122: - if ( ++p == pe ) - goto _test_eof122; -case 122: - switch( (*p) ) { - case 46: goto st118; - case 58: goto tr94; - case 63: goto st0; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st123; - goto st74; -st123: - if ( ++p == pe ) - goto _test_eof123; -case 123: - switch( (*p) ) { - case 46: goto st118; - case 58: goto tr94; - case 63: goto st0; - } - goto st74; -st124: - if ( ++p == pe ) - goto _test_eof124; -case 124: - switch( (*p) ) { - case 46: goto st116; - case 58: goto tr94; - case 63: goto st0; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st125; - goto st74; -st125: - if ( ++p == pe ) - goto _test_eof125; -case 125: - switch( (*p) ) { - case 46: goto st116; - case 58: goto tr94; - case 63: goto st0; - } - goto st74; -st126: - if ( ++p == pe ) - goto _test_eof126; -case 126: - switch( (*p) ) { - case 46: goto st114; - case 58: goto tr134; - case 63: goto st0; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st127; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st128; - } else - goto st128; - goto st74; -st127: - if ( ++p == pe ) - goto _test_eof127; -case 127: - switch( (*p) ) { - case 46: goto st114; - case 58: goto tr134; - case 63: goto st0; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st128; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st128; - } else - goto st128; - goto st74; -tr84: -#line 133 "src/uri.rl" - { schema.end = p - 3; } -#line 136 "src/uri.rl" - { login.start = p; } -#line 157 "src/uri.rl" - { host.start = p; } - goto st128; -st128: - if ( ++p == pe ) - goto _test_eof128; -case 128: -#line 843 "src/uri.cc" - switch( (*p) ) { - case 58: goto tr134; - case 63: goto st0; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st128; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st128; - } else - goto st128; - goto st74; -tr134: -#line 137 "src/uri.rl" - { login.end = p; } -#line 158 "src/uri.rl" - { host.end = p; } - goto st3; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: -#line 867 "src/uri.cc" - if ( (*p) == 48 ) - goto tr10; - if ( (*p) < 65 ) { - if ( 49 <= (*p) && (*p) <= 57 ) - goto tr11; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto tr12; - } else - goto tr12; - goto st0; -tr10: -#line 140 "src/uri.rl" - { password.start = p; } - goto st4; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: -#line 887 "src/uri.cc" - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st4; - } else - goto st4; - goto st0; -tr14: -#line 141 "src/uri.rl" - { password.end = p; } - goto st5; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: -#line 907 "src/uri.cc" - switch( (*p) ) { - case 58: goto st0; - case 63: goto st0; - case 91: goto tr6; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr15; - goto tr0; -tr15: -#line 157 "src/uri.rl" - { host.start = p; } -#line 144 "src/uri.rl" - { ip4.start = p; } - goto st129; -st129: - if ( ++p == pe ) - goto _test_eof129; -case 129: -#line 926 "src/uri.cc" - switch( (*p) ) { - case 46: goto st114; - case 58: goto tr94; - case 63: goto st0; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st130; - goto st74; -st130: - if ( ++p == pe ) - goto _test_eof130; -case 130: - switch( (*p) ) { - case 46: goto st114; - case 58: goto tr94; - case 63: goto st0; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st131; - goto st74; -st131: - if ( ++p == pe ) - goto _test_eof131; -case 131: - switch( (*p) ) { - case 46: goto st114; - case 58: goto tr94; - case 63: goto st0; - } - goto st74; -tr6: -#line 157 "src/uri.rl" - { host.start = p; } -#line 153 "src/uri.rl" - { ip6.start = p + 1; } - goto st132; -tr85: -#line 133 "src/uri.rl" - { schema.end = p - 3; } -#line 157 "src/uri.rl" - { host.start = p; } -#line 153 "src/uri.rl" - { ip6.start = p + 1; } - goto st132; -st132: - if ( ++p == pe ) - goto _test_eof132; -case 132: -#line 975 "src/uri.cc" - switch( (*p) ) { - case 58: goto tr152; - case 63: goto st0; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st133; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st133; - } else - goto st133; - goto st74; -st133: - if ( ++p == pe ) - goto _test_eof133; -case 133: - switch( (*p) ) { - case 58: goto tr154; - case 63: goto st0; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st134; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st134; - } else - goto st134; - goto st74; -st134: - if ( ++p == pe ) - goto _test_eof134; -case 134: - switch( (*p) ) { - case 58: goto tr154; - case 63: goto st0; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st135; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st135; - } else - goto st135; - goto st74; -st135: - if ( ++p == pe ) - goto _test_eof135; -case 135: - switch( (*p) ) { - case 58: goto tr154; - case 63: goto st0; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st136; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st136; - } else - goto st136; - goto st74; -st136: - if ( ++p == pe ) - goto _test_eof136; -case 136: - switch( (*p) ) { - case 58: goto tr154; - case 63: goto st0; - } - goto st74; -tr154: -#line 158 "src/uri.rl" - { host.end = p; } - goto st6; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: -#line 1057 "src/uri.cc" - switch( (*p) ) { - case 48: goto st7; - case 58: goto st11; - case 93: goto st137; - } - if ( (*p) < 71 ) { - if ( (*p) > 57 ) { - if ( 65 <= (*p) && (*p) <= 70 ) - goto tr19; - } else if ( (*p) >= 49 ) - goto tr17; - } else if ( (*p) > 90 ) { - if ( (*p) > 102 ) { - if ( 103 <= (*p) && (*p) <= 122 ) - goto tr9; - } else if ( (*p) >= 97 ) - goto tr19; - } else - goto tr9; - goto st0; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - switch( (*p) ) { - case 58: goto st11; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st8; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st8; - } else - goto st8; - goto st0; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: - switch( (*p) ) { - case 58: goto st11; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st9; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st9; - } else - goto st9; - goto st0; -st9: - if ( ++p == pe ) - goto _test_eof9; -case 9: - switch( (*p) ) { - case 58: goto st11; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st10; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st10; - } else - goto st10; - goto st0; -st10: - if ( ++p == pe ) - goto _test_eof10; -case 10: - switch( (*p) ) { - case 58: goto st11; - case 93: goto st137; - } - goto st0; -st11: - if ( ++p == pe ) - goto _test_eof11; -case 11: - switch( (*p) ) { - case 58: goto st16; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st12; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st12; - } else - goto st12; - goto st0; -st12: - if ( ++p == pe ) - goto _test_eof12; -case 12: - switch( (*p) ) { - case 58: goto st16; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st13; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st13; - } else - goto st13; - goto st0; -st13: - if ( ++p == pe ) - goto _test_eof13; -case 13: - switch( (*p) ) { - case 58: goto st16; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st14; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st14; - } else - goto st14; - goto st0; -st14: - if ( ++p == pe ) - goto _test_eof14; -case 14: - switch( (*p) ) { - case 58: goto st16; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st15; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st15; - } else - goto st15; - goto st0; -st15: - if ( ++p == pe ) - goto _test_eof15; -case 15: - switch( (*p) ) { - case 58: goto st16; - case 93: goto st137; - } - goto st0; -st16: - if ( ++p == pe ) - goto _test_eof16; -case 16: - switch( (*p) ) { - case 58: goto st21; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st17; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st17; - } else - goto st17; - goto st0; -st17: - if ( ++p == pe ) - goto _test_eof17; -case 17: - switch( (*p) ) { - case 58: goto st21; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st18; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st18; - } else - goto st18; - goto st0; -st18: - if ( ++p == pe ) - goto _test_eof18; -case 18: - switch( (*p) ) { - case 58: goto st21; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st19; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st19; - } else - goto st19; - goto st0; -st19: - if ( ++p == pe ) - goto _test_eof19; -case 19: - switch( (*p) ) { - case 58: goto st21; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st20; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st20; - } else - goto st20; - goto st0; -st20: - if ( ++p == pe ) - goto _test_eof20; -case 20: - switch( (*p) ) { - case 58: goto st21; - case 93: goto st137; - } - goto st0; -st21: - if ( ++p == pe ) - goto _test_eof21; -case 21: - switch( (*p) ) { - case 58: goto st26; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st22; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st22; - } else - goto st22; - goto st0; -st22: - if ( ++p == pe ) - goto _test_eof22; -case 22: - switch( (*p) ) { - case 58: goto st26; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st23; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st23; - } else - goto st23; - goto st0; -st23: - if ( ++p == pe ) - goto _test_eof23; -case 23: - switch( (*p) ) { - case 58: goto st26; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st24; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st24; - } else - goto st24; - goto st0; -st24: - if ( ++p == pe ) - goto _test_eof24; -case 24: - switch( (*p) ) { - case 58: goto st26; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st25; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st25; - } else - goto st25; - goto st0; -st25: - if ( ++p == pe ) - goto _test_eof25; -case 25: - switch( (*p) ) { - case 58: goto st26; - case 93: goto st137; - } - goto st0; -st26: - if ( ++p == pe ) - goto _test_eof26; -case 26: - switch( (*p) ) { - case 58: goto st31; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st27; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st27; - } else - goto st27; - goto st0; -st27: - if ( ++p == pe ) - goto _test_eof27; -case 27: - switch( (*p) ) { - case 58: goto st31; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st28; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st28; - } else - goto st28; - goto st0; -st28: - if ( ++p == pe ) - goto _test_eof28; -case 28: - switch( (*p) ) { - case 58: goto st31; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st29; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st29; - } else - goto st29; - goto st0; -st29: - if ( ++p == pe ) - goto _test_eof29; -case 29: - switch( (*p) ) { - case 58: goto st31; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st30; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st30; - } else - goto st30; - goto st0; -st30: - if ( ++p == pe ) - goto _test_eof30; -case 30: - switch( (*p) ) { - case 58: goto st31; - case 93: goto st137; - } - goto st0; -st31: - if ( ++p == pe ) - goto _test_eof31; -case 31: - switch( (*p) ) { - case 58: goto st36; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st32; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st32; - } else - goto st32; - goto st0; -st32: - if ( ++p == pe ) - goto _test_eof32; -case 32: - switch( (*p) ) { - case 58: goto st36; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st33; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st33; - } else - goto st33; - goto st0; -st33: - if ( ++p == pe ) - goto _test_eof33; -case 33: - switch( (*p) ) { - case 58: goto st36; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st34; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st34; - } else - goto st34; - goto st0; -st34: - if ( ++p == pe ) - goto _test_eof34; -case 34: - switch( (*p) ) { - case 58: goto st36; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st35; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st35; - } else - goto st35; - goto st0; -st35: - if ( ++p == pe ) - goto _test_eof35; -case 35: - switch( (*p) ) { - case 58: goto st36; - case 93: goto st137; - } - goto st0; -st36: - if ( ++p == pe ) - goto _test_eof36; -case 36: - switch( (*p) ) { - case 58: goto st41; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st37; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st37; - } else - goto st37; - goto st0; -st37: - if ( ++p == pe ) - goto _test_eof37; -case 37: - switch( (*p) ) { - case 58: goto st41; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st38; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st38; - } else - goto st38; - goto st0; -st38: - if ( ++p == pe ) - goto _test_eof38; -case 38: - switch( (*p) ) { - case 58: goto st41; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st39; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st39; - } else - goto st39; - goto st0; -st39: - if ( ++p == pe ) - goto _test_eof39; -case 39: - switch( (*p) ) { - case 58: goto st41; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st40; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st40; - } else - goto st40; - goto st0; -st40: - if ( ++p == pe ) - goto _test_eof40; -case 40: - switch( (*p) ) { - case 58: goto st41; - case 93: goto st137; - } - goto st0; -st41: - if ( ++p == pe ) - goto _test_eof41; -case 41: - if ( (*p) == 93 ) - goto st137; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st42; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st42; - } else - goto st42; - goto st0; -st42: - if ( ++p == pe ) - goto _test_eof42; -case 42: - if ( (*p) == 93 ) - goto st137; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st43; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st43; - } else - goto st43; - goto st0; -st43: - if ( ++p == pe ) - goto _test_eof43; -case 43: - if ( (*p) == 93 ) - goto st137; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st44; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st44; - } else - goto st44; - goto st0; -st44: - if ( ++p == pe ) - goto _test_eof44; -case 44: - if ( (*p) == 93 ) - goto st137; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st45; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st45; - } else - goto st45; - goto st0; -st45: - if ( ++p == pe ) - goto _test_eof45; -case 45: - if ( (*p) == 93 ) - goto st137; - goto st0; -st137: - if ( ++p == pe ) - goto _test_eof137; -case 137: - if ( (*p) == 58 ) - goto tr157; - goto st0; -tr17: -#line 166 "src/uri.rl" - { service.start = p; } -#line 161 "src/uri.rl" - { dport.start = p; port = 0; } -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st138; -st138: - if ( ++p == pe ) - goto _test_eof138; -case 138: -#line 1686 "src/uri.cc" - switch( (*p) ) { - case 58: goto st11; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr158; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st8; - } else - goto st8; - goto st0; -tr158: -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st139; -st139: - if ( ++p == pe ) - goto _test_eof139; -case 139: -#line 1708 "src/uri.cc" - switch( (*p) ) { - case 58: goto st11; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr159; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st9; - } else - goto st9; - goto st0; -tr159: -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st140; -st140: - if ( ++p == pe ) - goto _test_eof140; -case 140: -#line 1730 "src/uri.cc" - switch( (*p) ) { - case 58: goto st11; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr160; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st10; - } else - goto st10; - goto st0; -tr160: -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st141; -st141: - if ( ++p == pe ) - goto _test_eof141; -case 141: -#line 1752 "src/uri.cc" - switch( (*p) ) { - case 58: goto st11; - case 93: goto st137; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr95; - goto st0; -tr19: -#line 166 "src/uri.rl" - { service.start = p; } - goto st142; -st142: - if ( ++p == pe ) - goto _test_eof142; -case 142: -#line 1768 "src/uri.cc" - switch( (*p) ) { - case 58: goto st11; - case 93: goto st137; - } - if ( (*p) < 71 ) { - if ( (*p) > 57 ) { - if ( 65 <= (*p) && (*p) <= 70 ) - goto st143; - } else if ( (*p) >= 48 ) - goto st8; - } else if ( (*p) > 90 ) { - if ( (*p) > 102 ) { - if ( 103 <= (*p) && (*p) <= 122 ) - goto st77; - } else if ( (*p) >= 97 ) - goto st143; - } else - goto st77; - goto st0; -st143: - if ( ++p == pe ) - goto _test_eof143; -case 143: - switch( (*p) ) { - case 58: goto st11; - case 93: goto st137; - } - if ( (*p) < 71 ) { - if ( (*p) > 57 ) { - if ( 65 <= (*p) && (*p) <= 70 ) - goto st144; - } else if ( (*p) >= 48 ) - goto st9; - } else if ( (*p) > 90 ) { - if ( (*p) > 102 ) { - if ( 103 <= (*p) && (*p) <= 122 ) - goto st78; - } else if ( (*p) >= 97 ) - goto st144; - } else - goto st78; - goto st0; -st144: - if ( ++p == pe ) - goto _test_eof144; -case 144: - switch( (*p) ) { - case 58: goto st11; - case 93: goto st137; - } - if ( (*p) < 71 ) { - if ( (*p) > 57 ) { - if ( 65 <= (*p) && (*p) <= 70 ) - goto st145; - } else if ( (*p) >= 48 ) - goto st10; - } else if ( (*p) > 90 ) { - if ( (*p) > 102 ) { - if ( 103 <= (*p) && (*p) <= 122 ) - goto st79; - } else if ( (*p) >= 97 ) - goto st145; - } else - goto st79; - goto st0; -st145: - if ( ++p == pe ) - goto _test_eof145; -case 145: - switch( (*p) ) { - case 58: goto st11; - case 93: goto st137; - } - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st80; - } else if ( (*p) >= 65 ) - goto st80; - goto st0; -tr152: -#line 158 "src/uri.rl" - { host.end = p; } - goto st46; -st46: - if ( ++p == pe ) - goto _test_eof46; -case 46: -#line 1856 "src/uri.cc" - switch( (*p) ) { - case 48: goto st7; - case 58: goto st47; - case 93: goto st137; - } - if ( (*p) < 71 ) { - if ( (*p) > 57 ) { - if ( 65 <= (*p) && (*p) <= 70 ) - goto tr19; - } else if ( (*p) >= 49 ) - goto tr17; - } else if ( (*p) > 90 ) { - if ( (*p) > 102 ) { - if ( 103 <= (*p) && (*p) <= 122 ) - goto tr9; - } else if ( (*p) >= 97 ) - goto tr19; - } else - goto tr9; - goto st0; -st47: - if ( ++p == pe ) - goto _test_eof47; -case 47: - switch( (*p) ) { - case 58: goto st16; - case 70: goto st48; - case 93: goto st137; - case 102: goto st48; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st12; - } else if ( (*p) > 69 ) { - if ( 97 <= (*p) && (*p) <= 101 ) - goto st12; - } else - goto st12; - goto st0; -st48: - if ( ++p == pe ) - goto _test_eof48; -case 48: - switch( (*p) ) { - case 58: goto st16; - case 70: goto st49; - case 93: goto st137; - case 102: goto st49; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st13; - } else if ( (*p) > 69 ) { - if ( 97 <= (*p) && (*p) <= 101 ) - goto st13; - } else - goto st13; - goto st0; -st49: - if ( ++p == pe ) - goto _test_eof49; -case 49: - switch( (*p) ) { - case 58: goto st16; - case 70: goto st50; - case 93: goto st137; - case 102: goto st50; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st14; - } else if ( (*p) > 69 ) { - if ( 97 <= (*p) && (*p) <= 101 ) - goto st14; - } else - goto st14; - goto st0; -st50: - if ( ++p == pe ) - goto _test_eof50; -case 50: - switch( (*p) ) { - case 58: goto st16; - case 70: goto st51; - case 93: goto st137; - case 102: goto st51; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st15; - } else if ( (*p) > 69 ) { - if ( 97 <= (*p) && (*p) <= 101 ) - goto st15; - } else - goto st15; - goto st0; -st51: - if ( ++p == pe ) - goto _test_eof51; -case 51: - switch( (*p) ) { - case 58: goto st52; - case 93: goto st137; - } - goto st0; -st52: - if ( ++p == pe ) - goto _test_eof52; -case 52: - switch( (*p) ) { - case 58: goto st21; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr64; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st17; - } else - goto st17; - goto st0; -tr64: -#line 144 "src/uri.rl" - { ip4.start = p; } - goto st53; -st53: - if ( ++p == pe ) - goto _test_eof53; -case 53: -#line 1987 "src/uri.cc" - switch( (*p) ) { - case 46: goto st54; - case 58: goto st21; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st66; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st18; - } else - goto st18; - goto st0; -st54: - if ( ++p == pe ) - goto _test_eof54; -case 54: - if ( 48 <= (*p) && (*p) <= 57 ) - goto st55; - goto st0; -st55: - if ( ++p == pe ) - goto _test_eof55; -case 55: - if ( (*p) == 46 ) - goto st56; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st64; - goto st0; -st56: - if ( ++p == pe ) - goto _test_eof56; -case 56: - if ( 48 <= (*p) && (*p) <= 57 ) - goto st57; - goto st0; -st57: - if ( ++p == pe ) - goto _test_eof57; -case 57: - if ( (*p) == 46 ) - goto st58; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st62; - goto st0; -st58: - if ( ++p == pe ) - goto _test_eof58; -case 58: - if ( 48 <= (*p) && (*p) <= 57 ) - goto st59; - goto st0; -st59: - if ( ++p == pe ) - goto _test_eof59; -case 59: - if ( (*p) == 93 ) - goto tr75; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st60; - goto st0; -st60: - if ( ++p == pe ) - goto _test_eof60; -case 60: - if ( (*p) == 93 ) - goto tr75; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st61; - goto st0; -st61: - if ( ++p == pe ) - goto _test_eof61; -case 61: - if ( (*p) == 93 ) - goto tr75; - goto st0; -tr75: -#line 145 "src/uri.rl" - { ip4.end = p; } - goto st146; -st146: - if ( ++p == pe ) - goto _test_eof146; -case 146: -#line 2074 "src/uri.cc" - if ( (*p) == 58 ) - goto tr94; - goto st0; -st62: - if ( ++p == pe ) - goto _test_eof62; -case 62: - if ( (*p) == 46 ) - goto st58; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st63; - goto st0; -st63: - if ( ++p == pe ) - goto _test_eof63; -case 63: - if ( (*p) == 46 ) - goto st58; - goto st0; -st64: - if ( ++p == pe ) - goto _test_eof64; -case 64: - if ( (*p) == 46 ) - goto st56; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st65; - goto st0; -st65: - if ( ++p == pe ) - goto _test_eof65; -case 65: - if ( (*p) == 46 ) - goto st56; - goto st0; -st66: - if ( ++p == pe ) - goto _test_eof66; -case 66: - switch( (*p) ) { - case 46: goto st54; - case 58: goto st21; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st67; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st19; - } else - goto st19; - goto st0; -st67: - if ( ++p == pe ) - goto _test_eof67; -case 67: - switch( (*p) ) { - case 46: goto st54; - case 58: goto st21; - case 93: goto st137; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st20; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st20; - } else - goto st20; - goto st0; -tr11: -#line 140 "src/uri.rl" - { password.start = p; } -#line 166 "src/uri.rl" - { service.start = p; } -#line 161 "src/uri.rl" - { dport.start = p; port = 0; } -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st147; -tr164: -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st147; -st147: - if ( ++p == pe ) - goto _test_eof147; -case 147: -#line 2164 "src/uri.cc" - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr164; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st4; - } else - goto st4; - goto st0; -tr12: -#line 140 "src/uri.rl" - { password.start = p; } -#line 166 "src/uri.rl" - { service.start = p; } - goto st148; -st148: - if ( ++p == pe ) - goto _test_eof148; -case 148: -#line 2186 "src/uri.cc" - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st149; - } else - goto st149; - goto st0; -st149: - if ( ++p == pe ) - goto _test_eof149; -case 149: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st150; - } else - goto st150; - goto st0; -st150: - if ( ++p == pe ) - goto _test_eof150; -case 150: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st151; - } else - goto st151; - goto st0; -st151: - if ( ++p == pe ) - goto _test_eof151; -case 151: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st152; - } else - goto st152; - goto st0; -st152: - if ( ++p == pe ) - goto _test_eof152; -case 152: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st153; - } else - goto st153; - goto st0; -st153: - if ( ++p == pe ) - goto _test_eof153; -case 153: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st154; - } else - goto st154; - goto st0; -st154: - if ( ++p == pe ) - goto _test_eof154; -case 154: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st155; - } else - goto st155; - goto st0; -st155: - if ( ++p == pe ) - goto _test_eof155; -case 155: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st156; - } else - goto st156; - goto st0; -st156: - if ( ++p == pe ) - goto _test_eof156; -case 156: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st157; - } else - goto st157; - goto st0; -st157: - if ( ++p == pe ) - goto _test_eof157; -case 157: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st158; - } else - goto st158; - goto st0; -st158: - if ( ++p == pe ) - goto _test_eof158; -case 158: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st159; - } else - goto st159; - goto st0; -st159: - if ( ++p == pe ) - goto _test_eof159; -case 159: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st160; - } else - goto st160; - goto st0; -st160: - if ( ++p == pe ) - goto _test_eof160; -case 160: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st161; - } else - goto st161; - goto st0; -st161: - if ( ++p == pe ) - goto _test_eof161; -case 161: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st162; - } else - goto st162; - goto st0; -st162: - if ( ++p == pe ) - goto _test_eof162; -case 162: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st163; - } else - goto st163; - goto st0; -st163: - if ( ++p == pe ) - goto _test_eof163; -case 163: - if ( (*p) == 64 ) - goto tr14; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st4; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st4; - } else - goto st4; - goto st0; -tr3: -#line 136 "src/uri.rl" - { login.start = p; } -#line 157 "src/uri.rl" - { host.start = p; } -#line 144 "src/uri.rl" - { ip4.start = p; } -#line 171 "src/uri.rl" - { sport.start = p; port = 0; } -#line 172 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st164; -st164: - if ( ++p == pe ) - goto _test_eof164; -case 164: -#line 2439 "src/uri.cc" - switch( (*p) ) { - case 46: goto st114; - case 58: goto tr134; - case 63: goto st0; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr180; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st128; - } else - goto st128; - goto st74; -tr180: -#line 172 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st165; -st165: - if ( ++p == pe ) - goto _test_eof165; -case 165: -#line 2462 "src/uri.cc" - switch( (*p) ) { - case 46: goto st114; - case 58: goto tr134; - case 63: goto st0; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr181; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st128; - } else - goto st128; - goto st74; -tr181: -#line 172 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st166; -st166: - if ( ++p == pe ) - goto _test_eof166; -case 166: -#line 2485 "src/uri.cc" - switch( (*p) ) { - case 46: goto st114; - case 58: goto tr134; - case 63: goto st0; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr182; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st128; - } else - goto st128; - goto st74; -tr182: -#line 172 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st167; -st167: - if ( ++p == pe ) - goto _test_eof167; -case 167: -#line 2508 "src/uri.cc" - switch( (*p) ) { - case 58: goto tr134; - case 63: goto st0; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr182; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st128; - } else - goto st128; - goto st74; -tr5: -#line 132 "src/uri.rl" - { schema.start = p; } -#line 136 "src/uri.rl" - { login.start = p; } -#line 157 "src/uri.rl" - { host.start = p; } - goto st168; -st168: - if ( ++p == pe ) - goto _test_eof168; -case 168: -#line 2534 "src/uri.cc" - switch( (*p) ) { - case 58: goto tr183; - case 63: goto st0; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st128; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st168; - } else - goto st168; - goto st74; -tr183: -#line 137 "src/uri.rl" - { login.end = p; } -#line 158 "src/uri.rl" - { host.end = p; } - goto st68; -st68: - if ( ++p == pe ) - goto _test_eof68; -case 68: -#line 2558 "src/uri.cc" - switch( (*p) ) { - case 47: goto st69; - case 48: goto tr10; - } - if ( (*p) < 65 ) { - if ( 49 <= (*p) && (*p) <= 57 ) - goto tr11; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto tr12; - } else - goto tr12; - goto st0; -st69: - if ( ++p == pe ) - goto _test_eof69; -case 69: - if ( (*p) == 47 ) - goto st70; - goto st0; -st70: - if ( ++p == pe ) - goto _test_eof70; -case 70: - switch( (*p) ) { - case 58: goto st0; - case 63: goto st0; - case 91: goto tr85; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr83; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto tr84; - } else - goto tr84; - goto tr82; -tr7: -#line 132 "src/uri.rl" - { schema.start = p; } -#line 136 "src/uri.rl" - { login.start = p; } -#line 157 "src/uri.rl" - { host.start = p; } - goto st169; -st169: - if ( ++p == pe ) - goto _test_eof169; -case 169: -#line 2609 "src/uri.cc" - switch( (*p) ) { - case 58: goto tr183; - case 63: goto st0; - case 110: goto st170; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st128; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st168; - } else - goto st168; - goto st74; -st170: - if ( ++p == pe ) - goto _test_eof170; -case 170: - switch( (*p) ) { - case 58: goto tr183; - case 63: goto st0; - case 105: goto st171; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st128; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st168; - } else - goto st168; - goto st74; -st171: - if ( ++p == pe ) - goto _test_eof171; -case 171: - switch( (*p) ) { - case 58: goto tr183; - case 63: goto st0; - case 120: goto st172; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st128; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st168; - } else - goto st168; - goto st74; -st172: - if ( ++p == pe ) - goto _test_eof172; -case 172: - switch( (*p) ) { - case 58: goto tr188; - case 63: goto st0; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st128; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st168; - } else - goto st168; - goto st74; -tr188: -#line 137 "src/uri.rl" - { login.end = p; } -#line 158 "src/uri.rl" - { host.end = p; } - goto st71; -st71: - if ( ++p == pe ) - goto _test_eof71; -case 71: -#line 2687 "src/uri.cc" - switch( (*p) ) { - case 47: goto st72; - case 48: goto tr10; - } - if ( (*p) < 65 ) { - if ( 49 <= (*p) && (*p) <= 57 ) - goto tr11; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto tr12; - } else - goto tr12; - goto st0; -st72: - if ( ++p == pe ) - goto _test_eof72; -case 72: - if ( (*p) == 47 ) - goto st73; - goto st0; -st73: - if ( ++p == pe ) - goto _test_eof73; -case 73: - switch( (*p) ) { - case 58: goto tr90; - case 63: goto tr90; - case 91: goto tr92; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr89; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto tr91; - } else - goto tr91; - goto tr88; -tr88: -#line 180 "src/uri.rl" - { path.start = p; } -#line 133 "src/uri.rl" - { schema.end = p - 3; } -#line 157 "src/uri.rl" - { host.start = p; } - goto st173; -tr232: -#line 180 "src/uri.rl" - { path.start = p; } -#line 157 "src/uri.rl" - { host.start = p; } - goto st173; -st173: - if ( ++p == pe ) - goto _test_eof173; -case 173: -#line 2744 "src/uri.cc" - switch( (*p) ) { - case 58: goto tr190; - case 63: goto st175; - } - goto st173; -tr190: -#line 158 "src/uri.rl" - { host.end = p; } - goto st174; -tr222: -#line 145 "src/uri.rl" - { ip4.end = p; } -#line 158 "src/uri.rl" - { host.end = p; } - goto st174; -tr285: -#line 154 "src/uri.rl" - { ip6.end = p - 1; } -#line 158 "src/uri.rl" - { host.end = p; } - goto st174; -st174: - if ( ++p == pe ) - goto _test_eof174; -case 174: -#line 2770 "src/uri.cc" - if ( (*p) < 65 ) { - if ( 49 <= (*p) && (*p) <= 57 ) - goto tr192; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto tr193; - } else - goto tr193; - goto st175; -tr90: -#line 180 "src/uri.rl" - { path.start = p; } - goto st175; -st175: - if ( ++p == pe ) - goto _test_eof175; -case 175: -#line 2788 "src/uri.cc" - goto st175; -tr192: -#line 166 "src/uri.rl" - { service.start = p; } -#line 161 "src/uri.rl" - { dport.start = p; port = 0; } -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st176; -tr194: -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st176; -st176: - if ( ++p == pe ) - goto _test_eof176; -case 176: -#line 2806 "src/uri.cc" - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr194; - goto st175; -tr193: -#line 166 "src/uri.rl" - { service.start = p; } - goto st177; -st177: - if ( ++p == pe ) - goto _test_eof177; -case 177: -#line 2818 "src/uri.cc" - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st178; - } else if ( (*p) >= 65 ) - goto st178; - goto st175; -st178: - if ( ++p == pe ) - goto _test_eof178; -case 178: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st179; - } else if ( (*p) >= 65 ) - goto st179; - goto st175; -st179: - if ( ++p == pe ) - goto _test_eof179; -case 179: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st180; - } else if ( (*p) >= 65 ) - goto st180; - goto st175; -st180: - if ( ++p == pe ) - goto _test_eof180; -case 180: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st181; - } else if ( (*p) >= 65 ) - goto st181; - goto st175; -st181: - if ( ++p == pe ) - goto _test_eof181; -case 181: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st182; - } else if ( (*p) >= 65 ) - goto st182; - goto st175; -st182: - if ( ++p == pe ) - goto _test_eof182; -case 182: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st183; - } else if ( (*p) >= 65 ) - goto st183; - goto st175; -st183: - if ( ++p == pe ) - goto _test_eof183; -case 183: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st184; - } else if ( (*p) >= 65 ) - goto st184; - goto st175; -st184: - if ( ++p == pe ) - goto _test_eof184; -case 184: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st185; - } else if ( (*p) >= 65 ) - goto st185; - goto st175; -st185: - if ( ++p == pe ) - goto _test_eof185; -case 185: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st186; - } else if ( (*p) >= 65 ) - goto st186; - goto st175; -st186: - if ( ++p == pe ) - goto _test_eof186; -case 186: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st187; - } else if ( (*p) >= 65 ) - goto st187; - goto st175; -st187: - if ( ++p == pe ) - goto _test_eof187; -case 187: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st188; - } else if ( (*p) >= 65 ) - goto st188; - goto st175; -st188: - if ( ++p == pe ) - goto _test_eof188; -case 188: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st189; - } else if ( (*p) >= 65 ) - goto st189; - goto st175; -st189: - if ( ++p == pe ) - goto _test_eof189; -case 189: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st190; - } else if ( (*p) >= 65 ) - goto st190; - goto st175; -st190: - if ( ++p == pe ) - goto _test_eof190; -case 190: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st191; - } else if ( (*p) >= 65 ) - goto st191; - goto st175; -st191: - if ( ++p == pe ) - goto _test_eof191; -case 191: - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st192; - } else if ( (*p) >= 65 ) - goto st192; - goto st175; -st192: - if ( ++p == pe ) - goto _test_eof192; -case 192: - goto st175; -tr89: -#line 136 "src/uri.rl" - { login.start = p; } -#line 180 "src/uri.rl" - { path.start = p; } -#line 133 "src/uri.rl" - { schema.end = p - 3; } -#line 157 "src/uri.rl" - { host.start = p; } -#line 144 "src/uri.rl" - { ip4.start = p; } - goto st193; -st193: - if ( ++p == pe ) - goto _test_eof193; -case 193: -#line 2986 "src/uri.cc" - switch( (*p) ) { - case 46: goto st194; - case 58: goto tr212; - case 63: goto st175; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st206; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st208; - } else - goto st208; - goto st173; -st194: - if ( ++p == pe ) - goto _test_eof194; -case 194: - switch( (*p) ) { - case 58: goto tr190; - case 63: goto st175; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st195; - goto st173; -st195: - if ( ++p == pe ) - goto _test_eof195; -case 195: - switch( (*p) ) { - case 46: goto st196; - case 58: goto tr190; - case 63: goto st175; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st204; - goto st173; -st196: - if ( ++p == pe ) - goto _test_eof196; -case 196: - switch( (*p) ) { - case 58: goto tr190; - case 63: goto st175; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st197; - goto st173; -st197: - if ( ++p == pe ) - goto _test_eof197; -case 197: - switch( (*p) ) { - case 46: goto st198; - case 58: goto tr190; - case 63: goto st175; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st202; - goto st173; -st198: - if ( ++p == pe ) - goto _test_eof198; -case 198: - switch( (*p) ) { - case 58: goto tr190; - case 63: goto st175; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st199; - goto st173; -st199: - if ( ++p == pe ) - goto _test_eof199; -case 199: - switch( (*p) ) { - case 58: goto tr222; - case 63: goto st175; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st200; - goto st173; -st200: - if ( ++p == pe ) - goto _test_eof200; -case 200: - switch( (*p) ) { - case 58: goto tr222; - case 63: goto st175; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st201; - goto st173; -st201: - if ( ++p == pe ) - goto _test_eof201; -case 201: - switch( (*p) ) { - case 58: goto tr222; - case 63: goto st175; - } - goto st173; -st202: - if ( ++p == pe ) - goto _test_eof202; -case 202: - switch( (*p) ) { - case 46: goto st198; - case 58: goto tr190; - case 63: goto st175; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st203; - goto st173; -st203: - if ( ++p == pe ) - goto _test_eof203; -case 203: - switch( (*p) ) { - case 46: goto st198; - case 58: goto tr190; - case 63: goto st175; - } - goto st173; -st204: - if ( ++p == pe ) - goto _test_eof204; -case 204: - switch( (*p) ) { - case 46: goto st196; - case 58: goto tr190; - case 63: goto st175; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st205; - goto st173; -st205: - if ( ++p == pe ) - goto _test_eof205; -case 205: - switch( (*p) ) { - case 46: goto st196; - case 58: goto tr190; - case 63: goto st175; - } - goto st173; -st206: - if ( ++p == pe ) - goto _test_eof206; -case 206: - switch( (*p) ) { - case 46: goto st194; - case 58: goto tr212; - case 63: goto st175; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st207; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st208; - } else - goto st208; - goto st173; -st207: - if ( ++p == pe ) - goto _test_eof207; -case 207: - switch( (*p) ) { - case 46: goto st194; - case 58: goto tr212; - case 63: goto st175; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st208; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st208; - } else - goto st208; - goto st173; -tr91: -#line 136 "src/uri.rl" - { login.start = p; } -#line 180 "src/uri.rl" - { path.start = p; } -#line 133 "src/uri.rl" - { schema.end = p - 3; } -#line 157 "src/uri.rl" - { host.start = p; } - goto st208; -st208: - if ( ++p == pe ) - goto _test_eof208; -case 208: -#line 3183 "src/uri.cc" - switch( (*p) ) { - case 58: goto tr212; - case 63: goto st175; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st208; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st208; - } else - goto st208; - goto st173; -tr212: -#line 137 "src/uri.rl" - { login.end = p; } -#line 158 "src/uri.rl" - { host.end = p; } - goto st209; -st209: - if ( ++p == pe ) - goto _test_eof209; -case 209: -#line 3207 "src/uri.cc" - if ( (*p) == 48 ) - goto tr227; - if ( (*p) < 65 ) { - if ( 49 <= (*p) && (*p) <= 57 ) - goto tr228; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto tr229; - } else - goto tr229; - goto st175; -tr227: -#line 140 "src/uri.rl" - { password.start = p; } - goto st210; -st210: - if ( ++p == pe ) - goto _test_eof210; -case 210: -#line 3227 "src/uri.cc" - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st210; - } else - goto st210; - goto st175; -tr231: -#line 141 "src/uri.rl" - { password.end = p; } - goto st211; -st211: - if ( ++p == pe ) - goto _test_eof211; -case 211: -#line 3247 "src/uri.cc" - switch( (*p) ) { - case 58: goto tr90; - case 63: goto tr90; - case 91: goto tr234; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr233; - goto tr232; -tr233: -#line 180 "src/uri.rl" - { path.start = p; } -#line 157 "src/uri.rl" - { host.start = p; } -#line 144 "src/uri.rl" - { ip4.start = p; } - goto st212; -st212: - if ( ++p == pe ) - goto _test_eof212; -case 212: -#line 3268 "src/uri.cc" - switch( (*p) ) { - case 46: goto st194; - case 58: goto tr190; - case 63: goto st175; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st213; - goto st173; -st213: - if ( ++p == pe ) - goto _test_eof213; -case 213: - switch( (*p) ) { - case 46: goto st194; - case 58: goto tr190; - case 63: goto st175; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st214; - goto st173; -st214: - if ( ++p == pe ) - goto _test_eof214; -case 214: - switch( (*p) ) { - case 46: goto st194; - case 58: goto tr190; - case 63: goto st175; - } - goto st173; -tr92: -#line 180 "src/uri.rl" - { path.start = p; } -#line 133 "src/uri.rl" - { schema.end = p - 3; } -#line 157 "src/uri.rl" - { host.start = p; } -#line 153 "src/uri.rl" - { ip6.start = p + 1; } - goto st215; -tr234: -#line 180 "src/uri.rl" - { path.start = p; } -#line 157 "src/uri.rl" - { host.start = p; } -#line 153 "src/uri.rl" - { ip6.start = p + 1; } - goto st215; -st215: - if ( ++p == pe ) - goto _test_eof215; -case 215: -#line 3321 "src/uri.cc" - switch( (*p) ) { - case 58: goto tr238; - case 63: goto st175; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st216; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st216; - } else - goto st216; - goto st173; -st216: - if ( ++p == pe ) - goto _test_eof216; -case 216: - switch( (*p) ) { - case 58: goto tr240; - case 63: goto st175; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st217; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st217; - } else - goto st217; - goto st173; -st217: - if ( ++p == pe ) - goto _test_eof217; -case 217: - switch( (*p) ) { - case 58: goto tr240; - case 63: goto st175; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st218; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st218; - } else - goto st218; - goto st173; -st218: - if ( ++p == pe ) - goto _test_eof218; -case 218: - switch( (*p) ) { - case 58: goto tr240; - case 63: goto st175; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st219; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st219; - } else - goto st219; - goto st173; -st219: - if ( ++p == pe ) - goto _test_eof219; -case 219: - switch( (*p) ) { - case 58: goto tr240; - case 63: goto st175; - } - goto st173; -tr240: -#line 158 "src/uri.rl" - { host.end = p; } - goto st220; -st220: - if ( ++p == pe ) - goto _test_eof220; -case 220: -#line 3403 "src/uri.cc" - switch( (*p) ) { - case 48: goto st221; - case 58: goto st225; - case 93: goto st260; - } - if ( (*p) < 71 ) { - if ( (*p) > 57 ) { - if ( 65 <= (*p) && (*p) <= 70 ) - goto tr246; - } else if ( (*p) >= 49 ) - goto tr244; - } else if ( (*p) > 90 ) { - if ( (*p) > 102 ) { - if ( 103 <= (*p) && (*p) <= 122 ) - goto tr193; - } else if ( (*p) >= 97 ) - goto tr246; - } else - goto tr193; - goto st175; -st221: - if ( ++p == pe ) - goto _test_eof221; -case 221: - switch( (*p) ) { - case 58: goto st225; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st222; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st222; - } else - goto st222; - goto st175; -st222: - if ( ++p == pe ) - goto _test_eof222; -case 222: - switch( (*p) ) { - case 58: goto st225; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st223; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st223; - } else - goto st223; - goto st175; -st223: - if ( ++p == pe ) - goto _test_eof223; -case 223: - switch( (*p) ) { - case 58: goto st225; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st224; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st224; - } else - goto st224; - goto st175; -st224: - if ( ++p == pe ) - goto _test_eof224; -case 224: - switch( (*p) ) { - case 58: goto st225; - case 93: goto st260; - } - goto st175; -st225: - if ( ++p == pe ) - goto _test_eof225; -case 225: - switch( (*p) ) { - case 58: goto st230; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st226; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st226; - } else - goto st226; - goto st175; -st226: - if ( ++p == pe ) - goto _test_eof226; -case 226: - switch( (*p) ) { - case 58: goto st230; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st227; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st227; - } else - goto st227; - goto st175; -st227: - if ( ++p == pe ) - goto _test_eof227; -case 227: - switch( (*p) ) { - case 58: goto st230; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st228; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st228; - } else - goto st228; - goto st175; -st228: - if ( ++p == pe ) - goto _test_eof228; -case 228: - switch( (*p) ) { - case 58: goto st230; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st229; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st229; - } else - goto st229; - goto st175; -st229: - if ( ++p == pe ) - goto _test_eof229; -case 229: - switch( (*p) ) { - case 58: goto st230; - case 93: goto st260; - } - goto st175; -st230: - if ( ++p == pe ) - goto _test_eof230; -case 230: - switch( (*p) ) { - case 58: goto st235; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st231; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st231; - } else - goto st231; - goto st175; -st231: - if ( ++p == pe ) - goto _test_eof231; -case 231: - switch( (*p) ) { - case 58: goto st235; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st232; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st232; - } else - goto st232; - goto st175; -st232: - if ( ++p == pe ) - goto _test_eof232; -case 232: - switch( (*p) ) { - case 58: goto st235; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st233; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st233; - } else - goto st233; - goto st175; -st233: - if ( ++p == pe ) - goto _test_eof233; -case 233: - switch( (*p) ) { - case 58: goto st235; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st234; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st234; - } else - goto st234; - goto st175; -st234: - if ( ++p == pe ) - goto _test_eof234; -case 234: - switch( (*p) ) { - case 58: goto st235; - case 93: goto st260; - } - goto st175; -st235: - if ( ++p == pe ) - goto _test_eof235; -case 235: - switch( (*p) ) { - case 58: goto st240; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st236; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st236; - } else - goto st236; - goto st175; -st236: - if ( ++p == pe ) - goto _test_eof236; -case 236: - switch( (*p) ) { - case 58: goto st240; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st237; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st237; - } else - goto st237; - goto st175; -st237: - if ( ++p == pe ) - goto _test_eof237; -case 237: - switch( (*p) ) { - case 58: goto st240; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st238; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st238; - } else - goto st238; - goto st175; -st238: - if ( ++p == pe ) - goto _test_eof238; -case 238: - switch( (*p) ) { - case 58: goto st240; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st239; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st239; - } else - goto st239; - goto st175; -st239: - if ( ++p == pe ) - goto _test_eof239; -case 239: - switch( (*p) ) { - case 58: goto st240; - case 93: goto st260; - } - goto st175; -st240: - if ( ++p == pe ) - goto _test_eof240; -case 240: - switch( (*p) ) { - case 58: goto st245; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st241; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st241; - } else - goto st241; - goto st175; -st241: - if ( ++p == pe ) - goto _test_eof241; -case 241: - switch( (*p) ) { - case 58: goto st245; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st242; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st242; - } else - goto st242; - goto st175; -st242: - if ( ++p == pe ) - goto _test_eof242; -case 242: - switch( (*p) ) { - case 58: goto st245; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st243; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st243; - } else - goto st243; - goto st175; -st243: - if ( ++p == pe ) - goto _test_eof243; -case 243: - switch( (*p) ) { - case 58: goto st245; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st244; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st244; - } else - goto st244; - goto st175; -st244: - if ( ++p == pe ) - goto _test_eof244; -case 244: - switch( (*p) ) { - case 58: goto st245; - case 93: goto st260; - } - goto st175; -st245: - if ( ++p == pe ) - goto _test_eof245; -case 245: - switch( (*p) ) { - case 58: goto st250; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st246; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st246; - } else - goto st246; - goto st175; -st246: - if ( ++p == pe ) - goto _test_eof246; -case 246: - switch( (*p) ) { - case 58: goto st250; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st247; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st247; - } else - goto st247; - goto st175; -st247: - if ( ++p == pe ) - goto _test_eof247; -case 247: - switch( (*p) ) { - case 58: goto st250; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st248; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st248; - } else - goto st248; - goto st175; -st248: - if ( ++p == pe ) - goto _test_eof248; -case 248: - switch( (*p) ) { - case 58: goto st250; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st249; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st249; - } else - goto st249; - goto st175; -st249: - if ( ++p == pe ) - goto _test_eof249; -case 249: - switch( (*p) ) { - case 58: goto st250; - case 93: goto st260; - } - goto st175; -st250: - if ( ++p == pe ) - goto _test_eof250; -case 250: - switch( (*p) ) { - case 58: goto st255; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st251; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st251; - } else - goto st251; - goto st175; -st251: - if ( ++p == pe ) - goto _test_eof251; -case 251: - switch( (*p) ) { - case 58: goto st255; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st252; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st252; - } else - goto st252; - goto st175; -st252: - if ( ++p == pe ) - goto _test_eof252; -case 252: - switch( (*p) ) { - case 58: goto st255; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st253; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st253; - } else - goto st253; - goto st175; -st253: - if ( ++p == pe ) - goto _test_eof253; -case 253: - switch( (*p) ) { - case 58: goto st255; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st254; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st254; - } else - goto st254; - goto st175; -st254: - if ( ++p == pe ) - goto _test_eof254; -case 254: - switch( (*p) ) { - case 58: goto st255; - case 93: goto st260; - } - goto st175; -st255: - if ( ++p == pe ) - goto _test_eof255; -case 255: - if ( (*p) == 93 ) - goto st260; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st256; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st256; - } else - goto st256; - goto st175; -st256: - if ( ++p == pe ) - goto _test_eof256; -case 256: - if ( (*p) == 93 ) - goto st260; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st257; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st257; - } else - goto st257; - goto st175; -st257: - if ( ++p == pe ) - goto _test_eof257; -case 257: - if ( (*p) == 93 ) - goto st260; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st258; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st258; - } else - goto st258; - goto st175; -st258: - if ( ++p == pe ) - goto _test_eof258; -case 258: - if ( (*p) == 93 ) - goto st260; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st259; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st259; - } else - goto st259; - goto st175; -st259: - if ( ++p == pe ) - goto _test_eof259; -case 259: - if ( (*p) == 93 ) - goto st260; - goto st175; -st260: - if ( ++p == pe ) - goto _test_eof260; -case 260: - if ( (*p) == 58 ) - goto tr285; - goto st175; -tr244: -#line 166 "src/uri.rl" - { service.start = p; } -#line 161 "src/uri.rl" - { dport.start = p; port = 0; } -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st261; -st261: - if ( ++p == pe ) - goto _test_eof261; -case 261: -#line 4032 "src/uri.cc" - switch( (*p) ) { - case 58: goto st225; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr286; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st222; - } else - goto st222; - goto st175; -tr286: -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st262; -st262: - if ( ++p == pe ) - goto _test_eof262; -case 262: -#line 4054 "src/uri.cc" - switch( (*p) ) { - case 58: goto st225; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr287; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st223; - } else - goto st223; - goto st175; -tr287: -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st263; -st263: - if ( ++p == pe ) - goto _test_eof263; -case 263: -#line 4076 "src/uri.cc" - switch( (*p) ) { - case 58: goto st225; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr288; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st224; - } else - goto st224; - goto st175; -tr288: -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st264; -st264: - if ( ++p == pe ) - goto _test_eof264; -case 264: -#line 4098 "src/uri.cc" - switch( (*p) ) { - case 58: goto st225; - case 93: goto st260; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr194; - goto st175; -tr246: -#line 166 "src/uri.rl" - { service.start = p; } - goto st265; -st265: - if ( ++p == pe ) - goto _test_eof265; -case 265: -#line 4114 "src/uri.cc" - switch( (*p) ) { - case 58: goto st225; - case 93: goto st260; - } - if ( (*p) < 71 ) { - if ( (*p) > 57 ) { - if ( 65 <= (*p) && (*p) <= 70 ) - goto st266; - } else if ( (*p) >= 48 ) - goto st222; - } else if ( (*p) > 90 ) { - if ( (*p) > 102 ) { - if ( 103 <= (*p) && (*p) <= 122 ) - goto st178; - } else if ( (*p) >= 97 ) - goto st266; - } else - goto st178; - goto st175; -st266: - if ( ++p == pe ) - goto _test_eof266; -case 266: - switch( (*p) ) { - case 58: goto st225; - case 93: goto st260; - } - if ( (*p) < 71 ) { - if ( (*p) > 57 ) { - if ( 65 <= (*p) && (*p) <= 70 ) - goto st267; - } else if ( (*p) >= 48 ) - goto st223; - } else if ( (*p) > 90 ) { - if ( (*p) > 102 ) { - if ( 103 <= (*p) && (*p) <= 122 ) - goto st179; - } else if ( (*p) >= 97 ) - goto st267; - } else - goto st179; - goto st175; -st267: - if ( ++p == pe ) - goto _test_eof267; -case 267: - switch( (*p) ) { - case 58: goto st225; - case 93: goto st260; - } - if ( (*p) < 71 ) { - if ( (*p) > 57 ) { - if ( 65 <= (*p) && (*p) <= 70 ) - goto st268; - } else if ( (*p) >= 48 ) - goto st224; - } else if ( (*p) > 90 ) { - if ( (*p) > 102 ) { - if ( 103 <= (*p) && (*p) <= 122 ) - goto st180; - } else if ( (*p) >= 97 ) - goto st268; - } else - goto st180; - goto st175; -st268: - if ( ++p == pe ) - goto _test_eof268; -case 268: - switch( (*p) ) { - case 58: goto st225; - case 93: goto st260; - } - if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st181; - } else if ( (*p) >= 65 ) - goto st181; - goto st175; -tr238: -#line 158 "src/uri.rl" - { host.end = p; } - goto st269; -st269: - if ( ++p == pe ) - goto _test_eof269; -case 269: -#line 4202 "src/uri.cc" - switch( (*p) ) { - case 48: goto st221; - case 58: goto st270; - case 93: goto st260; - } - if ( (*p) < 71 ) { - if ( (*p) > 57 ) { - if ( 65 <= (*p) && (*p) <= 70 ) - goto tr246; - } else if ( (*p) >= 49 ) - goto tr244; - } else if ( (*p) > 90 ) { - if ( (*p) > 102 ) { - if ( 103 <= (*p) && (*p) <= 122 ) - goto tr193; - } else if ( (*p) >= 97 ) - goto tr246; - } else - goto tr193; - goto st175; -st270: - if ( ++p == pe ) - goto _test_eof270; -case 270: - switch( (*p) ) { - case 58: goto st230; - case 70: goto st271; - case 93: goto st260; - case 102: goto st271; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st226; - } else if ( (*p) > 69 ) { - if ( 97 <= (*p) && (*p) <= 101 ) - goto st226; - } else - goto st226; - goto st175; -st271: - if ( ++p == pe ) - goto _test_eof271; -case 271: - switch( (*p) ) { - case 58: goto st230; - case 70: goto st272; - case 93: goto st260; - case 102: goto st272; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st227; - } else if ( (*p) > 69 ) { - if ( 97 <= (*p) && (*p) <= 101 ) - goto st227; - } else - goto st227; - goto st175; -st272: - if ( ++p == pe ) - goto _test_eof272; -case 272: - switch( (*p) ) { - case 58: goto st230; - case 70: goto st273; - case 93: goto st260; - case 102: goto st273; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st228; - } else if ( (*p) > 69 ) { - if ( 97 <= (*p) && (*p) <= 101 ) - goto st228; - } else - goto st228; - goto st175; -st273: - if ( ++p == pe ) - goto _test_eof273; -case 273: - switch( (*p) ) { - case 58: goto st230; - case 70: goto st274; - case 93: goto st260; - case 102: goto st274; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st229; - } else if ( (*p) > 69 ) { - if ( 97 <= (*p) && (*p) <= 101 ) - goto st229; - } else - goto st229; - goto st175; -st274: - if ( ++p == pe ) - goto _test_eof274; -case 274: - switch( (*p) ) { - case 58: goto st275; - case 93: goto st260; - } - goto st175; -st275: - if ( ++p == pe ) - goto _test_eof275; -case 275: - switch( (*p) ) { - case 58: goto st235; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr298; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st231; - } else - goto st231; - goto st175; -tr298: -#line 144 "src/uri.rl" - { ip4.start = p; } - goto st276; -st276: - if ( ++p == pe ) - goto _test_eof276; -case 276: -#line 4333 "src/uri.cc" - switch( (*p) ) { - case 46: goto st277; - case 58: goto st235; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st290; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st232; - } else - goto st232; - goto st175; -st277: - if ( ++p == pe ) - goto _test_eof277; -case 277: - if ( 48 <= (*p) && (*p) <= 57 ) - goto st278; - goto st175; -st278: - if ( ++p == pe ) - goto _test_eof278; -case 278: - if ( (*p) == 46 ) - goto st279; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st288; - goto st175; -st279: - if ( ++p == pe ) - goto _test_eof279; -case 279: - if ( 48 <= (*p) && (*p) <= 57 ) - goto st280; - goto st175; -st280: - if ( ++p == pe ) - goto _test_eof280; -case 280: - if ( (*p) == 46 ) - goto st281; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st286; - goto st175; -st281: - if ( ++p == pe ) - goto _test_eof281; -case 281: - if ( 48 <= (*p) && (*p) <= 57 ) - goto st282; - goto st175; -st282: - if ( ++p == pe ) - goto _test_eof282; -case 282: - if ( (*p) == 93 ) - goto tr309; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st283; - goto st175; -st283: - if ( ++p == pe ) - goto _test_eof283; -case 283: - if ( (*p) == 93 ) - goto tr309; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st284; - goto st175; -st284: - if ( ++p == pe ) - goto _test_eof284; -case 284: - if ( (*p) == 93 ) - goto tr309; - goto st175; -tr309: -#line 145 "src/uri.rl" - { ip4.end = p; } - goto st285; -st285: - if ( ++p == pe ) - goto _test_eof285; -case 285: -#line 4420 "src/uri.cc" - if ( (*p) == 58 ) - goto tr190; - goto st175; -st286: - if ( ++p == pe ) - goto _test_eof286; -case 286: - if ( (*p) == 46 ) - goto st281; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st287; - goto st175; -st287: - if ( ++p == pe ) - goto _test_eof287; -case 287: - if ( (*p) == 46 ) - goto st281; - goto st175; -st288: - if ( ++p == pe ) - goto _test_eof288; -case 288: - if ( (*p) == 46 ) - goto st279; - if ( 48 <= (*p) && (*p) <= 57 ) - goto st289; - goto st175; -st289: - if ( ++p == pe ) - goto _test_eof289; -case 289: - if ( (*p) == 46 ) - goto st279; - goto st175; -st290: - if ( ++p == pe ) - goto _test_eof290; -case 290: - switch( (*p) ) { - case 46: goto st277; - case 58: goto st235; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st291; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st233; - } else - goto st233; - goto st175; -st291: - if ( ++p == pe ) - goto _test_eof291; -case 291: - switch( (*p) ) { - case 46: goto st277; - case 58: goto st235; - case 93: goto st260; - } - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st234; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st234; - } else - goto st234; - goto st175; -tr228: -#line 140 "src/uri.rl" - { password.start = p; } -#line 166 "src/uri.rl" - { service.start = p; } -#line 161 "src/uri.rl" - { dport.start = p; port = 0; } -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st292; -tr314: -#line 162 "src/uri.rl" - { port = port * 10 + (int)(*p - '0'); } - goto st292; -st292: - if ( ++p == pe ) - goto _test_eof292; -case 292: -#line 4510 "src/uri.cc" - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr314; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st210; - } else - goto st210; - goto st175; -tr229: -#line 140 "src/uri.rl" - { password.start = p; } -#line 166 "src/uri.rl" - { service.start = p; } - goto st293; -st293: - if ( ++p == pe ) - goto _test_eof293; -case 293: -#line 4532 "src/uri.cc" - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st294; - } else - goto st294; - goto st175; -st294: - if ( ++p == pe ) - goto _test_eof294; -case 294: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st295; - } else - goto st295; - goto st175; -st295: - if ( ++p == pe ) - goto _test_eof295; -case 295: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st296; - } else - goto st296; - goto st175; -st296: - if ( ++p == pe ) - goto _test_eof296; -case 296: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st297; - } else - goto st297; - goto st175; -st297: - if ( ++p == pe ) - goto _test_eof297; -case 297: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st298; - } else - goto st298; - goto st175; -st298: - if ( ++p == pe ) - goto _test_eof298; -case 298: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st299; - } else - goto st299; - goto st175; -st299: - if ( ++p == pe ) - goto _test_eof299; -case 299: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st300; - } else - goto st300; - goto st175; -st300: - if ( ++p == pe ) - goto _test_eof300; -case 300: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st301; - } else - goto st301; - goto st175; -st301: - if ( ++p == pe ) - goto _test_eof301; -case 301: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st302; - } else - goto st302; - goto st175; -st302: - if ( ++p == pe ) - goto _test_eof302; -case 302: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st303; - } else - goto st303; - goto st175; -st303: - if ( ++p == pe ) - goto _test_eof303; -case 303: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st304; - } else - goto st304; - goto st175; -st304: - if ( ++p == pe ) - goto _test_eof304; -case 304: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st305; - } else - goto st305; - goto st175; -st305: - if ( ++p == pe ) - goto _test_eof305; -case 305: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st306; - } else - goto st306; - goto st175; -st306: - if ( ++p == pe ) - goto _test_eof306; -case 306: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st307; - } else - goto st307; - goto st175; -st307: - if ( ++p == pe ) - goto _test_eof307; -case 307: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st308; - } else - goto st308; - goto st175; -st308: - if ( ++p == pe ) - goto _test_eof308; -case 308: - if ( (*p) == 64 ) - goto tr231; - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st210; - } else if ( (*p) > 90 ) { - if ( 97 <= (*p) && (*p) <= 122 ) - goto st210; - } else - goto st210; - goto st175; - } - _test_eof74: cs = 74; goto _test_eof; - _test_eof2: cs = 2; goto _test_eof; - _test_eof75: cs = 75; goto _test_eof; - _test_eof76: cs = 76; goto _test_eof; - _test_eof77: cs = 77; goto _test_eof; - _test_eof78: cs = 78; goto _test_eof; - _test_eof79: cs = 79; goto _test_eof; - _test_eof80: cs = 80; goto _test_eof; - _test_eof81: cs = 81; goto _test_eof; - _test_eof82: cs = 82; goto _test_eof; - _test_eof83: cs = 83; goto _test_eof; - _test_eof84: cs = 84; goto _test_eof; - _test_eof85: cs = 85; goto _test_eof; - _test_eof86: cs = 86; goto _test_eof; - _test_eof87: cs = 87; goto _test_eof; - _test_eof88: cs = 88; goto _test_eof; - _test_eof89: cs = 89; goto _test_eof; - _test_eof90: cs = 90; goto _test_eof; - _test_eof91: cs = 91; goto _test_eof; - _test_eof92: cs = 92; goto _test_eof; - _test_eof93: cs = 93; goto _test_eof; - _test_eof94: cs = 94; goto _test_eof; - _test_eof95: cs = 95; goto _test_eof; - _test_eof96: cs = 96; goto _test_eof; - _test_eof97: cs = 97; goto _test_eof; - _test_eof98: cs = 98; goto _test_eof; - _test_eof99: cs = 99; goto _test_eof; - _test_eof100: cs = 100; goto _test_eof; - _test_eof101: cs = 101; goto _test_eof; - _test_eof102: cs = 102; goto _test_eof; - _test_eof103: cs = 103; goto _test_eof; - _test_eof104: cs = 104; goto _test_eof; - _test_eof105: cs = 105; goto _test_eof; - _test_eof106: cs = 106; goto _test_eof; - _test_eof107: cs = 107; goto _test_eof; - _test_eof108: cs = 108; goto _test_eof; - _test_eof109: cs = 109; goto _test_eof; - _test_eof110: cs = 110; goto _test_eof; - _test_eof111: cs = 111; goto _test_eof; - _test_eof112: cs = 112; goto _test_eof; - _test_eof113: cs = 113; goto _test_eof; - _test_eof114: cs = 114; goto _test_eof; - _test_eof115: cs = 115; goto _test_eof; - _test_eof116: cs = 116; goto _test_eof; - _test_eof117: cs = 117; goto _test_eof; - _test_eof118: cs = 118; goto _test_eof; - _test_eof119: cs = 119; goto _test_eof; - _test_eof120: cs = 120; goto _test_eof; - _test_eof121: cs = 121; goto _test_eof; - _test_eof122: cs = 122; goto _test_eof; - _test_eof123: cs = 123; goto _test_eof; - _test_eof124: cs = 124; goto _test_eof; - _test_eof125: cs = 125; goto _test_eof; - _test_eof126: cs = 126; goto _test_eof; - _test_eof127: cs = 127; goto _test_eof; - _test_eof128: cs = 128; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof129: cs = 129; goto _test_eof; - _test_eof130: cs = 130; goto _test_eof; - _test_eof131: cs = 131; goto _test_eof; - _test_eof132: cs = 132; goto _test_eof; - _test_eof133: cs = 133; goto _test_eof; - _test_eof134: cs = 134; goto _test_eof; - _test_eof135: cs = 135; goto _test_eof; - _test_eof136: cs = 136; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof11: cs = 11; goto _test_eof; - _test_eof12: cs = 12; goto _test_eof; - _test_eof13: cs = 13; goto _test_eof; - _test_eof14: cs = 14; goto _test_eof; - _test_eof15: cs = 15; goto _test_eof; - _test_eof16: cs = 16; goto _test_eof; - _test_eof17: cs = 17; goto _test_eof; - _test_eof18: cs = 18; goto _test_eof; - _test_eof19: cs = 19; goto _test_eof; - _test_eof20: cs = 20; goto _test_eof; - _test_eof21: cs = 21; goto _test_eof; - _test_eof22: cs = 22; goto _test_eof; - _test_eof23: cs = 23; goto _test_eof; - _test_eof24: cs = 24; goto _test_eof; - _test_eof25: cs = 25; goto _test_eof; - _test_eof26: cs = 26; goto _test_eof; - _test_eof27: cs = 27; goto _test_eof; - _test_eof28: cs = 28; goto _test_eof; - _test_eof29: cs = 29; goto _test_eof; - _test_eof30: cs = 30; goto _test_eof; - _test_eof31: cs = 31; goto _test_eof; - _test_eof32: cs = 32; goto _test_eof; - _test_eof33: cs = 33; goto _test_eof; - _test_eof34: cs = 34; goto _test_eof; - _test_eof35: cs = 35; goto _test_eof; - _test_eof36: cs = 36; goto _test_eof; - _test_eof37: cs = 37; goto _test_eof; - _test_eof38: cs = 38; goto _test_eof; - _test_eof39: cs = 39; goto _test_eof; - _test_eof40: cs = 40; goto _test_eof; - _test_eof41: cs = 41; goto _test_eof; - _test_eof42: cs = 42; goto _test_eof; - _test_eof43: cs = 43; goto _test_eof; - _test_eof44: cs = 44; goto _test_eof; - _test_eof45: cs = 45; goto _test_eof; - _test_eof137: cs = 137; goto _test_eof; - _test_eof138: cs = 138; goto _test_eof; - _test_eof139: cs = 139; goto _test_eof; - _test_eof140: cs = 140; goto _test_eof; - _test_eof141: cs = 141; goto _test_eof; - _test_eof142: cs = 142; goto _test_eof; - _test_eof143: cs = 143; goto _test_eof; - _test_eof144: cs = 144; goto _test_eof; - _test_eof145: cs = 145; goto _test_eof; - _test_eof46: cs = 46; goto _test_eof; - _test_eof47: cs = 47; goto _test_eof; - _test_eof48: cs = 48; goto _test_eof; - _test_eof49: cs = 49; goto _test_eof; - _test_eof50: cs = 50; goto _test_eof; - _test_eof51: cs = 51; goto _test_eof; - _test_eof52: cs = 52; goto _test_eof; - _test_eof53: cs = 53; goto _test_eof; - _test_eof54: cs = 54; goto _test_eof; - _test_eof55: cs = 55; goto _test_eof; - _test_eof56: cs = 56; goto _test_eof; - _test_eof57: cs = 57; goto _test_eof; - _test_eof58: cs = 58; goto _test_eof; - _test_eof59: cs = 59; goto _test_eof; - _test_eof60: cs = 60; goto _test_eof; - _test_eof61: cs = 61; goto _test_eof; - _test_eof146: cs = 146; goto _test_eof; - _test_eof62: cs = 62; goto _test_eof; - _test_eof63: cs = 63; goto _test_eof; - _test_eof64: cs = 64; goto _test_eof; - _test_eof65: cs = 65; goto _test_eof; - _test_eof66: cs = 66; goto _test_eof; - _test_eof67: cs = 67; goto _test_eof; - _test_eof147: cs = 147; goto _test_eof; - _test_eof148: cs = 148; goto _test_eof; - _test_eof149: cs = 149; goto _test_eof; - _test_eof150: cs = 150; goto _test_eof; - _test_eof151: cs = 151; goto _test_eof; - _test_eof152: cs = 152; goto _test_eof; - _test_eof153: cs = 153; goto _test_eof; - _test_eof154: cs = 154; goto _test_eof; - _test_eof155: cs = 155; goto _test_eof; - _test_eof156: cs = 156; goto _test_eof; - _test_eof157: cs = 157; goto _test_eof; - _test_eof158: cs = 158; goto _test_eof; - _test_eof159: cs = 159; goto _test_eof; - _test_eof160: cs = 160; goto _test_eof; - _test_eof161: cs = 161; goto _test_eof; - _test_eof162: cs = 162; goto _test_eof; - _test_eof163: cs = 163; goto _test_eof; - _test_eof164: cs = 164; goto _test_eof; - _test_eof165: cs = 165; goto _test_eof; - _test_eof166: cs = 166; goto _test_eof; - _test_eof167: cs = 167; goto _test_eof; - _test_eof168: cs = 168; goto _test_eof; - _test_eof68: cs = 68; goto _test_eof; - _test_eof69: cs = 69; goto _test_eof; - _test_eof70: cs = 70; goto _test_eof; - _test_eof169: cs = 169; goto _test_eof; - _test_eof170: cs = 170; goto _test_eof; - _test_eof171: cs = 171; goto _test_eof; - _test_eof172: cs = 172; goto _test_eof; - _test_eof71: cs = 71; goto _test_eof; - _test_eof72: cs = 72; goto _test_eof; - _test_eof73: cs = 73; goto _test_eof; - _test_eof173: cs = 173; goto _test_eof; - _test_eof174: cs = 174; goto _test_eof; - _test_eof175: cs = 175; goto _test_eof; - _test_eof176: cs = 176; goto _test_eof; - _test_eof177: cs = 177; goto _test_eof; - _test_eof178: cs = 178; goto _test_eof; - _test_eof179: cs = 179; goto _test_eof; - _test_eof180: cs = 180; goto _test_eof; - _test_eof181: cs = 181; goto _test_eof; - _test_eof182: cs = 182; goto _test_eof; - _test_eof183: cs = 183; goto _test_eof; - _test_eof184: cs = 184; goto _test_eof; - _test_eof185: cs = 185; goto _test_eof; - _test_eof186: cs = 186; goto _test_eof; - _test_eof187: cs = 187; goto _test_eof; - _test_eof188: cs = 188; goto _test_eof; - _test_eof189: cs = 189; goto _test_eof; - _test_eof190: cs = 190; goto _test_eof; - _test_eof191: cs = 191; goto _test_eof; - _test_eof192: cs = 192; goto _test_eof; - _test_eof193: cs = 193; goto _test_eof; - _test_eof194: cs = 194; goto _test_eof; - _test_eof195: cs = 195; goto _test_eof; - _test_eof196: cs = 196; goto _test_eof; - _test_eof197: cs = 197; goto _test_eof; - _test_eof198: cs = 198; goto _test_eof; - _test_eof199: cs = 199; goto _test_eof; - _test_eof200: cs = 200; goto _test_eof; - _test_eof201: cs = 201; goto _test_eof; - _test_eof202: cs = 202; goto _test_eof; - _test_eof203: cs = 203; goto _test_eof; - _test_eof204: cs = 204; goto _test_eof; - _test_eof205: cs = 205; goto _test_eof; - _test_eof206: cs = 206; goto _test_eof; - _test_eof207: cs = 207; goto _test_eof; - _test_eof208: cs = 208; goto _test_eof; - _test_eof209: cs = 209; goto _test_eof; - _test_eof210: cs = 210; goto _test_eof; - _test_eof211: cs = 211; goto _test_eof; - _test_eof212: cs = 212; goto _test_eof; - _test_eof213: cs = 213; goto _test_eof; - _test_eof214: cs = 214; goto _test_eof; - _test_eof215: cs = 215; goto _test_eof; - _test_eof216: cs = 216; goto _test_eof; - _test_eof217: cs = 217; goto _test_eof; - _test_eof218: cs = 218; goto _test_eof; - _test_eof219: cs = 219; goto _test_eof; - _test_eof220: cs = 220; goto _test_eof; - _test_eof221: cs = 221; goto _test_eof; - _test_eof222: cs = 222; goto _test_eof; - _test_eof223: cs = 223; goto _test_eof; - _test_eof224: cs = 224; goto _test_eof; - _test_eof225: cs = 225; goto _test_eof; - _test_eof226: cs = 226; goto _test_eof; - _test_eof227: cs = 227; goto _test_eof; - _test_eof228: cs = 228; goto _test_eof; - _test_eof229: cs = 229; goto _test_eof; - _test_eof230: cs = 230; goto _test_eof; - _test_eof231: cs = 231; goto _test_eof; - _test_eof232: cs = 232; goto _test_eof; - _test_eof233: cs = 233; goto _test_eof; - _test_eof234: cs = 234; goto _test_eof; - _test_eof235: cs = 235; goto _test_eof; - _test_eof236: cs = 236; goto _test_eof; - _test_eof237: cs = 237; goto _test_eof; - _test_eof238: cs = 238; goto _test_eof; - _test_eof239: cs = 239; goto _test_eof; - _test_eof240: cs = 240; goto _test_eof; - _test_eof241: cs = 241; goto _test_eof; - _test_eof242: cs = 242; goto _test_eof; - _test_eof243: cs = 243; goto _test_eof; - _test_eof244: cs = 244; goto _test_eof; - _test_eof245: cs = 245; goto _test_eof; - _test_eof246: cs = 246; goto _test_eof; - _test_eof247: cs = 247; goto _test_eof; - _test_eof248: cs = 248; goto _test_eof; - _test_eof249: cs = 249; goto _test_eof; - _test_eof250: cs = 250; goto _test_eof; - _test_eof251: cs = 251; goto _test_eof; - _test_eof252: cs = 252; goto _test_eof; - _test_eof253: cs = 253; goto _test_eof; - _test_eof254: cs = 254; goto _test_eof; - _test_eof255: cs = 255; goto _test_eof; - _test_eof256: cs = 256; goto _test_eof; - _test_eof257: cs = 257; goto _test_eof; - _test_eof258: cs = 258; goto _test_eof; - _test_eof259: cs = 259; goto _test_eof; - _test_eof260: cs = 260; goto _test_eof; - _test_eof261: cs = 261; goto _test_eof; - _test_eof262: cs = 262; goto _test_eof; - _test_eof263: cs = 263; goto _test_eof; - _test_eof264: cs = 264; goto _test_eof; - _test_eof265: cs = 265; goto _test_eof; - _test_eof266: cs = 266; goto _test_eof; - _test_eof267: cs = 267; goto _test_eof; - _test_eof268: cs = 268; goto _test_eof; - _test_eof269: cs = 269; goto _test_eof; - _test_eof270: cs = 270; goto _test_eof; - _test_eof271: cs = 271; goto _test_eof; - _test_eof272: cs = 272; goto _test_eof; - _test_eof273: cs = 273; goto _test_eof; - _test_eof274: cs = 274; goto _test_eof; - _test_eof275: cs = 275; goto _test_eof; - _test_eof276: cs = 276; goto _test_eof; - _test_eof277: cs = 277; goto _test_eof; - _test_eof278: cs = 278; goto _test_eof; - _test_eof279: cs = 279; goto _test_eof; - _test_eof280: cs = 280; goto _test_eof; - _test_eof281: cs = 281; goto _test_eof; - _test_eof282: cs = 282; goto _test_eof; - _test_eof283: cs = 283; goto _test_eof; - _test_eof284: cs = 284; goto _test_eof; - _test_eof285: cs = 285; goto _test_eof; - _test_eof286: cs = 286; goto _test_eof; - _test_eof287: cs = 287; goto _test_eof; - _test_eof288: cs = 288; goto _test_eof; - _test_eof289: cs = 289; goto _test_eof; - _test_eof290: cs = 290; goto _test_eof; - _test_eof291: cs = 291; goto _test_eof; - _test_eof292: cs = 292; goto _test_eof; - _test_eof293: cs = 293; goto _test_eof; - _test_eof294: cs = 294; goto _test_eof; - _test_eof295: cs = 295; goto _test_eof; - _test_eof296: cs = 296; goto _test_eof; - _test_eof297: cs = 297; goto _test_eof; - _test_eof298: cs = 298; goto _test_eof; - _test_eof299: cs = 299; goto _test_eof; - _test_eof300: cs = 300; goto _test_eof; - _test_eof301: cs = 301; goto _test_eof; - _test_eof302: cs = 302; goto _test_eof; - _test_eof303: cs = 303; goto _test_eof; - _test_eof304: cs = 304; goto _test_eof; - _test_eof305: cs = 305; goto _test_eof; - _test_eof306: cs = 306; goto _test_eof; - _test_eof307: cs = 307; goto _test_eof; - _test_eof308: cs = 308; goto _test_eof; - - _test_eof: {} - if ( p == eof ) - { - switch ( cs ) { - case 74: - case 92: - case 113: - case 114: - case 115: - case 116: - case 117: - case 118: - case 122: - case 123: - case 124: - case 125: - case 126: - case 127: - case 128: - case 129: - case 130: - case 131: - case 132: - case 133: - case 134: - case 135: - case 136: - case 146: - case 168: - case 169: - case 170: - case 171: - case 172: -#line 158 "src/uri.rl" - { host.end = p; } - break; - case 76: - case 77: - case 78: - case 79: - case 80: - case 81: - case 82: - case 83: - case 84: - case 85: - case 86: - case 87: - case 88: - case 89: - case 90: - case 91: - case 142: - case 143: - case 144: - case 145: - case 148: - case 149: - case 150: - case 151: - case 152: - case 153: - case 154: - case 155: - case 156: - case 157: - case 158: - case 159: - case 160: - case 161: - case 162: - case 163: -#line 167 "src/uri.rl" - { service.end = p; } - break; - case 94: - case 95: -#line 177 "src/uri.rl" - { path.end = p; } - break; - case 174: - case 175: - case 209: - case 210: - case 211: - case 220: - case 221: - case 222: - case 223: - case 224: - case 225: - case 226: - case 227: - case 228: - case 229: - case 230: - case 231: - case 232: - case 233: - case 234: - case 235: - case 236: - case 237: - case 238: - case 239: - case 240: - case 241: - case 242: - case 243: - case 244: - case 245: - case 246: - case 247: - case 248: - case 249: - case 250: - case 251: - case 252: - case 253: - case 254: - case 255: - case 256: - case 257: - case 258: - case 259: - case 269: - case 270: - case 271: - case 272: - case 273: - case 274: - case 275: - case 276: - case 277: - case 278: - case 279: - case 280: - case 281: - case 282: - case 283: - case 284: - case 286: - case 287: - case 288: - case 289: - case 290: - case 291: -#line 181 "src/uri.rl" - { path.end = p; } - break; - case 119: - case 120: - case 121: -#line 145 "src/uri.rl" - { ip4.end = p; } -#line 158 "src/uri.rl" - { host.end = p; } - break; - case 137: -#line 154 "src/uri.rl" - { ip6.end = p - 1; } -#line 158 "src/uri.rl" - { host.end = p; } - break; - case 164: - case 165: - case 166: - case 167: -#line 158 "src/uri.rl" - { host.end = p; } -#line 173 "src/uri.rl" - { sport.end = p; } - break; - case 93: -#line 158 "src/uri.rl" - { host.end = p; } -#line 177 "src/uri.rl" - { path.end = p; } - break; - case 75: - case 138: - case 139: - case 140: - case 141: - case 147: -#line 163 "src/uri.rl" - { dport.end = p; } -#line 167 "src/uri.rl" - { service.end = p; } - break; - case 97: - case 98: - case 99: - case 100: - case 101: - case 102: - case 103: - case 104: - case 105: - case 106: - case 107: - case 108: - case 109: - case 110: - case 111: - case 112: -#line 167 "src/uri.rl" - { service.end = p; } -#line 177 "src/uri.rl" - { path.end = p; } - break; - case 173: - case 193: - case 194: - case 195: - case 196: - case 197: - case 198: - case 202: - case 203: - case 204: - case 205: - case 206: - case 207: - case 208: - case 212: - case 213: - case 214: - case 215: - case 216: - case 217: - case 218: - case 219: - case 285: -#line 181 "src/uri.rl" - { path.end = p; } -#line 158 "src/uri.rl" - { host.end = p; } - break; - case 177: - case 178: - case 179: - case 180: - case 181: - case 182: - case 183: - case 184: - case 185: - case 186: - case 187: - case 188: - case 189: - case 190: - case 191: - case 192: - case 265: - case 266: - case 267: - case 268: - case 293: - case 294: - case 295: - case 296: - case 297: - case 298: - case 299: - case 300: - case 301: - case 302: - case 303: - case 304: - case 305: - case 306: - case 307: - case 308: -#line 181 "src/uri.rl" - { path.end = p; } -#line 167 "src/uri.rl" - { service.end = p; } - break; - case 96: -#line 163 "src/uri.rl" - { dport.end = p; } -#line 167 "src/uri.rl" - { service.end = p; } -#line 177 "src/uri.rl" - { path.end = p; } - break; - case 199: - case 200: - case 201: -#line 181 "src/uri.rl" - { path.end = p; } -#line 145 "src/uri.rl" - { ip4.end = p; } -#line 158 "src/uri.rl" - { host.end = p; } - break; - case 260: -#line 181 "src/uri.rl" - { path.end = p; } -#line 154 "src/uri.rl" - { ip6.end = p - 1; } -#line 158 "src/uri.rl" - { host.end = p; } - break; - case 176: - case 261: - case 262: - case 263: - case 264: - case 292: -#line 181 "src/uri.rl" - { path.end = p; } -#line 163 "src/uri.rl" - { dport.end = p; } -#line 167 "src/uri.rl" - { service.end = p; } - break; -#line 5397 "src/uri.cc" - } - } - - _out: {} - } - -#line 198 "src/uri.rl" - - - (void)uri_first_final; - (void)uri_error; - (void)uri_en_main; - - if (login.start && login.end && password.start && password.end) { - snprintf(uri->login, sizeof(uri->login), - "%.*s", (int) (login.end - login.start), login.start); - snprintf(uri->password, sizeof(uri->password), - "%.*s", (int) (password.end - password.start), - password.start); - } - - if (path.start && path.end) { - struct sockaddr_un *un = (struct sockaddr_un *)&uri->addr; - uri->addr_len = sizeof(*un); - un->sun_family = AF_UNIX; - if (path.end - path.start >= sizeof(un->sun_path)) - return -1; - - snprintf(un->sun_path, sizeof(un->sun_path), - "%.*s", (int) (path.end - path.start), path.start); - snprintf(uri->schema, sizeof(uri->schema), "unix"); - return 0; - } - - if (schema.start && schema.end) { - snprintf(uri->schema, sizeof(uri->schema), - "%.*s", (int) (schema.end - schema.start), schema.start); - } else { - snprintf(uri->schema, sizeof(uri->schema), "tcp"); - } - - - /* only port was defined */ - if (sport.start && sport.end) { - struct sockaddr_in *in = (struct sockaddr_in *)&uri->addr; - uri->addr_len = sizeof(*in); - - in->sin_family = AF_INET; - in->sin_port = htons(port); - in->sin_addr.s_addr = INADDR_ANY; - return 0; - } - - - if (!(dport.start && dport.end)) { - port = 0; - if (service.start && service.end) { - if (service.end - service.start >= NI_MAXSERV) - return -1; - char sname[NI_MAXSERV]; - snprintf(sname, sizeof(sname), "%.*s", - (int) (service.end - service.start), - service.start); - struct servent *s = getservbyname(sname, NULL); - if (!s) - return -1; - port = ntohs(s->s_port); - } - } - - - /* IPv4 uri */ - if (ip4.start && ip4.end) { - struct sockaddr_in *in = - (struct sockaddr_in *)&uri->addr; - uri->addr_len = sizeof(*in); - - in->sin_family = AF_INET; - in->sin_port = htons(port); - - char sip4[3 * 4 + 3 + 1]; - memset(sip4, 0, sizeof(sip4)); - snprintf(sip4, sizeof(sip4), "%.*s", (int) (ip4.end - ip4.start), - ip4.start); - if (inet_aton(sip4, &in->sin_addr)) - return 0; - return -1; - } - - /* IPv6 uri */ - if (ip6.start && ip6.end) { - struct sockaddr_in6 *in6 = - (struct sockaddr_in6 *)&uri->addr; - uri->addr_len = sizeof(*in6); - - - char sip6[8 * 4 + 7 + 1]; - memset(sip6, 0, sizeof(sip6)); - snprintf(sip6, sizeof(sip6), "%.*s", (int) (ip6.end - ip6.start), - ip6.start); - - in6->sin6_family = AF_INET6; - in6->sin6_port = htonl(port); - - if (inet_pton(AF_INET6, sip6, (void *)&in6->sin6_addr)) - return 0; - - return -1; - } - - - if (!host.start || !host.end) - return -1; - - if (host.end - host.start >= NI_MAXHOST) - return -1; - - char shost[NI_MAXHOST]; - char sservice[NI_MAXSERV]; - snprintf(shost, sizeof(shost), "%.*s", (int) (host.end - host.start), - host.start); - if (service.end) { - snprintf(sservice, sizeof(sservice), "%.*s", - (int) (service.end - service.start), service.start); - } else { - sservice[0] = '\0'; - } - - struct addrinfo hints, *res; - memset(&hints, 0, sizeof(hints)); - hints.ai_protocol = getprotobyname("tcp")->p_proto; - - if (getaddrinfo(shost, sservice, &hints, &res) != 0) - return -1; - - uri->addr_len = res->ai_addrlen; - memcpy((void *)&uri->addr, (void *)res->ai_addr, res->ai_addrlen); - freeaddrinfo(res); - return 0; -} - -/* vim: set ft=ragel: */ diff --git a/src/uri.h b/src/uri.h index 377b4a3cb0f02a4b8c2097a9122c472604996c61..8bdf34e13d2a84c14ba8e092a38ab77272f2e49e 100644 --- a/src/uri.h +++ b/src/uri.h @@ -28,43 +28,47 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#include <sys/types.h> /* for netinet/ip.h on BSD */ -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <netdb.h> -#include <sys/un.h> -enum { URI_STR_LEN = 32 }; +#include <stddef.h> +#include <netdb.h> /* NI_MAXHOST, NI_MAXSERV */ +#include <limits.h> /* _POSIX_PATH_MAX */ -/** A parsed representation of an URI */ -struct uri { - - union { - struct sockaddr addr; - struct sockaddr_in in; - struct sockaddr_un un; - struct sockaddr_in6 in6; - struct sockaddr_storage addr_storage; - }; - socklen_t addr_len; +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ - char schema[URI_STR_LEN]; - char login[URI_STR_LEN]; - char password[URI_STR_LEN]; +struct uri { + const char *scheme; + size_t scheme_len; + const char *login; + size_t login_len; + const char *password; + size_t password_len; + const char *host; + size_t host_len; + const char *service; + size_t service_len; + const char *path; + size_t path_len; + const char *query; + size_t query_len; + const char *fragment; + size_t fragment_len; + int host_hint; }; -/** - * Parse a string and fill uri struct. - * @retval 0 success - * @retval -1 error - */ +#define URI_HOST_UNIX "unix/" +#define URI_MAXHOST NI_MAXHOST +#define URI_MAXSERVICE _POSIX_PATH_MAX /* _POSIX_PATH_MAX always > NI_MAXSERV */ + int uri_parse(struct uri *uri, const char *str); -/** Convert an uri to string */ -const char * -uri_to_string(const struct uri * uri); +char * +uri_format(const struct uri *uri); +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ #endif /* TARANTOOL_URI_H_INCLUDED */ diff --git a/src/uri.rl b/src/uri.rl index ddde079ba3305719cc95d224ba9acaa56b42b6c9..151341bfb1e2ab966c80f1c756cfe1ba78c124f3 100644 --- a/src/uri.rl +++ b/src/uri.rl @@ -28,305 +28,193 @@ */ #include "uri.h" #include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <assert.h> -#include <sys/socket.h> -#include <netinet/ip.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/un.h> -#include <netdb.h> - -const char * -uri_to_string(const struct uri * uri) -{ - static __thread char - str[NI_MAXSERV + NI_MAXHOST + sizeof(uri->schema)]; - - if (!uri || !uri->addr_len) { - snprintf(str, sizeof(str), "unknown address"); - return str; - } - - switch (uri->addr.sa_family) { - case AF_INET6: - case AF_INET: - { - char shost[NI_MAXHOST]; - char sservice[NI_MAXSERV]; - getnameinfo( - (struct sockaddr *)&uri->addr, - uri->addr_len, - shost, sizeof(shost), - sservice, sizeof(sservice), - NI_NUMERICHOST|NI_NUMERICSERV); - if (uri->addr.sa_family == AF_INET) { - if (strncmp(uri->schema, "tcp", 3) == 0) { - snprintf(str, sizeof(str), "%s:%s", - shost, sservice); - } else { - snprintf(str, sizeof(str), "%s://%s:%s", - uri->schema, shost, sservice); - } - } else { - if (strncmp(uri->schema, "tcp", 3) == 0) { - snprintf(str, sizeof(str), "%s:%s", - shost, sservice); - } else { - snprintf(str, sizeof(str), "%s://[%s]:%s", - uri->schema, shost, sservice); - } - } - break; - } - case AF_UNIX: - { - struct sockaddr_un *un = - (struct sockaddr_un *)&uri->addr; - snprintf(str, sizeof(str), "unix://%.*s", - (int) sizeof(un->sun_path), un->sun_path); - break; - } - default: - snprintf(str, sizeof(str), "unknown address"); - break; - } - return str; -} - +#include <stdio.h> /* snprintf */ int uri_parse(struct uri *uri, const char *p) { - (void) uri; const char *pe = p + strlen(p); const char *eof = pe; int cs; memset(uri, 0, sizeof(*uri)); - struct { - const char *start; - const char *end; - } schema = { 0, 0 }, - host = { 0, 0 }, - service = { 0, 0 }, - sport = { 0, 0 }, - login = { 0, 0 }, - password = { 0, 0 }, - ip4 = { 0, 0 }, - ip6 = { 0, 0 }, - path = { 0, 0 }, - dport = { 0, 0 } - ; - - unsigned port = 0; + if (p == pe) + return -1; + + const char *s = NULL, *login = NULL, *scheme = NULL; + size_t login_len = 0, scheme_len = 0; %%{ machine uri; write data; - hex1_4 = ([0-9a-fA-F]{1,4}); - + # + # Line by line translation of RFC3986 + # http://tools.ietf.org/html/rfc3986#appendix-A + # + + gen_delims = (":" | "/" | "?" | "#" | "[" | "]" | "@"); + sub_delims = ("!" | "$" | "&" | "'" | "(" | ")" + | "*" | "+" | "," | ";" | "="); + + reserved = (gen_delims | sub_delims); + unreserved = alpha | digit | "-" | "_" | "~" | "."; + pct_encoded = ("%%" | ("%" xdigit xdigit?) + | ("%u" xdigit xdigit xdigit xdigit)); + + pchar_nc = unreserved | pct_encoded | sub_delims | "@"; + pchar = pchar_nc | ":"; + + query = (pchar | "/" | "?")* + >{ s = p; } + %{ uri->query = s; uri->query_len = p - s; }; + + fragment = (pchar | "/" | "?")* + >{ s = p; } + %{ uri->fragment = s; uri->fragment_len = p - s; }; + + segment = pchar*; + segment_nz = pchar+; + segment_nz_nc = pchar_nc+; + + path_abempty = ( "/" segment )*; + path_absolute = ("/" ( segment_nz ( "/" segment )* )?); + path_noscheme = (segment_nz_nc ( "/" segment )*); + path_rootless = (pchar_nc ( "/" segment )*); + path_empty = ""; + + path = path_abempty # begins with "/" or is empty + | path_absolute # begins with "/" but not "//" + | path_noscheme # begins with a non-colon segment + | path_rootless # begins with a segment + | path_empty; # zero characters + + reg_name = (unreserved | pct_encoded | sub_delims)+ + >{ s = p; } + %{ uri->host = s; uri->host_len = p - s;}; + + hex1_4 = ([0-9a-fa-f]{1,4}); + + ip4addr = ((digit{1,3}) (("." digit{1,3}){3})); + ip4 = ip4addr + >{ s = p; } + %{ uri->host = s; uri->host_len = p - s; + uri->host_hint = 1; }; + + ip6 = ("[" ( + ((hex1_4?) ((":" (hex1_4?)){1,8})) | + ("::" [ff][ff][ff][ff] ":" ip4addr)) + >{ s = p; } + %{ uri->host = s; uri->host_len = p - s; + uri->host_hint = 2; } + "]"); + + action unix{ + /* + * This action is also called for path_* terms. + * I absolutely have no idea why. + */ + if (uri->host_hint != 3) { + uri->host_hint = 3; + uri->host = URI_HOST_UNIX; + uri->host_len = strlen(URI_HOST_UNIX); + uri->service = s; uri->service_len = p - s; + /* a workaround for grammar limitations */ + uri->path = NULL; + uri->path_len = 0; + }; + } + # Non-standard: "unix/" support + unix = ("unix/:" %{ s = p;} path) %unix; - schema = ((alpha+) "://") - >{ schema.start = p; } - %{ schema.end = p - 3; }; + service = (digit+ | alpha*) + >{ s = p; } + %{ uri->service = s; uri->service_len = p - s; }; - login = (alnum+) - >{ login.start = p; } - %{ login.end = p; }; + host = (ip4 | ip6 | reg_name); - password = (alnum+) - >{ password.start = p; } - %{ password.end = p; }; + login = (unreserved | pct_encoded | sub_delims )+ + >{ s = p; } + %{ login = s; login_len = p - s; }; - ip4 = ((digit{1,3}) (("." digit{1,3}){3})) - >{ ip4.start = p; } - %{ ip4.end = p; }; + password = (unreserved | pct_encoded | sub_delims )+ + >{ s = p; } + %{ uri->password = s; uri->password_len = p - s; }; - ip4_6 = ("[::" [fF][fF][fF][fF] ":" ip4 "]"); + # Non-standard: split userinfo to login and password + userinfo = login (":" password)? + %{ uri->login = login; uri->login_len = login_len; }; - ip6 = ("[" - (hex1_4?) - ((":" (hex1_4?)){1,8}) - "]") - >{ ip6.start = p + 1; } - %{ ip6.end = p - 1; }; + # Non-standard: use service instead of port here + support unix + authority = (userinfo "@")? ((host (":" service)?) | (unix ":")); - host = (ip4_6 | ip4 | ip6 | ([^:?]+)) - >{ host.start = p; } - %{ host.end = p; }; + scheme = alpha > { s = p; } + (alpha | digit | "+" | "-" | ".")* + %{scheme = s; scheme_len = p - s; }; - dport = ([1-9] (digit*)) - >{ dport.start = p; port = 0; } - ${ port = port * 10 + (int)(*p - '0'); } - %{ dport.end = p; }; + # relative_part = "//" authority > { s = p } path_abempty | + # path_absolute | + # path_noscheme | + # path_empty; - service = (dport | (alpha{1,16})) - >{ service.start = p; } - %{ service.end = p; }; + # Non-standard: allow URI without scheme + hier_part_noscheme = (((authority %{ s = p; } path_abempty? + | path_absolute? + | path_rootless? + | path_empty? + ) %{ uri->path = s; uri->path_len = p - s; }) | + unix); + hier_part = "//" + >{ uri->scheme = scheme; uri->scheme_len = scheme_len;} + hier_part_noscheme; - port = ([1-9] digit*) - >{ sport.start = p; port = 0; } - ${ port = port * 10 + (int)(*p - '0'); } - %{ sport.end = p; }; + # relative_ref = relative_part ("?" >{ s = p; } query)? + # ("#" >{ s = p; } fragment)?; - abspath = ("/" any+) - >{ path.start = p; } - %{ path.end = p; }; + # absolute_URI = scheme ":" hier_part ("?" >{ s = p; } query); - file = (any+) - >{ path.start = p; } - %{ path.end = p; }; + PORT = digit+ + >{ uri->service = p; } + %{ uri->service_len = p - uri->service; + uri->host = NULL; uri->host_len = 0; }; + PATH = ((userinfo "@")? %{ s = p; } path_absolute %unix); - main := ( - ("unix://" - ((login ":" password "@") ?) file) | + URI = ((scheme ":" hier_part) | hier_part_noscheme) + ("?" >{ s = p; } query)? ("#" >{ s = p; } fragment)?; - ((schema)? - ((login ":" password "@")?) - host - ((":" service)?)) | + # Non-RFC: support port and absolute path + main := URI | PORT | PATH; - port | - abspath - ); write init; write exec; }%% - (void)uri_first_final; - (void)uri_error; - (void)uri_en_main; - - if (login.start && login.end && password.start && password.end) { - snprintf(uri->login, sizeof(uri->login), - "%.*s", (int) (login.end - login.start), login.start); - snprintf(uri->password, sizeof(uri->password), - "%.*s", (int) (password.end - password.start), - password.start); - } - - if (path.start && path.end) { - struct sockaddr_un *un = (struct sockaddr_un *)&uri->addr; - uri->addr_len = sizeof(*un); - un->sun_family = AF_UNIX; - if (path.end - path.start >= sizeof(un->sun_path)) - return -1; - - snprintf(un->sun_path, sizeof(un->sun_path), - "%.*s", (int) (path.end - path.start), path.start); - snprintf(uri->schema, sizeof(uri->schema), "unix"); - return 0; - } - - if (schema.start && schema.end) { - snprintf(uri->schema, sizeof(uri->schema), - "%.*s", (int) (schema.end - schema.start), schema.start); - } else { - snprintf(uri->schema, sizeof(uri->schema), "tcp"); - } - - - /* only port was defined */ - if (sport.start && sport.end) { - struct sockaddr_in *in = (struct sockaddr_in *)&uri->addr; - uri->addr_len = sizeof(*in); - - in->sin_family = AF_INET; - in->sin_port = htons(port); - in->sin_addr.s_addr = INADDR_ANY; - return 0; - } - - - if (!(dport.start && dport.end)) { - port = 0; - if (service.start && service.end) { - if (service.end - service.start >= NI_MAXSERV) - return -1; - char sname[NI_MAXSERV]; - snprintf(sname, sizeof(sname), "%.*s", - (int) (service.end - service.start), - service.start); - struct servent *s = getservbyname(sname, NULL); - if (!s) - return -1; - port = ntohs(s->s_port); - } - } - - - /* IPv4 uri */ - if (ip4.start && ip4.end) { - struct sockaddr_in *in = - (struct sockaddr_in *)&uri->addr; - uri->addr_len = sizeof(*in); - - in->sin_family = AF_INET; - in->sin_port = htons(port); - - char sip4[3 * 4 + 3 + 1]; - memset(sip4, 0, sizeof(sip4)); - snprintf(sip4, sizeof(sip4), "%.*s", (int) (ip4.end - ip4.start), - ip4.start); - if (inet_aton(sip4, &in->sin_addr)) - return 0; + if (uri->path_len == 0) + uri->path = NULL; + if (uri->service_len == 0) + uri->service = NULL; + if (uri->service_len >= URI_MAXSERVICE) return -1; - } - - /* IPv6 uri */ - if (ip6.start && ip6.end) { - struct sockaddr_in6 *in6 = - (struct sockaddr_in6 *)&uri->addr; - uri->addr_len = sizeof(*in6); - - - char sip6[8 * 4 + 7 + 1]; - memset(sip6, 0, sizeof(sip6)); - snprintf(sip6, sizeof(sip6), "%.*s", (int) (ip6.end - ip6.start), - ip6.start); - - in6->sin6_family = AF_INET6; - in6->sin6_port = htonl(port); - - if (inet_pton(AF_INET6, sip6, (void *)&in6->sin6_addr)) - return 0; - - return -1; - } - - - if (!host.start || !host.end) + if (uri->host_len >= URI_MAXHOST) return -1; - if (host.end - host.start >= NI_MAXHOST) - return -1; - - char shost[NI_MAXHOST]; - char sservice[NI_MAXSERV]; - snprintf(shost, sizeof(shost), "%.*s", (int) (host.end - host.start), - host.start); - if (service.end) { - snprintf(sservice, sizeof(sservice), "%.*s", - (int) (service.end - service.start), service.start); - } else { - sservice[0] = '\0'; - } - - struct addrinfo hints, *res; - memset(&hints, 0, sizeof(hints)); - hints.ai_protocol = getprotobyname("tcp")->p_proto; - - if (getaddrinfo(shost, sservice, &hints, &res) != 0) - return -1; + (void)uri_first_final; + (void)uri_error; + (void)uri_en_main; + (void)eof; - uri->addr_len = res->ai_addrlen; - memcpy((void *)&uri->addr, (void *)res->ai_addr, res->ai_addrlen); - freeaddrinfo(res); - return 0; + return cs >= uri_first_final ? 0 : -1; } +char * +uri_format(const struct uri *uri) +{ + static char buf[1024]; + /* very primitive implementation suitable for our needs */ + snprintf(buf, sizeof(buf), "%.*s:%.*s", + (int) uri->host_len, uri->host != NULL ? uri->host : "*", + (int) uri->service_len, uri->service); + return buf; +} /* vim: set ft=ragel: */ diff --git a/src/util.cc b/src/util.cc index 6f30246714bc5ec326ab80fce74530f10adcb6aa..f0cd3ca37cf1eb6a557f4322f97eaf9d8589a3c2 100644 --- a/src/util.cc +++ b/src/util.cc @@ -314,7 +314,7 @@ backtrace_foreach(backtrace_cb cb, void *frame_, void *stack, size_t stack_size, } } -void +extern "C" void print_backtrace() { void *frame = __builtin_frame_address(0); diff --git a/test/app/cfg.result b/test/app/cfg.result index 5ded3d0573975846c06847d6428e2e2ed3fafa9f..38f4a9c0db8c3de4ad176a7e8d11d5b527ce1b80 100644 --- a/test/app/cfg.result +++ b/test/app/cfg.result @@ -1,2 +1,10 @@ -false [string "-- load_cfg.lua - internal file..."]:137: Please call box.cfg{} first -true table +TAP version 13 +1..8 +ok - exception on unconfigured box +ok - configured box +ok - cfg.wal_mode default value +ok - cfg.wal_mode default value +ok - cfg.wal_mode change +ok - cfg.wal_mode default value +ok - cfg.wal_mode change +ok - cfg.wal_mode default value diff --git a/test/app/cfg.test.lua b/test/app/cfg.test.lua index bce98a2db290b603bec2a20e71572090c8a3ea2a..d768107c2cae79144649420f3a1ae68ca9b86e91 100755 --- a/test/app/cfg.test.lua +++ b/test/app/cfg.test.lua @@ -1,19 +1,48 @@ #!/usr/bin/env tarantool +local tap = require('tap') +local test = tap.test('cfg') +test:plan(8) + -------------------------------------------------------------------------------- -- All box members must raise an exception on access if box.cfg{} wasn't called -------------------------------------------------------------------------------- local box = require('box') -local function test() +local function testfun() return type(box.space) end -print(pcall(test)) +local status, result = pcall(testfun) + +test:ok(not status and result:match('Please call box.cfg{}'), + 'exception on unconfigured box') + box.cfg{ logger="tarantool.log", slab_alloc_arena=0.1, + wal_mode = "", -- "" means default value } -print(pcall(test)) +status, result = pcall(testfun) +test:ok(status and result == 'table', 'configured box') + +-------------------------------------------------------------------------------- +-- gh-534: Segmentation fault after two bad wal_mode settings +-------------------------------------------------------------------------------- + +test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value") +box.cfg{wal_mode = ""} +test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value") +box.cfg{wal_mode = "none"} +test:is(box.cfg.wal_mode, "none", "cfg.wal_mode change") +-- "" or NULL resets option to default value +box.cfg{wal_mode = ""} +test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value") +box.cfg{wal_mode = "none"} +test:is(box.cfg.wal_mode, "none", "cfg.wal_mode change") +box.cfg{wal_mode = require('msgpack').NULL} +test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value") + +test:check() os.exit(0) diff --git a/test/app/console.result b/test/app/console.result index e7f5b5ca465f82e795277c588e439b323a4cc9e4..40596ba7e469aa898ae91efc7b5cbc639a151dfa 100644 --- a/test/app/console.result +++ b/test/app/console.result @@ -1,6 +1,7 @@ TAP version 13 -1..18 +1..26 ok - console.listen started +ok - Handshake ok - connect to console ok - eval ok - state.socker:peer().host @@ -11,6 +12,7 @@ ok - get delimiter is ';' ok - clear delimiter ok - remote network error ok - remote access denied +ok - remote access denied ok - remote connect ok - remote eval ok - remote state.remote.host @@ -18,3 +20,9 @@ ok - remote state.remote.port ok - remote state.prompt ok - remote disconnect ok - console.listen stopped +ok - console.listen uri support +ok - console.listen uri support +ok - console.listen uri support +ok - console.listen uri support +ok - console.listen uri support +ok - console.listen uri support diff --git a/test/app/console.test.lua b/test/app/console.test.lua index 516d4eb46d5595ca9e8f4565909da04e110888e5..5a611cc4e4b7c7961534b53c1d136311cdcef5f1 100755 --- a/test/app/console.test.lua +++ b/test/app/console.test.lua @@ -12,7 +12,7 @@ os.remove(CONSOLE_SOCKET) os.remove(IPROTO_SOCKET) box.cfg{ - listen='unix://'..IPROTO_SOCKET; + listen=IPROTO_SOCKET; slab_alloc_arena=0.1, logger="tarantool.log", } @@ -22,12 +22,14 @@ local EOL = "\n%.%.%.\n" test = tap.test("console") -test:plan(18) +test:plan(26) -- Start console and connect to it local server = console.listen(CONSOLE_SOCKET) test:ok(server ~= nil, "console.listen started") local client = socket.tcp_connect("unix/", CONSOLE_SOCKET) +local handshake = client:read{chunk = 128} +test:ok(string.match(handshake, '^Tarantool .*console') ~= nil, 'Handshake') test:ok(client ~= nil, "connect to console") -- Execute some command @@ -55,22 +57,30 @@ client:write("require('console').delimiter('');\n") test:is(yaml.decode(client:read(EOL)), '', "clear delimiter") -- Connect to iproto console (CALL) -client:write(string.format("require('console').connect('unix/', '/')\n")) +client:write(string.format("require('console').connect('/')\n")) -- error: Connection is not established test:ok(yaml.decode(client:read(EOL))[1].error:find('not established'), 'remote network error') -client:write(string.format("require('console').connect('unix/', '%s')\n", +client:write(string.format("require('console').connect('%s')\n", IPROTO_SOCKET)) -- error: Execute access denied for user 'guest' to function 'dostring test:ok(yaml.decode(client:read(EOL))[1].error:find('access denied'), 'remote access denied') +-- create user +box.schema.user.create('test', { password = 'pass' }) +client:write(string.format("require('console').connect('test:pass@%s')\n", + IPROTO_SOCKET)) +-- error: Execute access denied for user 'tester' to function 'dostring +test:ok(yaml.decode(client:read(EOL))[1].error:find('access denied'), + 'remote access denied') + -- Add permissions to execute `dostring` for `guest` box.schema.func.create('dostring') -box.schema.user.grant('guest', 'execute', 'function', 'dostring') +box.schema.user.grant('test', 'execute', 'function', 'dostring') -client:write(string.format("require('console').connect('unix/', '%s')\n", +client:write(string.format("require('console').connect('test:pass@%s')\n", IPROTO_SOCKET)) test:is(yaml.decode(client:read(EOL)), '', "remote connect") @@ -102,11 +112,24 @@ server:close() -- Check that admon console has been stopped test:isnil(socket.tcp_connect("unix/", CONSOLE_SOCKET), "console.listen stopped") -test:check() - -- Stop iproto (not implemented yet) -- box.cfg{listen = nil} - -os.remove(CONSOLE_SOCKET) os.remove(IPROTO_SOCKET) + +local s = console.listen('127.0.0.1:0') +addr = s:name() +test:is(addr.family, 'AF_INET', 'console.listen uri support') +test:is(addr.host, '127.0.0.1', 'console.listen uri support') +test:isnt(addr.port, 0, 'console.listen uri support') +s:close() + +local s = console.listen('console://unix/:'..CONSOLE_SOCKET) +addr = s:name() +test:is(addr.family, 'AF_UNIX', 'console.listen uri support') +test:is(addr.host, 'unix/', 'console.listen uri support') +test:is(addr.port, CONSOLE_SOCKET, 'console.listen uri support') +s:close() + +test:check() + os.exit(0) diff --git a/test/app/float_value.result b/test/app/float_value.result index b7300c58a9b73fe818e6f67ac9632e5acc1b01f6..c3cfdb6c80f7d36870ddc5f0a736d81db0f93c16 100644 --- a/test/app/float_value.result +++ b/test/app/float_value.result @@ -11,15 +11,16 @@ box.cfg 10 logger_nonblock:true 11 snap_dir:. 12 coredump:false -13 wal_mode:write -14 panic_on_snap_error:true -15 panic_on_wal_error:false -16 too_long_threshold:0.01 -17 readahead:16320 -18 wal_dir:. -19 snapshot_period:0 -20 slab_alloc_minimal:64 -21 wal_dir_rescan_delay:0.1 +13 sophia_dir:./sophia +14 wal_mode:write +15 panic_on_snap_error:true +16 panic_on_wal_error:false +17 too_long_threshold:0.01 +18 slab_alloc_minimal:64 +19 wal_dir:. +20 readahead:16320 +21 snapshot_period:0 +22 wal_dir_rescan_delay:0.1 ------------------------------------------------------ Check that too_long_threshold = 0.01 0.01 diff --git a/test/app/init_script.result b/test/app/init_script.result index 428c555e57d1ac4846ccc775d649197822b143fd..321c3db21f233e79288fe4232befc003a183ddfa 100644 --- a/test/app/init_script.result +++ b/test/app/init_script.result @@ -6,7 +6,7 @@ box.cfg 1 snapshot_count:6 2 pid_file:box.pid 3 slab_alloc_factor:2 -4 slab_alloc_minimal:64 +4 rows_per_wal:500000 5 background:false 6 logger:tarantool.log 7 slab_alloc_arena:0.1 @@ -15,15 +15,16 @@ box.cfg 10 logger_nonblock:true 11 snap_dir:. 12 coredump:false -13 wal_mode:write -14 panic_on_snap_error:true -15 panic_on_wal_error:false -16 too_long_threshold:0.5 -17 readahead:16320 -18 rows_per_wal:500000 +13 sophia_dir:./sophia +14 wal_mode:write +15 panic_on_snap_error:true +16 panic_on_wal_error:false +17 too_long_threshold:0.5 +18 slab_alloc_minimal:64 19 wal_dir:. -20 snapshot_period:0 -21 wal_dir_rescan_delay:0.1 +20 readahead:16320 +21 snapshot_period:0 +22 wal_dir_rescan_delay:0.1 -- -- Test insert from detached fiber -- diff --git a/test/app/uri.result b/test/app/uri.result new file mode 100644 index 0000000000000000000000000000000000000000..d1ab78669126331ee3f54316ce3c162bd26322fa --- /dev/null +++ b/test/app/uri.result @@ -0,0 +1,25 @@ +TAP version 13 +# uri +1..1 + # parse + 1..17 + ok - scheme + ok - login + ok - password + ok - host + ok - service + ok - path + ok - query + ok - fragment + ok - ipv4 + ok - ipv4 + ok - ipv6 + ok - ipv6 + ok - unix + ok - unix + ok - unix + ok - invalid uri + ok - invalid uri + # parse: end +ok - parse +# uri: end diff --git a/test/app/uri.test.lua b/test/app/uri.test.lua new file mode 100755 index 0000000000000000000000000000000000000000..96f2f7a5e215b52b4407c0eb872a3084db5ce29b --- /dev/null +++ b/test/app/uri.test.lua @@ -0,0 +1,46 @@ +#!/usr/bin/env tarantool + +local tap = require('tap') +local uri = require('uri') + +local function test_parse(test) + -- Tests for uri.parse() Lua bindings. + -- Parser itself is tested by test/unit/uri unit test. + test:plan(17) + + local u + + u = uri.parse("scheme://login:password@host:service".. + "/path1/path2/path3?q1=v1&q2=v2#fragment") + test:is(u.scheme, "scheme", "scheme") + test:is(u.login, "login", "login") + test:is(u.password, "password", "password") + test:is(u.host, "host", "host") + test:is(u.service, "service", "service") + test:is(u.path, "/path1/path2/path3", "path") + test:is(u.query, "q1=v1&q2=v2", "query") + test:is(u.fragment, "fragment", "fragment") + + u = uri.parse('127.0.0.1') + test:is(u.host, '127.0.0.1', 'ipv4') + test:is(u.ipv4, '127.0.0.1', 'ipv4') + + u = uri.parse('[2a00:1148:b0ba:2016:12bf:48ff:fe78:fd10]') + test:is(u.host, '2a00:1148:b0ba:2016:12bf:48ff:fe78:fd10', 'ipv6') + test:is(u.ipv6, '2a00:1148:b0ba:2016:12bf:48ff:fe78:fd10', 'ipv6') + + u = uri.parse('/tmp/unix.sock') + test:is(u.host, 'unix/', 'unix') + test:is(u.service, '/tmp/unix.sock', 'unix') + test:is(u.unix, '/tmp/unix.sock', 'unix') + + u = uri.parse("") + test:isnil(u, "invalid uri", u) + u = uri.parse("://") + test:isnil(u, "invalid uri", u) +end + +tap.test("uri", function(test) + test:plan(1) + test:test("parse", test_parse) +end) diff --git a/test/big/lua.result b/test/big/lua.result index 63e45db0529297a79fd7d07730ad5dba6dca4ba7..2d7a81ec4793d50821db2b144c028ca8c9c4494b 100644 --- a/test/big/lua.result +++ b/test/big/lua.result @@ -734,7 +734,7 @@ t:find(2, '2') ... t:find(89, '2') --- -- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next''' ... t:findall(4, '3') --- diff --git a/test/box/access.result b/test/box/access.result index eaf920e8f612ae728e6f467e72eba74730d87ed7..7ad11d39e9fed0a5ee2de6ac5226c74d2e5d3dc8 100644 --- a/test/box/access.result +++ b/test/box/access.result @@ -156,7 +156,14 @@ box.schema.user.drop('ПетÑ_Иванов') --- ... -- gh-300: misleading error message if a function does not exist -c = (require 'net.box'):new("127.0.0.1", box.cfg.listen) +LISTEN = require('uri').parse(box.cfg.listen) +--- +... +LISTEN ~= nil +--- +- true +... +c = (require 'net.box'):new(LISTEN.host, LISTEN.service) --- ... c:call('nosuchfunction') diff --git a/test/box/access.test.lua b/test/box/access.test.lua index cc7ff3a2b4c6202749f1cf5157c2fa783bcf3cb2..8569e0ec32e5093cffe4a40b75c1dc6541e17ccf 100644 --- a/test/box/access.test.lua +++ b/test/box/access.test.lua @@ -74,7 +74,9 @@ box.schema.user.create('ПетÑ_Иванов') box.schema.user.drop('ПетÑ_Иванов') -- gh-300: misleading error message if a function does not exist -c = (require 'net.box'):new("127.0.0.1", box.cfg.listen) +LISTEN = require('uri').parse(box.cfg.listen) +LISTEN ~= nil +c = (require 'net.box'):new(LISTEN.host, LISTEN.service) c:call('nosuchfunction') function nosuchfunction() end diff --git a/test/box/access_bin.result b/test/box/access_bin.result index 23aa5b2d6f54fc0b81d192f24bec291cd079f5c2..e9f6c586f8e8277036ac79b9356e7add9c755b2a 100644 --- a/test/box/access_bin.result +++ b/test/box/access_bin.result @@ -11,7 +11,14 @@ session = box.session net = { box = require('net.box') } --- ... -c = net.box:new(0, box.cfg.listen) +LISTEN = require('uri').parse(box.cfg.listen) +--- +... +LISTEN ~= nil +--- +- true +... +c = net.box:new(LISTEN.host, LISTEN.service) --- ... c:call("dostring", "session.su('admin')") @@ -45,7 +52,7 @@ box.schema.func.create('setuid_func') box.schema.user.grant('guest', 'execute', 'function', 'setuid_func') --- ... -c = net.box:new(0, box.cfg.listen) +c = net.box:new(LISTEN.host, LISTEN.service) --- ... c:call("setuid_func") @@ -95,3 +102,48 @@ setuid_space:drop() --- ... -- +-- gh-530 "assertion failed" +-- If a user is dropped, its session should not be usable +-- any more +-- +test = box.schema.space.create('test') +--- +... +test:create_index('primary') +--- +... +box.schema.user.create('test', {password='test'}) +--- +... +box.schema.user.grant('test', 'read,write', 'space','test') +--- +... +box.schema.user.grant('test', 'read', 'space', '_space') +--- +... +box.schema.user.grant('test', 'read', 'space', '_index') +--- +... +net = require('net.box') +--- +... +c = net.new(LISTEN.host, LISTEN.service, {user = 'test', password='test'}) +--- +... +c.space.test:insert{1} +--- +- [1] +... +box.schema.user.drop('test') +--- +... +c.space.test:insert{1} +--- +- error: User '3' is not found +... +c:close() +--- +... +test:drop() +--- +... diff --git a/test/box/access_bin.test.lua b/test/box/access_bin.test.lua index f9841d7ea50220baa1ddb83ccf11d29607c37b0c..7ff79d2bb53c448ae0f5df8cfdfe8b95481af5b1 100644 --- a/test/box/access_bin.test.lua +++ b/test/box/access_bin.test.lua @@ -5,7 +5,9 @@ box.schema.user.grant('guest','read,write,execute','universe') session = box.session net = { box = require('net.box') } -c = net.box:new(0, box.cfg.listen) +LISTEN = require('uri').parse(box.cfg.listen) +LISTEN ~= nil +c = net.box:new(LISTEN.host, LISTEN.service) c:call("dostring", "session.su('admin')") c:call("dostring", "return session.user()") c:close() @@ -18,7 +20,7 @@ setuid_space:create_index('primary') setuid_func = function() return box.space.setuid_space:auto_increment{} end box.schema.func.create('setuid_func') box.schema.user.grant('guest', 'execute', 'function', 'setuid_func') -c = net.box:new(0, box.cfg.listen) +c = net.box:new(LISTEN.host, LISTEN.service) c:call("setuid_func") session.su('guest') setuid_func() @@ -34,3 +36,21 @@ c:close() box.schema.func.drop('setuid_func') setuid_space:drop() -- +-- gh-530 "assertion failed" +-- If a user is dropped, its session should not be usable +-- any more +-- +test = box.schema.space.create('test') +test:create_index('primary') +box.schema.user.create('test', {password='test'}) +box.schema.user.grant('test', 'read,write', 'space','test') +box.schema.user.grant('test', 'read', 'space', '_space') +box.schema.user.grant('test', 'read', 'space', '_index') +net = require('net.box') +c = net.new(LISTEN.host, LISTEN.service, {user = 'test', password='test'}) +c.space.test:insert{1} +box.schema.user.drop('test') +c.space.test:insert{1} +c:close() +test:drop() + diff --git a/test/box/admin.result b/test/box/admin.result index bdd175de0cabf49b3009591b3ef4dae5aed94bb6..82da4e86bf979f63ca17ab5c6b2ea3b94ec767f7 100644 --- a/test/box/admin.result +++ b/test/box/admin.result @@ -21,7 +21,7 @@ box.cfg - snapshot_count: 6 too_long_threshold: 0.5 slab_alloc_factor: 2 - slab_alloc_minimal: 64 + rows_per_wal: 50 background: false slab_alloc_arena: 0.1 log_level: 5 @@ -29,14 +29,15 @@ box.cfg logger_nonblock: true snap_dir: . coredump: false + sophia_dir: ./sophia wal_mode: write panic_on_snap_error: true panic_on_wal_error: false pid_file: tarantool.pid - readahead: 16320 + slab_alloc_minimal: 64 wal_dir: . + readahead: 16320 snapshot_period: 0 - rows_per_wal: 50 wal_dir_rescan_delay: 0.1 ... space:insert{1, 'tuple'} diff --git a/test/box/alter_limits.result b/test/box/alter_limits.result index 8a64a0270eb9ea246df9d8a74aa6445d33acf323..10bf75b93b1f2adddb6b2fb14ffec0a384f0bba1 100644 --- a/test/box/alter_limits.result +++ b/test/box/alter_limits.result @@ -1189,6 +1189,21 @@ s_nil.index.secondary:count(1) --- - 0 ... +-- gh-503 if_not_exits option in create index +i1 = s_empty:create_index("test") +--- +... +i2 = s_empty:create_index("test") +--- +- error: Index 'test' already exists +... +i3 = s_empty:create_index("test", { if_not_exists = true } ) +--- +... +i3:select{} +--- +- [] +... -- cleanup s_empty:drop() --- diff --git a/test/box/alter_limits.test.lua b/test/box/alter_limits.test.lua index 1406fec524dd76b1c4e1e354fdb551d12712eb1f..73f87152d589d17a09ee24f953e0a326f21887aa 100644 --- a/test/box/alter_limits.test.lua +++ b/test/box/alter_limits.test.lua @@ -419,6 +419,12 @@ r_empty.index.secondary:count(1) r_full.index.secondary:count(1) s_nil.index.secondary:count(1) +-- gh-503 if_not_exits option in create index +i1 = s_empty:create_index("test") +i2 = s_empty:create_index("test") +i3 = s_empty:create_index("test", { if_not_exists = true } ) +i3:select{} + -- cleanup s_empty:drop() s_full:drop() diff --git a/test/box/bad_trigger.result b/test/box/bad_trigger.result index f44644d9f8c100cd2fbf57b4bb3d56fcb4847eb2..5740f76833df897d234d482b85063b3b325d19f3 100644 --- a/test/box/bad_trigger.result +++ b/test/box/bad_trigger.result @@ -1,7 +1,7 @@ - + # # if on_connect() trigger raises an exception, the connection is dropped - # + # function f1() nosuchfunction() end --- diff --git a/test/box/bad_trigger.test.py b/test/box/bad_trigger.test.py index ebbed28bf956dc93ef8450aa8bb093c36b635036..b7337cdf61c6dade851eb05a9af917b45d9275e6 100644 --- a/test/box/bad_trigger.test.py +++ b/test/box/bad_trigger.test.py @@ -1,14 +1,15 @@ from lib.box_connection import BoxConnection +from lib.tarantool_connection import TarantoolConnection from tarantool import NetworkError from tarantool.const import IPROTO_GREETING_SIZE, IPROTO_CODE, IPROTO_ERROR, \ REQUEST_TYPE_ERROR import socket import msgpack -print """ +print """ # # if on_connect() trigger raises an exception, the connection is dropped - # + # """ server.admin("function f1() nosuchfunction() end") @@ -16,8 +17,9 @@ server.admin("box.session.on_connect(f1)") unpacker = msgpack.Unpacker(use_list = False) -s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -s.connect(('localhost', server.sql.port)) +conn = TarantoolConnection(server.sql.host, server.sql.port) +conn.connect() +s = conn.socket # Read greeting print 'greeting: ', len(s.recv(IPROTO_GREETING_SIZE)) == IPROTO_GREETING_SIZE diff --git a/test/box/box.net.box.result b/test/box/box.net.box.result index f3e7a5da7c3f5043ed9d8cb67621005ec39ee638..1c0b7af47d7b1574ee1aa4bb4903967f6061bd97 100644 --- a/test/box/box.net.box.result +++ b/test/box/box.net.box.result @@ -7,10 +7,13 @@ fiber = require 'fiber' log = require 'log' --- ... +msgpack = require 'msgpack' +--- +... box.schema.user.grant('guest', 'read,write,execute', 'universe') --- ... -port = box.cfg.listen +LISTEN = require('uri').parse(box.cfg.listen) --- ... space = box.schema.create_space('net_box_test_space') @@ -23,7 +26,7 @@ space:create_index('primary', { type = 'tree' }) log.info("create connection") --- ... -cn = remote:new('127.0.0.1', port) +cn = remote:new(LISTEN.host, LISTEN.service) --- ... cn:_wait_state({'active', 'error'}, 1) @@ -138,7 +141,7 @@ cn.space.net_box_test_space:insert{234, 1,2,3} ... cn.space.net_box_test_space.insert{234, 1,2,3} --- -- error: 'builtin/net.box.lua:239: Use space:method(...) instead space.method(...)' +- error: 'builtin/net.box.lua:229: Use space:method(...) instead space.method(...)' ... cn.space.net_box_test_space:replace{354, 1,2,3} --- @@ -298,7 +301,7 @@ cn:call('test_foo') - error: Connection is not established ... -- -- 2 reconnect -cn = remote:new('127.0.0.1', port, { reconnect_after = .1 }) +cn = remote:new(LISTEN.host, LISTEN.service, { reconnect_after = .1 }) --- ... cn:_wait_state({'active'}, 1) @@ -342,8 +345,24 @@ cn:_select(space.id, 0, {}, { iterator = 'ALL' }) - - [234, 1, 2, 3] - [354, 1, 2, 4] ... +-- send broken packet (remote server will close socket) +cn.s:syswrite(msgpack.encode(1) .. msgpack.encode('abc')) +--- +- 5 +... +fiber.sleep(.2) +--- +... +cn.state +--- +- active +... +cn:ping() +--- +- true +... -- -- dot-new-method -cn1 = remote.new('127.0.0.1', port) +cn1 = remote.new(LISTEN.host, LISTEN.service) --- ... cn1:_select(space.id, 0, {}, { iterator = 'ALL' }) @@ -420,7 +439,7 @@ cn.proto.b64decode('gJLoc!!!!!!!') --- - !!binary gJLo ... -cn = remote:new('127.0.0.1', port, { user = 'netbox', password = '123', wait_connected = true }) +cn = remote:new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true }) --- ... cn:is_connected() @@ -441,7 +460,7 @@ box.schema.user.create('netbox', { password = 'test' }) box.schema.user.grant('netbox', 'read, write, execute', 'universe'); --- ... -cn = remote:new('127.0.0.1', port, { user = 'netbox', password = 'test' }) +cn = remote:new(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' }) --- ... cn.state @@ -476,11 +495,11 @@ cn:timeout(.01):call('ret_after', 1) --- - error: Timeout exceeded ... -cn = remote:timeout(0.0000000001):new('127.0.0.1', port, { user = 'netbox', password = '123' }) +cn = remote:timeout(0.0000000001):new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) --- - error: Timeout exceeded ... -cn = remote:timeout(1):new('127.0.0.1', port, { user = 'netbox', password = '123' }) +cn = remote:timeout(1):new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) --- ... remote.self:ping() @@ -499,3 +518,119 @@ remote.self:timeout(123).space.net_box_test_space:select{234} space:drop() --- ... +-- admin console tests +function console_test(...) return { ... } end +--- +... +function console_test_error(...) error(string.format(...)) end +--- +... +function console_unpack_test(...) return ... end +--- +... +ADMIN = require('uri').parse(os.getenv('ADMIN')) +--- +... +cn = remote:new(LISTEN.host, LISTEN.service) +--- +... +cnc = remote:new(ADMIN.host, ADMIN.service) +--- +... +cnc.console +--- +- true +... +cn:call('console_test', 1, 2, 3, 'string', nil) +--- +- - [1, 2, 3, 'string'] +... +cnc:call('console_test', 1, 2, 3, 'string', nil) +--- +- - [1, 2, 3, 'string'] +... +cn:call('console_test_error', 'error %d', 123) +--- +- error: '[string "function console_test_error(...) error(string..."]:1: error 123' +... +cnc:call('console_test_error', 'error %d', 123) +--- +- error: '[string "function console_test_error(...) error(string..."]:1: error 123' +... +cn:call('console_unpack_test', 1) +--- +- - [1] +... +cnc:call('console_unpack_test', 1) +--- +- - [1] +... +cn:call('123') +--- +- error: Procedure '123' is not defined +... +cnc:call('123') +--- +- error: '[string "123()"]:1: unexpected symbol near ''123''' +... +-- #545 user or password is not defined +remote:new(LISTEN.host, LISTEN.service, { user = 'test' }) +--- +- error: 'net.box: password is not defined' +... +remote:new(LISTEN.host, LISTEN.service, { password = 'test' }) +--- +- error: 'net.box: user is not defined' +... +-- #544 usage for remote[point]method +cn:call('console_test') +--- +- - [] +... +cn.call('console_test') +--- +- error: 'usage: remote:call(proc_name, ...)' +... +cn.ping() +--- +- error: 'usage: remote:ping()' +... +remote.self:call('console_test') +--- +- [] +... +remote.self.call('console_test') +--- +- error: 'usage: remote:call(proc_name, ...)' +... +-- uri as the first argument +uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service) +--- +... +cn = remote.new(uri) +--- +... +cn:ping() +--- +- true +... +cn:close() +--- +... +uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service) +--- +... +remote.new(uri) +--- +- error: 'net.box: password is not defined' +... +cn = remote.new(uri, { password = 'test' }) +--- +... +cn:ping() +--- +- true +... +cn:close() +--- +... diff --git a/test/box/box.net.box.test.lua b/test/box/box.net.box.test.lua index 647a62c6bc2bdac682ab6e6e872d167628e41f45..e1b7396b052abe0e74b7ac37f9759e8433b61377 100644 --- a/test/box/box.net.box.test.lua +++ b/test/box/box.net.box.test.lua @@ -1,15 +1,16 @@ remote = require 'net.box' fiber = require 'fiber' log = require 'log' +msgpack = require 'msgpack' box.schema.user.grant('guest', 'read,write,execute', 'universe') -port = box.cfg.listen +LISTEN = require('uri').parse(box.cfg.listen) space = box.schema.create_space('net_box_test_space') space:create_index('primary', { type = 'tree' }) -- low level connection log.info("create connection") -cn = remote:new('127.0.0.1', port) +cn = remote:new(LISTEN.host, LISTEN.service) cn:_wait_state({'active', 'error'}, 1) log.info("state is %s", cn.state) @@ -105,7 +106,7 @@ cn:ping() cn:call('test_foo') -- -- 2 reconnect -cn = remote:new('127.0.0.1', port, { reconnect_after = .1 }) +cn = remote:new(LISTEN.host, LISTEN.service, { reconnect_after = .1 }) cn:_wait_state({'active'}, 1) cn.space ~= nil @@ -119,9 +120,16 @@ cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) cn:_fatal 'Test error' cn:_select(space.id, 0, {}, { iterator = 'ALL' }) +-- send broken packet (remote server will close socket) +cn.s:syswrite(msgpack.encode(1) .. msgpack.encode('abc')) +fiber.sleep(.2) + +cn.state +cn:ping() + -- -- dot-new-method -cn1 = remote.new('127.0.0.1', port) +cn1 = remote.new(LISTEN.host, LISTEN.service) cn1:_select(space.id, 0, {}, { iterator = 'ALL' }) -- -- error while waiting for response @@ -151,7 +159,7 @@ res[1][2] == string.rep('a', 50000) cn.proto.b64decode('gJLocxbO32VmfO8x04xRVxKfgwzmNVM2t6a1ME8XsD0=') cn.proto.b64decode('gJLoc!!!!!!!') -cn = remote:new('127.0.0.1', port, { user = 'netbox', password = '123', wait_connected = true }) +cn = remote:new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true }) cn:is_connected() cn.error cn.state @@ -159,7 +167,7 @@ cn.state box.schema.user.create('netbox', { password = 'test' }) box.schema.user.grant('netbox', 'read, write, execute', 'universe'); -cn = remote:new('127.0.0.1', port, { user = 'netbox', password = 'test' }) +cn = remote:new(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' }) cn.state cn.error cn:ping() @@ -172,8 +180,8 @@ cn:call('ret_after', .01) cn:timeout(1):call('ret_after', .01) cn:timeout(.01):call('ret_after', 1) -cn = remote:timeout(0.0000000001):new('127.0.0.1', port, { user = 'netbox', password = '123' }) -cn = remote:timeout(1):new('127.0.0.1', port, { user = 'netbox', password = '123' }) +cn = remote:timeout(0.0000000001):new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) +cn = remote:timeout(1):new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) @@ -187,3 +195,60 @@ remote.self:timeout(123).space.net_box_test_space:select{234} -- cleanup database after tests space:drop() + +-- admin console tests +function console_test(...) return { ... } end +function console_test_error(...) error(string.format(...)) end +function console_unpack_test(...) return ... end + + +ADMIN = require('uri').parse(os.getenv('ADMIN')) + +cn = remote:new(LISTEN.host, LISTEN.service) +cnc = remote:new(ADMIN.host, ADMIN.service) +cnc.console + +cn:call('console_test', 1, 2, 3, 'string', nil) +cnc:call('console_test', 1, 2, 3, 'string', nil) + +cn:call('console_test_error', 'error %d', 123) +cnc:call('console_test_error', 'error %d', 123) + + +cn:call('console_unpack_test', 1) +cnc:call('console_unpack_test', 1) + + + + +cn:call('123') +cnc:call('123') + + +-- #545 user or password is not defined +remote:new(LISTEN.host, LISTEN.service, { user = 'test' }) +remote:new(LISTEN.host, LISTEN.service, { password = 'test' }) + +-- #544 usage for remote[point]method +cn:call('console_test') +cn.call('console_test') + +cn.ping() + +remote.self:call('console_test') +remote.self.call('console_test') + + +-- uri as the first argument +uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service) + +cn = remote.new(uri) +cn:ping() +cn:close() + +uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service) +remote.new(uri) +cn = remote.new(uri, { password = 'test' }) +cn:ping() +cn:close() + diff --git a/test/box/bsdsocket.result b/test/box/bsdsocket.result index ccc0973dea38030d9b48b65242cb2c55859ef2ea..b2122b38bd5b489c9c19d317676ca476041fd71d 100644 --- a/test/box/bsdsocket.result +++ b/test/box/bsdsocket.result @@ -22,6 +22,9 @@ log = require 'log' errno = require 'errno' --- ... +fio = require 'fio' +--- +... type(socket) --- - table @@ -59,18 +62,26 @@ for k in pairs(getmetatable(s).__index) do end; --- ... ---# setopt delimiter '' -port = string.gsub(box.cfg.listen, '^.*:', '') +s:close() --- +- true ... -s:nonblock(false) +--# setopt delimiter '' +s:close() + --- - false ... -s:sysconnect('127.0.0.1', port) +LISTEN = require('uri').parse(box.cfg.listen) +--- +... +LISTEN ~= nil --- - true ... +s = socket.tcp_connect(LISTEN.host, LISTEN.service) +--- +... s:nonblock(true) --- - true @@ -268,7 +279,7 @@ s:getsockopt('SOL_SOCKET', 'SO_DEBUG') ... s:setsockopt('SOL_SOCKET', 'SO_ACCEPTCONN', 1) --- -- error: 'builtin/socket.lua:341: Socket option SO_ACCEPTCONN is read only' +- error: 'builtin/socket.lua:343: Socket option SO_ACCEPTCONN is read only' ... s:getsockopt('SOL_SOCKET', 'SO_RCVBUF') > 32 --- @@ -349,8 +360,19 @@ sc:write('Hello, world') --- - true ... -sa = s:accept() +sa, addr = s:accept() +--- +... +addr2 = sa:name() +--- +... +addr2.host == addr.host +--- +- true +... +addr2.family == addr.family --- +- true ... sa:nonblock(1) --- @@ -1209,9 +1231,13 @@ os.remove(path) --- - true ... -server = socket.tcp_server('unix/', path, function(s) s:write('Hello, world') end) +server, addr = socket.tcp_server('unix/', path, function(s) s:write('Hello, world') end) --- ... +type(addr) +--- +- table +... server ~= nil --- - true @@ -1230,11 +1256,83 @@ client:read(123) --- - Hello, world ... -server:stop() +server:close() --- - true ... -os.remove(path) +-- unix socket automatically removed +fio.stat(path) == nil +--- +- true +... +--# setopt delimiter ';' +server, addr = socket.tcp_server('localhost', 0, { handler = function(s) + s:read(2) + s:write('Hello, world') +end, name = 'testserv'}); +--- +... +--# setopt delimiter '' +type(addr) +--- +- table +... +server ~= nil +--- +- true +... +addr2 = server:name() +--- +... +addr.host == addr2.host +--- +- true +... +addr.family == addr2.family +--- +- true +... +fiber.sleep(.5) +--- +... +client = socket.tcp_connect(addr2.host, addr2.port) +--- +... +client ~= nil +--- +- true +... +-- Check that listen and client fibers have appropriate names +cnt = 0 +--- +... +--# setopt delimiter ';' +for i=100,200 do + local f = fiber.find(i) + if f and f:name():match('^testserv/') then + cnt = cnt + 1 + end +end; +--- +... +--# setopt delimiter '' +cnt +--- +- 2 +... +client:write('hi') +--- +- true +... +client:read(123) +--- +- Hello, world +... +client:close() +--- +- true +... +server:close() --- - true ... @@ -1275,11 +1373,7 @@ client:read{ line = { "\n\n", "\r\n\r\n" } } --- - "Hello\r\n\r\n" ... -server:stop() ---- -- true -... -os.remove(path) +server:close() --- - true ... @@ -1339,3 +1433,50 @@ yaml.decode(yaml.encode(s)).fd == s:fd() s = nil --- ... +-- start AF_UNIX server with dead socket exists +path = '/tmp/tarantool-test-socket' +--- +... +s = socket('AF_UNIX', 'SOCK_STREAM', 0) +--- +... +s:bind('unix/', path) +--- +- true +... +s:close() +--- +- true +... +s = socket('AF_UNIX', 'SOCK_STREAM', 0) +--- +... +{ s:bind('unix/', path), errno.strerror() } +--- +- - false + - Address already in use +... +s:close() +--- +- true +... +s = socket.tcp_server('unix/', path, function() end) +--- +... +s ~= nil +--- +- true +... +s:close() +--- +- true +... +fio.stat(path) == nil +--- +- true +... +{ socket.tcp_connect('abrakadabra#123') == nil, errno.strerror() } +--- +- - true + - Invalid argument +... diff --git a/test/box/bsdsocket.test.lua b/test/box/bsdsocket.test.lua index 7ead95599262bb1498d51354ba5cd88928b7ed1b..8fc124573ef7a22ad677a899eef160ccb1f812e0 100644 --- a/test/box/bsdsocket.test.lua +++ b/test/box/bsdsocket.test.lua @@ -6,6 +6,7 @@ fiber = require 'fiber' msgpack = require 'msgpack' log = require 'log' errno = require 'errno' +fio = require 'fio' type(socket) socket('PF_INET', 'SOCK_STREAM', 'tcp121222'); @@ -23,12 +24,12 @@ for k in pairs(getmetatable(s).__index) do error("Arguments is not checked for "..k) end end; +s:close() --# setopt delimiter '' -port = string.gsub(box.cfg.listen, '^.*:', '') - -s:nonblock(false) -s:sysconnect('127.0.0.1', port) +LISTEN = require('uri').parse(box.cfg.listen) +LISTEN ~= nil +s = socket.tcp_connect(LISTEN.host, LISTEN.service) s:nonblock(true) s:nonblock() s:nonblock(false) @@ -114,7 +115,10 @@ sc:writable(10) sc:write('Hello, world') -sa = s:accept() +sa, addr = s:accept() +addr2 = sa:name() +addr2.host == addr.host +addr2.family == addr.family sa:nonblock(1) sa:read(8) sa:read(3) @@ -404,37 +408,59 @@ s:close() os.remove(path) -server = socket.tcp_server('unix/', path, function(s) s:write('Hello, world') end) +server, addr = socket.tcp_server('unix/', path, function(s) s:write('Hello, world') end) +type(addr) server ~= nil fiber.sleep(.5) client = socket.tcp_connect('unix/', path) client ~= nil client:read(123) -server:stop() -os.remove(path) +server:close() +-- unix socket automatically removed +fio.stat(path) == nil +--# setopt delimiter ';' +server, addr = socket.tcp_server('localhost', 0, { handler = function(s) + s:read(2) + s:write('Hello, world') +end, name = 'testserv'}); +--# setopt delimiter '' +type(addr) +server ~= nil +addr2 = server:name() +addr.host == addr2.host +addr.family == addr2.family +fiber.sleep(.5) +client = socket.tcp_connect(addr2.host, addr2.port) +client ~= nil +-- Check that listen and client fibers have appropriate names +cnt = 0 +--# setopt delimiter ';' +for i=100,200 do + local f = fiber.find(i) + if f and f:name():match('^testserv/') then + cnt = cnt + 1 + end +end; +--# setopt delimiter '' +cnt +client:write('hi') +client:read(123) +client:close() +server:close() longstring = string.rep("abc", 65535) server = socket.tcp_server('unix/', path, function(s) s:write(longstring) end) - client = socket.tcp_connect('unix/', path) client:read(#longstring) == longstring - client = socket.tcp_connect('unix/', path) client:read(#longstring + 1) == longstring - client = socket.tcp_connect('unix/', path) client:read(#longstring - 1) == string.sub(longstring, 1, #longstring - 1) - - longstring = "Hello\r\n\r\nworld\n\n" - client = socket.tcp_connect('unix/', path) client:read{ line = { "\n\n", "\r\n\r\n" } } - - -server:stop() -os.remove(path) +server:close() -- Test that socket is closed on GC @@ -456,3 +482,20 @@ s.waiters json.decode(json.encode(s)).fd == s:fd() yaml.decode(yaml.encode(s)).fd == s:fd() s = nil + +-- start AF_UNIX server with dead socket exists +path = '/tmp/tarantool-test-socket' +s = socket('AF_UNIX', 'SOCK_STREAM', 0) +s:bind('unix/', path) +s:close() + +s = socket('AF_UNIX', 'SOCK_STREAM', 0) +{ s:bind('unix/', path), errno.strerror() } +s:close() + +s = socket.tcp_server('unix/', path, function() end) +s ~= nil +s:close() +fio.stat(path) == nil + +{ socket.tcp_connect('abrakadabra#123') == nil, errno.strerror() } diff --git a/test/box/cfg.result b/test/box/cfg.result index f08d7e79efa89372d846a4ea3447610016101b5d..6255ecf21bc9c468f64457ac52de01800a8b8e89 100644 --- a/test/box/cfg.result +++ b/test/box/cfg.result @@ -2,7 +2,7 @@ --# push filter 'admin: .*' to 'admin: <uri>' box.cfg.nosuchoption = 1 --- -- error: '[string "-- load_cfg.lua - internal file..."]:202: Attempt to modify a read-only +- error: '[string "-- load_cfg.lua - internal file..."]:195: Attempt to modify a read-only table' ... t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end @@ -13,7 +13,7 @@ t - - 'snapshot_count: 6' - 'too_long_threshold: 0.5' - 'slab_alloc_factor: 2' - - 'slab_alloc_minimal: 64' + - 'rows_per_wal: 50' - 'background: false' - 'slab_alloc_arena: 0.1' - 'log_level: 5' @@ -21,14 +21,15 @@ t - 'logger_nonblock: true' - 'snap_dir: .' - 'coredump: false' + - 'sophia_dir: ./sophia' - 'wal_mode: write' - 'panic_on_snap_error: true' - 'panic_on_wal_error: false' - 'pid_file: tarantool.pid' - - 'readahead: 16320' + - 'slab_alloc_minimal: 64' - 'wal_dir: .' + - 'readahead: 16320' - 'snapshot_period: 0' - - 'rows_per_wal: 50' - 'wal_dir_rescan_delay: 0.1' ... -- must be read-only @@ -43,7 +44,7 @@ t - - 'snapshot_count: 6' - 'too_long_threshold: 0.5' - 'slab_alloc_factor: 2' - - 'slab_alloc_minimal: 64' + - 'rows_per_wal: 50' - 'background: false' - 'slab_alloc_arena: 0.1' - 'log_level: 5' @@ -51,14 +52,37 @@ t - 'logger_nonblock: true' - 'snap_dir: .' - 'coredump: false' + - 'sophia_dir: ./sophia' - 'wal_mode: write' - 'panic_on_snap_error: true' - 'panic_on_wal_error: false' - 'pid_file: tarantool.pid' - - 'readahead: 16320' + - 'slab_alloc_minimal: 64' - 'wal_dir: .' + - 'readahead: 16320' - 'snapshot_period: 0' - - 'rows_per_wal: 50' - 'wal_dir_rescan_delay: 0.1' ... +-- check that cfg with unexpected parameter fails. +box.cfg{sherlock = 'holmes'} +--- +- error: '[string "-- load_cfg.lua - internal file..."]:121: Error: cfg parameter + ''sherlock'' is unexpected' +... +-- check that cfg with unexpected type of parameter failes +box.cfg{listen = {}} +--- +- error: '[string "-- load_cfg.lua - internal file..."]:136: Error: cfg parameter + ''listen'' should be one of types: string, number' +... +box.cfg{wal_dir = 0} +--- +- error: '[string "-- load_cfg.lua - internal file..."]:130: Error: cfg parameter + ''wal_dir'' should be of type string' +... +box.cfg{coredump = 'true'} +--- +- error: '[string "-- load_cfg.lua - internal file..."]:130: Error: cfg parameter + ''coredump'' should be of type boolean' +... --# clear filter diff --git a/test/box/cfg.test.lua b/test/box/cfg.test.lua index ee99deae794a6f606d6711abe6d65f4d19adb0d6..9d4e87075df1a961723c3e1a9badf8d65257f974 100644 --- a/test/box/cfg.test.lua +++ b/test/box/cfg.test.lua @@ -7,4 +7,13 @@ t box.cfg() t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end t + +-- check that cfg with unexpected parameter fails. +box.cfg{sherlock = 'holmes'} + +-- check that cfg with unexpected type of parameter failes +box.cfg{listen = {}} +box.cfg{wal_dir = 0} +box.cfg{coredump = 'true'} + --# clear filter diff --git a/test/box/digest.result b/test/box/digest.result index 4ee42a1f2098208c350c09789214312c3d4a3e99..0113ed92b6cd092d4543bde83331d1a09f28dce3 100644 --- a/test/box/digest.result +++ b/test/box/digest.result @@ -149,6 +149,64 @@ digest.crc32_update(digest.crc32('abc'), 'cde') --- - 3628146660 ... +digest.base64_encode('12345') +--- +- MTIzNDU= +... +digest.base64_decode('MTIzNDU=') +--- +- '12345' +... +digest.base64_encode('asdfl asdf adfa zxc vzxcvz llll') +--- +- YXNkZmwgYXNkZiBhZGZhIHp4YyB2enhjdnogbGxsbA== +... +digest.base64_decode('YXNkZmwgYXNkZiBhZGZhIHp4YyB2enhjdnogbGxsbA==') +--- +- asdfl asdf adfa zxc vzxcvz llll +... +digest.base64_encode('11 00 11 00 abcdef ABCDEF 00 11 00 11') +--- +- MTEgMDAgMTEgMDAgYWJjZGVmIEFCQ0RFRiAwMCAxMSAwMCAxMQ== +... +digest.base64_decode('MTEgMDAgMTEgMDAgYWJjZGVmIEFCQ0RFRiAwMCAxMSAwMCAxMQ==') +--- +- 11 00 11 00 abcdef ABCDEF 00 11 00 11 +... +s = string.rep('a', 54 * 2) -- two lines in base64 +--- +... +b = digest.base64_encode(s) +--- +... +b +--- +- 'YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh + + YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh + +' +... +digest.base64_decode(b) == s +--- +- true +... +digest.base64_decode(nil) +--- +- error: 'builtin/digest.lua:88: Usage: digest.base64_decode(string)' +... +digest.base64_encode(nil) +--- +- error: 'builtin/digest.lua:77: Usage: digest.base64_encode(string)' +... +digest.base64_encode(123) +--- +- error: 'builtin/digest.lua:77: Usage: digest.base64_encode(string)' +... +digest.base64_decode(123) +--- +- error: 'builtin/digest.lua:88: Usage: digest.base64_decode(string)' +... digest = nil --- ... diff --git a/test/box/digest.test.lua b/test/box/digest.test.lua index 96f3b5c6d2aa1fb014a79a2e900d50bb1cbb05f4..6475bf6b650136b9cd62cc81a0d1b134d9989b7d 100644 --- a/test/box/digest.test.lua +++ b/test/box/digest.test.lua @@ -43,4 +43,20 @@ digest.crc32_update(4294967295, 'abc') digest.crc32('abccde') digest.crc32_update(digest.crc32('abc'), 'cde') + +digest.base64_encode('12345') +digest.base64_decode('MTIzNDU=') +digest.base64_encode('asdfl asdf adfa zxc vzxcvz llll') +digest.base64_decode('YXNkZmwgYXNkZiBhZGZhIHp4YyB2enhjdnogbGxsbA==') +digest.base64_encode('11 00 11 00 abcdef ABCDEF 00 11 00 11') +digest.base64_decode('MTEgMDAgMTEgMDAgYWJjZGVmIEFCQ0RFRiAwMCAxMSAwMCAxMQ==') +s = string.rep('a', 54 * 2) -- two lines in base64 +b = digest.base64_encode(s) +b +digest.base64_decode(b) == s +digest.base64_decode(nil) +digest.base64_encode(nil) +digest.base64_encode(123) +digest.base64_decode(123) + digest = nil diff --git a/test/box/fiber.result b/test/box/fiber.result index 58656e42e8ad628672c8a494ceafa4e72ecfe505..13a1aa6044ed9b8a51b2f6744deef3477548b8f8 100644 --- a/test/box/fiber.result +++ b/test/box/fiber.result @@ -726,6 +726,44 @@ done --- - true ... +-- # gh-536: fiber.info() doesn't list fibers with default names +-- +function loop() while true do fiber.sleep(10) end end +--- +... +f1 = fiber.create(loop) +--- +... +f2 = fiber.create(loop) +--- +... +f3 = fiber.create(loop) +--- +... +info = fiber.info() +--- +... +info[f1:id()] ~= nil +--- +- true +... +info[f2:id()] ~= nil +--- +- true +... +info[f3:id()] ~= nil +--- +- true +... +f1:cancel() +--- +... +f2:cancel() +--- +... +f3:cancel() +--- +... fiber = nil --- ... diff --git a/test/box/fiber.test.lua b/test/box/fiber.test.lua index 8c80a81c45e15cd3e8f1b1aa5c21a671947e5974..258561e06c04dc5b89bbe9f055cd63c2dcb2b8c4 100644 --- a/test/box/fiber.test.lua +++ b/test/box/fiber.test.lua @@ -296,4 +296,20 @@ end; f = fiber.create(test) done +-- # gh-536: fiber.info() doesn't list fibers with default names +-- +function loop() while true do fiber.sleep(10) end end +f1 = fiber.create(loop) +f2 = fiber.create(loop) +f3 = fiber.create(loop) + +info = fiber.info() +info[f1:id()] ~= nil +info[f2:id()] ~= nil +info[f3:id()] ~= nil + +f1:cancel() +f2:cancel() +f3:cancel() + fiber = nil diff --git a/test/box/fio.result b/test/box/fio.result index 1485c63ad1689a6263814b9a4919af3b1314692a..301874a6dfd5bcae89e7bac05406b7f1f0306d51 100644 --- a/test/box/fio.result +++ b/test/box/fio.result @@ -286,3 +286,24 @@ fio.unlink(nil) --- - false ... +-- dirname +fio.dirname('abc') +--- +- . +... +fio.dirname('/abc') +--- +- / +... +fio.dirname('/abc/cde') +--- +- /abc +... +fio.dirname('/abc/cde/') +--- +- /abc +... +fio.dirname('/') +--- +- / +... diff --git a/test/box/fio.test.lua b/test/box/fio.test.lua index c97c15965a5d0f12d9d25e1c279a69bb2e5c0d54..2a18ee6df2479a0d0f98c6b6cf1c2907b76460ab 100644 --- a/test/box/fio.test.lua +++ b/test/box/fio.test.lua @@ -97,3 +97,11 @@ fio.rmdir(tmpdir) fio.unlink() fio.unlink(nil) + +-- dirname + +fio.dirname('abc') +fio.dirname('/abc') +fio.dirname('/abc/cde') +fio.dirname('/abc/cde/') +fio.dirname('/') diff --git a/test/box/iproto.test.py b/test/box/iproto.test.py index cde404f3256f3220b3ef20a5410b2ed7a638c0bb..c4c60e52bc91ea2fb1a122b306305856c22e7b1b 100644 --- a/test/box/iproto.test.py +++ b/test/box/iproto.test.py @@ -7,6 +7,7 @@ from tarantool.const import * from tarantool import Connection from tarantool.request import Request, RequestInsert, RequestSelect from tarantool.response import Response +from lib.tarantool_connection import TarantoolConnection admin("box.schema.user.grant('guest', 'read,write,execute', 'universe')") @@ -17,8 +18,9 @@ print """ """ # opeing new connection to tarantool/box -s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -s.connect(('localhost', server.sql.port)) +conn = TarantoolConnection(server.sql.host, server.sql.port) +conn.connect() +s = conn.socket print """ # Test bug #899343 (server assertion failure on incorrect packet) diff --git a/test/box/misc.result b/test/box/misc.result index 651ae9f1b75a0d42dc9afe54cf5d2b4b269b7687..f779861515522d17820dbd8a4bfdf29d885ac32b 100644 --- a/test/box/misc.result +++ b/test/box/misc.result @@ -24,6 +24,7 @@ t - info - internal - rollback + - runtime - schema - session - slab @@ -154,6 +155,14 @@ t; - arena_size - slabs ... +box.runtime.info().used > 0; +--- +- true +... +box.runtime.info().maxalloc > 0; +--- +- true +... -- -- gh-502: box.slab.info() excessively sparse array -- @@ -173,11 +182,11 @@ end; t; --- - - 'box.error.EXACT_MATCH : 19' - - 'box.error.SECONDARY : 7' + - 'box.error.NO_SUCH_TRIGGER : 34' - 'box.error.CLUSTER_ID_IS_RO : 65' - 'box.error.INDEX_TYPE : 13' - 'box.error.CLUSTER_ID_MISMATCH : 63' - - 'box.error.FIELD_TYPE : 23' + - 'box.error.MEMORY_ISSUE : 2' - 'box.error.KEY_PART_TYPE : 18' - 'box.error.CREATE_FUNCTION : 50' - 'box.error.SOPHIA : 60' @@ -200,11 +209,12 @@ t; - 'box.error.CREATE_USER : 43' - 'box.error.CREATE_SPACE : 9' - 'box.error.UNKNOWN_SCHEMA_OBJECT : 49' + - 'box.error.PROC_LUA : 32' - 'box.error.CREATE_ROLE : 84' - 'box.error.ROLE_EXISTS : 83' - 'box.error.NO_SUCH_ROLE : 82' - 'box.error.NO_ACTIVE_TRANSACTION : 80' - - 'box.error.SPLICE : 25' + - 'box.error.TUPLE_FOUND : 3' - 'box.error.FIELD_TYPE_MISMATCH : 24' - 'box.error.UNSUPPORTED : 5' - 'box.error.INVALID_MSGPACK : 20' @@ -212,7 +222,7 @@ t; - 'box.error.ALTER_SPACE : 12' - 'box.error.ACTIVE_TRANSACTION : 79' - 'box.error.NO_CONNECTION : 77' - - 'box.error.DROP_SPACE : 11' + - 'box.error.FIELD_TYPE : 23' - 'box.error.INVALID_XLOG_NAME : 75' - 'box.error.INVALID_XLOG : 74' - 'box.error.REPLICA_MAX : 73' @@ -226,34 +236,34 @@ t; - 'box.error.INVALID_ORDER : 68' - 'box.error.CFG : 59' - 'box.error.SPACE_FIELD_COUNT : 38' - - 'box.error.SPACE_ACCESS_DENIED : 55' + - 'box.error.UNKNOWN : 0' - 'box.error.NO_SUCH_FIELD : 37' - 'box.error.LOCAL_SERVER_IS_NOT_ACTIVE : 61' - 'box.error.RELOAD_CFG : 58' - 'box.error.PROC_RET : 21' - 'box.error.INJECTION : 8' - - 'box.error.PROC_LUA : 32' + - 'box.error.FUNCTION_MAX : 54' - 'box.error.ILLEGAL_PARAMS : 1' - - 'box.error.TUPLE_NOT_ARRAY : 22' - 'box.error.TUPLE_FORMAT_LIMIT : 16' + - 'box.error.USER_MAX : 56' - 'box.error.INVALID_UUID : 64' - - 'box.error.UNKNOWN : 0' + - 'box.error.SPLICE : 25' - 'box.error.TIMEOUT : 78' - - 'box.error.TUPLE_FOUND : 3' - - 'box.error.MEMORY_ISSUE : 2' - - 'box.error.NO_SUCH_TRIGGER : 34' + - 'box.error.MORE_THAN_ONE_TUPLE : 41' + - 'box.error.NO_SUCH_SPACE : 36' + - 'box.error.INDEX_EXISTS : 85' - 'box.error.UPDATE_FIELD : 29' - 'box.error.ARG_TYPE : 26' - - 'box.error.NO_SUCH_SPACE : 36' - 'box.error.INDEX_FIELD_COUNT : 39' - - 'box.error.MORE_THAN_ONE_TUPLE : 41' + - 'box.error.READONLY : 7' - 'box.error.DROP_PRIMARY_KEY : 17' + - 'box.error.DROP_SPACE : 11' - 'box.error.UNKNOWN_REQUEST_TYPE : 48' - 'box.error.INVALID_XLOG_ORDER : 76' - - 'box.error.FUNCTION_MAX : 54' + - 'box.error.SPACE_ACCESS_DENIED : 55' - 'box.error.NO_SUCH_USER : 45' - - 'box.error.USER_MAX : 56' - 'box.error.UNKNOWN_UPDATE_OP : 28' + - 'box.error.TUPLE_NOT_ARRAY : 22' - 'box.error.NO_SUCH_PROC : 33' - 'box.error.FUNCTION_ACCESS_DENIED : 53' ... diff --git a/test/box/misc.test.lua b/test/box/misc.test.lua index dd7c2ddb984a11ca9c3b678882f026014d7aef23..10edd169c8516ee26cee0b29bcb0373a693787ef 100644 --- a/test/box/misc.test.lua +++ b/test/box/misc.test.lua @@ -61,6 +61,8 @@ for k, v in pairs(box.slab.info()) do table.insert(t, k) end; t; +box.runtime.info().used > 0; +box.runtime.info().maxalloc > 0; -- -- gh-502: box.slab.info() excessively sparse array diff --git a/test/box/protocol.result b/test/box/protocol.result index fbbe9a349d1bfb0d36868ed35a4e8568f23f3d3a..f1e99fccb70c88b6891e9fa4be66a9540d47fd2b 100644 --- a/test/box/protocol.result +++ b/test/box/protocol.result @@ -13,10 +13,14 @@ space:create_index('primary', { type = 'tree'}) for i=1,5 do space:insert{i} end --- ... -port = string.gsub(box.cfg.listen, '^.*:', '') +LISTEN = require('uri').parse(box.cfg.listen) --- ... -conn = (require 'net.box'):new('127.0.0.1', tonumber(port)) +LISTEN ~= nil +--- +- true +... +conn = (require 'net.box'):new(LISTEN.host, LISTEN.service) --- ... conn.space[space.id]:select(3, { iterator = 'GE' }) diff --git a/test/box/protocol.test.lua b/test/box/protocol.test.lua index 975fb20ffa50199fbf1bf2e2e16568e5ff6e01ad..fa75d8d8cd854e8020ccfb2ae59dc567fcd1f6f1 100644 --- a/test/box/protocol.test.lua +++ b/test/box/protocol.test.lua @@ -8,8 +8,9 @@ space = box.schema.create_space('tweedledum') space:create_index('primary', { type = 'tree'}) for i=1,5 do space:insert{i} end -port = string.gsub(box.cfg.listen, '^.*:', '') -conn = (require 'net.box'):new('127.0.0.1', tonumber(port)) +LISTEN = require('uri').parse(box.cfg.listen) +LISTEN ~= nil +conn = (require 'net.box'):new(LISTEN.host, LISTEN.service) conn.space[space.id]:select(3, { iterator = 'GE' }) conn.space[space.id]:select(3, { iterator = 'LE' }) conn.space[space.id]:select(3, { iterator = 'GT' }) diff --git a/test/box/session.result b/test/box/session.result index b0610ea741b85f00382872938bfcf11f28861874..96469ca9389aae39fe99580b2ec388a3bc57bc05 100644 --- a/test/box/session.result +++ b/test/box/session.result @@ -128,7 +128,10 @@ session.on_disconnect(dec) active_connections = 0 --- ... -c = net.box:new(0, box.cfg.listen) +LISTEN = require('uri').parse(box.cfg.listen) +--- +... +c = net.box:new(LISTEN.host, LISTEN.service) --- ... while active_connections < 1 do fiber.sleep(0.001) end @@ -138,7 +141,7 @@ active_connections --- - 1 ... -c1 = net.box:new(0, box.cfg.listen) +c1 = net.box:new(LISTEN.host, LISTEN.service) --- ... while active_connections < 2 do fiber.sleep(0.001) end @@ -183,7 +186,7 @@ session.on_disconnect(audit_disconnect) box.schema.user.grant('guest', 'read,write,execute', 'universe') --- ... -a = net.box:new('127.0.0.1', box.cfg.listen) +a = net.box:new(LISTEN.host, LISTEN.service) --- ... a:call('dostring', 'return space:get{session.id()}[1] == session.id()')[1][1] diff --git a/test/box/session.test.lua b/test/box/session.test.lua index 9be90f703391a53abcb661a3562237698bfbd292..95152624feb1015433c4c135a6500a97510228ed 100644 --- a/test/box/session.test.lua +++ b/test/box/session.test.lua @@ -51,10 +51,11 @@ net = { box = require('net.box') } session.on_connect(inc) session.on_disconnect(dec) active_connections = 0 -c = net.box:new(0, box.cfg.listen) +LISTEN = require('uri').parse(box.cfg.listen) +c = net.box:new(LISTEN.host, LISTEN.service) while active_connections < 1 do fiber.sleep(0.001) end active_connections -c1 = net.box:new(0, box.cfg.listen) +c1 = net.box:new(LISTEN.host, LISTEN.service) while active_connections < 2 do fiber.sleep(0.001) end active_connections c:close() @@ -72,7 +73,7 @@ session.on_connect(audit_connect) session.on_disconnect(audit_disconnect) box.schema.user.grant('guest', 'read,write,execute', 'universe') -a = net.box:new('127.0.0.1', box.cfg.listen) +a = net.box:new(LISTEN.host, LISTEN.service) a:call('dostring', 'return space:get{session.id()}[1] == session.id()')[1][1] a:close() diff --git a/test/box/snap_daemon.result b/test/box/snapshot_daemon.result similarity index 93% rename from test/box/snap_daemon.result rename to test/box/snapshot_daemon.result index e411a87accc3ec5ed842a16873eb06664735ddf5..57e0fd3d52964518cf632195051ce6f36021c963 100644 --- a/test/box/snap_daemon.result +++ b/test/box/snapshot_daemon.result @@ -43,7 +43,7 @@ end --- ... -space = box.schema.create_space('snap_daemon') +space = box.schema.create_space('snapshot_daemon') --- ... space:create_index('pk', { type = 'tree', parts = { 1, 'num' }}) @@ -112,3 +112,7 @@ PERIOD --- - 0.03 ... +box.cfg{ snapshot_count = .2 } +--- +- error: snapshot_count must be integer +... diff --git a/test/box/snap_daemon.test.lua b/test/box/snapshot_daemon.test.lua similarity index 94% rename from test/box/snap_daemon.test.lua rename to test/box/snapshot_daemon.test.lua index bdfcc649274af25bdb9f564dfe1e17d884d62f4a..45aeb441fc5981d1527210571af289b486396613 100644 --- a/test/box/snap_daemon.test.lua +++ b/test/box/snapshot_daemon.test.lua @@ -23,7 +23,7 @@ end --# setopt delimiter '' -space = box.schema.create_space('snap_daemon') +space = box.schema.create_space('snapshot_daemon') space:create_index('pk', { type = 'tree', parts = { 1, 'num' }}) @@ -70,3 +70,5 @@ box.cfg{snapshot_period = 3600 * 4, snapshot_count = 4 } space:drop() PERIOD + +box.cfg{ snapshot_count = .2 } diff --git a/test/box/sophia.result b/test/box/sophia.result deleted file mode 100644 index 2126bd3e3885dbc3c12b27201503586d0da574fc..0000000000000000000000000000000000000000 --- a/test/box/sophia.result +++ /dev/null @@ -1,335 +0,0 @@ -os.execute("rm -rf sophia") ---- -- 0 -... -space = box.schema.create_space('tweedledum', { id = 123, engine = 'sophia' }) ---- -... -space:create_index('primary', { type = 'tree', parts = {1, 'num'} }) ---- -... -for v=1, 10 do space:insert({v}) end ---- -... -t = space.index[0]:select({}, {iterator = box.index.ALL}) ---- -... -t ---- -- - [1] - - [2] - - [3] - - [4] - - [5] - - [6] - - [7] - - [8] - - [9] - - [10] -... -t = space.index[0]:select({}, {iterator = box.index.GE}) ---- -... -t ---- -- - [1] - - [2] - - [3] - - [4] - - [5] - - [6] - - [7] - - [8] - - [9] - - [10] -... -t = space.index[0]:select(4, {iterator = box.index.GE}) ---- -... -t ---- -- - [4] - - [5] - - [6] - - [7] - - [8] - - [9] - - [10] -... -t = space.index[0]:select({}, {iterator = box.index.LE}) ---- -... -t ---- -- - [10] - - [9] - - [8] - - [7] - - [6] - - [5] - - [4] - - [3] - - [2] - - [1] -... -t = space.index[0]:select(7, {iterator = box.index.LE}) ---- -... -t ---- -- - [7] - - [6] - - [5] - - [4] - - [3] - - [2] - - [1] -... -t = {} ---- -... -for v=1, 10 do table.insert(t, space:get({v})) end ---- -... -t ---- -- - [1] - - [2] - - [3] - - [4] - - [5] - - [6] - - [7] - - [8] - - [9] - - [10] -... -space:drop() ---- -... -box.snapshot() ---- -- ok -... --- --- gh-283: Sophia: hang after three creates and drops --- -s = box.schema.create_space('space0', {id = 33, engine='sophia'}) ---- -... -i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}}) ---- -... -s:insert{'a', 'b', 'c'} ---- -- ['a', 'b', 'c'] -... -s:drop() ---- -... -s = box.schema.create_space('space0', {id = 33, engine='sophia'}) ---- -... -i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}}) ---- -... -s:insert{'a', 'b', 'c'} ---- -- ['a', 'b', 'c'] -... -t = s.index[0]:select({}, {iterator = box.index.ALL}) ---- -... -t ---- -- - ['a', 'b', 'c'] -... -s:drop() ---- -... -s = box.schema.create_space('space0', {id = 33, engine='sophia'}) ---- -... -i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}}) ---- -... -s:insert{'a', 'b', 'c'} ---- -- ['a', 'b', 'c'] -... -t = s.index[0]:select({}, {iterator = box.index.ALL}) ---- -... -t ---- -- - ['a', 'b', 'c'] -... -s:drop() ---- -... --- --- gh-280: Sophia: crash if insert without index --- -s = box.schema.create_space('test', {engine='sophia'}) ---- -... -s:insert{'a'} ---- -- error: 'No index #0 is defined in space ''test''' -... -s:drop() ---- -... ---- ---- gh-431: Sophia: assertion if box.begin ---- -box.cfg{} ---- -... -s = box.schema.create_space('tester',{engine='sophia'}) ---- -... -s:create_index('sophia_index', {}) ---- -... -s:insert{10000, 'Hilton'} ---- -- [10000, 'Hilton'] -... -box.begin() ---- -... -s:delete{10000} -- exception ---- -- error: sophia does not support transactions -... -box.rollback() ---- -... -s:select{10000} ---- -- - [10000, 'Hilton'] -... -s:drop() ---- -... ---- ---- gh-456: Sophia: index size() is unsupported ---- -box.cfg{} ---- -... -s = box.schema.create_space('tester',{engine='sophia'}) ---- -... -s:create_index('sophia_index', {}) ---- -... -s.index[0]:len() -- exception ---- -- error: SophiaIndex does not support size operation -... -box.error() ---- -- error: SophiaIndex does not support size operation -... -s:drop() ---- -... ---- ---- gh-436: No error when creating temporary sophia space ---- -box.cfg{} ---- -... -s = box.schema.create_space('tester',{engine='sophia', temporary=true}) ---- -- error: 'Can''t modify space 512: space does not support temporary flag' -... ---- ---- gh-432: Sophia: ignored limit ---- -s = box.schema.create_space('tester',{id = 89, engine='sophia'}) ---- -... -s:create_index('sophia_index', {}) ---- -... -for v=1, 100 do s:insert({v}) end ---- -... -t = s:select({''},{iterator='GT', limit =1}) ---- -- error: 'Supplied key type of part 0 does not match index part type: expected NUM' -... -t ---- -- - ['a', 'b', 'c'] -... -t = s:select({},{iterator='GT', limit =1}) ---- -... -t ---- -- - [1] -... -s:drop() ---- -... -s = box.schema.create_space('tester', {id = 90, engine='sophia'}) ---- -... -s:create_index('sophia_index', {type = 'tree', parts = {1, 'STR'}}) ---- -... -for v=1, 100 do s:insert({tostring(v)}) end ---- -... -t = s:select({''},{iterator='GT', limit =1}) ---- -... -t ---- -- - ['1'] -... -t = s:select({},{iterator='GT', limit =1}) ---- -... -t ---- -- - ['1'] -... -s:drop() ---- -... ---- ---- gh-282: Sophia: truncate() does nothing ---- -s = box.schema.create_space('name_of_space', {id = 33, engine='sophia'}) ---- -... -i = s:create_index('name_of_index', {type = 'tree', parts = {1, 'STR'}}) ---- -... -s:insert{'a', 'b', 'c'} ---- -- ['a', 'b', 'c'] -... -box.space['name_of_space']:select{'a'} ---- -- - ['a', 'b', 'c'] -... -box.space['name_of_space']:truncate() ---- -... -box.space['name_of_space']:select{'a'} ---- -- [] -... -s:drop() ---- -... -os.execute("rm -rf sophia") ---- -- 0 -... diff --git a/test/box/stat.result b/test/box/stat.result index ad1ea78af49b1ab993cefa331cfa834eb59e5d12..9a7d80f3ec8bc3c7ca54e63c41ba464e648c2433 100644 --- a/test/box/stat.result +++ b/test/box/stat.result @@ -50,7 +50,7 @@ box.stat.REPLACE.total ... box.stat.SELECT.total --- -- 2 +- 3 ... --# stop server default --# start server default diff --git a/test/box/tuple.result b/test/box/tuple.result index 53077ca336610fd08a89dcab5ff3e9bc09cc2611..3cf34faca9948f9068f1f645e04423bc4fd7596b 100644 --- a/test/box/tuple.result +++ b/test/box/tuple.result @@ -377,15 +377,15 @@ t:next(3) ... t:next(4) --- -- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next''' ... t:next(-1) --- -- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next''' ... t:next("fdsaf") --- -- error: '[string "-- tuple.lua (internal file)..."]:52: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next''' ... box.tuple.new({'x', 'y', 'z'}):next() --- @@ -397,7 +397,7 @@ t=space:insert{1953719668} ... t:next(1684234849) --- -- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next''' ... t:next(1) --- @@ -553,7 +553,7 @@ r = {} ... for _state, val in t:pairs(10) do table.insert(r, val) end --- -- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next''' ... r --- @@ -639,19 +639,19 @@ t:findall(1, 'xxxxx') ... t:find(100, 'a') --- -- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next''' ... t:findall(100, 'a') --- -- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next''' ... t:find(100, 'xxxxx') --- -- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next''' ... t:findall(100, 'xxxxx') --- -- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next''' ... --- -- Lua type coercion @@ -737,6 +737,42 @@ t:findall(-9223372036854775807LL) - - 11 ... -------------------------------------------------------------------------------- +-- test tuple:update +-------------------------------------------------------------------------------- +-- see box/update.test.lua for more test cases +t = box.tuple.new({'a', 'b', 'c', 'd', 'e'}) +--- +... +t:update() +--- +- error: '[string "-- tuple.lua (internal file)..."]:152: Usage: tuple:update({ { + op, field, arg}+ })' +... +t:update(10) +--- +- error: '[string "-- tuple.lua (internal file)..."]:152: Usage: tuple:update({ { + op, field, arg}+ })' +... +t:update({}) +--- +- error: Illegal parameters, no operations for update +... +t:update({{ '!', -1, 'f'}}) +--- +- ['a', 'b', 'c', 'd', 'e', 'f'] +... +t:update({{ '#', 4, 1}}) +--- +- ['a', 'b', 'c', 'e'] +... +t +--- +- ['a', 'b', 'c', 'd', 'e'] +... +t = nil +--- +... +-------------------------------------------------------------------------------- -- test msgpack.encode + tuple -------------------------------------------------------------------------------- msgpack = require('msgpack') diff --git a/test/box/tuple.test.lua b/test/box/tuple.test.lua index 78a70b4c5bc60e376a12a8f45a253a18db958310..cb8f126f3d96ffd141119d63a28a4cac81b72d6f 100644 --- a/test/box/tuple.test.lua +++ b/test/box/tuple.test.lua @@ -230,6 +230,22 @@ t:findall(9223372036854775807ULL) t:find(-9223372036854775807LL) t:findall(-9223372036854775807LL) +-------------------------------------------------------------------------------- +-- test tuple:update +-------------------------------------------------------------------------------- + +-- see box/update.test.lua for more test cases + +t = box.tuple.new({'a', 'b', 'c', 'd', 'e'}) +t:update() +t:update(10) +t:update({}) +t:update({{ '!', -1, 'f'}}) +t:update({{ '#', 4, 1}}) + +t +t = nil + -------------------------------------------------------------------------------- -- test msgpack.encode + tuple -------------------------------------------------------------------------------- diff --git a/test/lib/admin_connection.py b/test/lib/admin_connection.py index 14d2e908027773a4cc29607a5fb9077a097bbeb5..5841a12e2a2742630101a5bb8b15e2e24f0d21c5 100644 --- a/test/lib/admin_connection.py +++ b/test/lib/admin_connection.py @@ -56,3 +56,9 @@ class AdminConnection(TarantoolConnection): if not silent: sys.stdout.write(res.replace("\r\n", "\n")) return res + + def connect(self): + super(AdminConnection, self).connect() + handshake = self.socket.recv(128) + if not re.search(r'^Tarantool.*console.*', str(handshake)): + raise RuntimeError('Broken tarantool console handshake') diff --git a/test/lib/preprocessor.py b/test/lib/preprocessor.py index 8f536568d0ea86a77069ac872f2a369539dbf712..f5f63678679fd15f8f0aaf3d9d257cce2b2960ff 100644 --- a/test/lib/preprocessor.py +++ b/test/lib/preprocessor.py @@ -30,8 +30,8 @@ class TestState(object): # curcon is an array since we may have many connections self.curcon = [self.connections['default']] nmsp = Namespace() - setattr(nmsp, 'admin', default_server.admin.port) - setattr(nmsp, 'listen', default_server.sql.port) + setattr(nmsp, 'admin', default_server.admin.uri) + setattr(nmsp, 'listen', default_server.sql.uri) setattr(self.environ, 'default', nmsp) def parse_preprocessor(self, string): diff --git a/test/lib/server.py b/test/lib/server.py index d7f8420abf5cce5f8a899a0e30abcb1086a64467..5aed7f27a4f043480c1dacd8d5794908b699efb7 100644 --- a/test/lib/server.py +++ b/test/lib/server.py @@ -15,8 +15,7 @@ import ConfigParser def check_port(port): """Check if the port we're connecting to is available""" try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.connect(("localhost", port)) + sock = socket.create_connection(("localhost", port)) except socket.error as e: return raise RuntimeError("The server is already running on port {0}".format(port)) diff --git a/test/lib/sql_ast.py b/test/lib/sql_ast.py index 3b0741745ef0322407fda3bda7c365f811ea66a9..f49a42ac6f8bb2ada158b1dcabb4cbfe01bcff38 100644 --- a/test/lib/sql_ast.py +++ b/test/lib/sql_ast.py @@ -25,7 +25,7 @@ ER = { 4: "ER_TUPLE_NOT_FOUND" , 5: "ER_UNSUPPORTED" , 6: "ER_NONMASTER" , - 7: "ER_SECONDARY" , + 7: "ER_READONLY" , 8: "ER_INJECTION" , 9: "ER_CREATE_SPACE" , 10: "ER_SPACE_EXISTS" , diff --git a/test/lib/tarantool-python b/test/lib/tarantool-python index df94b88d87c249e41cdf45dd74b13a2949be24f0..b2bcd37691d3f4664bd34646078b02709fa102cd 160000 --- a/test/lib/tarantool-python +++ b/test/lib/tarantool-python @@ -1 +1 @@ -Subproject commit df94b88d87c249e41cdf45dd74b13a2949be24f0 +Subproject commit b2bcd37691d3f4664bd34646078b02709fa102cd diff --git a/test/lib/tarantool_connection.py b/test/lib/tarantool_connection.py index 873c1db09d874eb602abd2b82a73dbbc6e906b0e..5278809c10e72512cfb41ea95eb753da4633bbe6 100644 --- a/test/lib/tarantool_connection.py +++ b/test/lib/tarantool_connection.py @@ -27,6 +27,14 @@ import errno import re class TarantoolConnection(object): + + @property + def uri(self): + if self.host == 'unix/' or re.search(r'^/', str(self.port)): + return self.port + else: + return self.host+':'+str(self.port) + def __init__(self, host, port): self.host = host self.port = port @@ -37,9 +45,8 @@ class TarantoolConnection(object): self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.socket.connect(self.port) else: - self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.socket = socket.create_connection((self.host, self.port)) self.socket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) - self.socket.connect((self.host, self.port)) self.is_connected = True def disconnect(self): diff --git a/test/lib/tarantool_server.py b/test/lib/tarantool_server.py index 332d37cbfd996000cb9c4c950c361d366d5ffe17..114f505fbaff71e0aa8b38c274c9c803fa4e4b26 100644 --- a/test/lib/tarantool_server.py +++ b/test/lib/tarantool_server.py @@ -36,8 +36,7 @@ color_stdout = Colorer() def check_port(port, rais=True): try: if isinstance(port, (int, long)): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.connect(("localhost", port)) + sock = socket.create_connection(("localhost", port)) else: sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.connect(port) @@ -464,10 +463,10 @@ class TarantoolServer(Server): check_port(self.admin.port) - os.putenv("LISTEN", str(self.sql.port)) - os.putenv("ADMIN", str(self.admin.port)) + os.putenv("LISTEN", self.sql.uri) + os.putenv("ADMIN", self.admin.uri) if self.rpl_master: - os.putenv("MASTER", "127.0.0.1:"+str(self.rpl_master.sql.port)) + os.putenv("MASTER", self.rpl_master.sql.uri) args = self.prepare_args() self.logfile_pos = self.logfile self.process = subprocess.Popen(args, diff --git a/test/replication/cluster.result b/test/replication/cluster.result new file mode 100644 index 0000000000000000000000000000000000000000..efd3543df86a852b77e870b0f8e630b23e4610df --- /dev/null +++ b/test/replication/cluster.result @@ -0,0 +1,36 @@ +box.space._cluster:replace{1, '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae'} +--- +- [1, '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae'] +... +box.info.server.uuid +--- +- 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae +... +check log line for 'server uuid changed to 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae' + +'server uuid changed to 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae' exists in server log + +box.info.server.uuid +--- +- 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae +... +box.snapshot() +--- +- ok +... +box.info.server.uuid +--- +- 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae +... +box.space._cluster:delete(1) +--- +- error: Can't reset server id +... +box.space._cluster:update(1, {{'=', 1, 10}}) +--- +- error: Can't reset server id +... +box.space._cluster:replace{1, require('uuid').NULL:str()} +--- +- error: 'Invalid UUID: 00000000-0000-0000-0000-000000000000' +... diff --git a/test/replication/cluster.test.py b/test/replication/cluster.test.py new file mode 100644 index 0000000000000000000000000000000000000000..b909a00082b2c665a038f96b30b6f7ccf375214a --- /dev/null +++ b/test/replication/cluster.test.py @@ -0,0 +1,48 @@ +import re +import yaml + +# +# gh-434: Assertion if replace _cluster tuple +# + +new_uuid = '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae' + +# Requires panic_on_wal_error = false +server.admin("box.space._cluster:replace{{1, '{}'}}".format(new_uuid)) +server.admin("box.info.server.uuid") + +# Check log message +server.stop() +f = open(server.logfile, "r") +f.seek(0, 2) +server.start() + +check="server uuid changed to " + new_uuid +print "check log line for '%s'" % check +print +line = f.readline() +while line: + if re.search(r'(%s)' % check, line): + print "'%s' exists in server log" % check + break + line = f.readline() +print +f.close() +server.admin("box.info.server.uuid") + +# Check that new UUID has been saved in snapshot +server.admin("box.snapshot()") +server.restart() + +server.admin("box.info.server.uuid") + +# Can't reset server id +server.admin("box.space._cluster:delete(1)") +server.admin("box.space._cluster:update(1, {{'=', 1, 10}})") + +# Invalid UUID +server.admin("box.space._cluster:replace{1, require('uuid').NULL:str()}") + +# Cleanup +server.stop() +server.deploy() diff --git a/test/replication/hot_standby.result b/test/replication/hot_standby.result index 65676c970e8ca4bc47d827bf854fb6ac33a1e5fb..d2b066d47a98c1c6fc952afcf7743f088c45fd28 100644 --- a/test/replication/hot_standby.result +++ b/test/replication/hot_standby.result @@ -12,7 +12,7 @@ box.schema.user.grant('guest', 'read,write,execute', 'universe') fiber = require('fiber'); --- ... -while box.info.server == nil do fiber.sleep(0.01) end; +while box.info.server.id == 0 do fiber.sleep(0.01) end; --- ... while box.space['_priv']:len() < 1 do fiber.sleep(0.001) end; @@ -64,7 +64,14 @@ end; --# set connection default -- set begin lsn on master, replica and hot_standby. --# set variable replica_port to 'replica.listen' -a = (require 'net.box'):new('127.0.0.1', replica_port) +REPLICA = require('uri').parse(tostring(replica_port)) +--- +... +REPLICA ~= nil +--- +- true +... +a = (require 'net.box'):new(REPLICA.host, REPLICA.service) --- ... a:call('_set_pri_lsn', box.info.server.id, box.info.server.lsn) @@ -132,7 +139,14 @@ while box.info.status ~= 'running' do fiber.sleep(0.001) end -- hot_standby.listen is garbage, since hot_standby.lua -- uses MASTER environment variable for its listen --# set variable hot_standby_port to 'hot_standby.master' -a = (require 'net.box'):new('127.0.0.1', hot_standby_port) +HOT_STANDBY = require('uri').parse(tostring(hot_standby_port)) +--- +... +HOT_STANDBY ~= nil +--- +- true +... +a = (require 'net.box'):new(HOT_STANDBY.host, HOT_STANDBY.service) --- ... a:call('_set_pri_lsn', box.info.server.id, box.info.server.lsn) diff --git a/test/replication/hot_standby.test.lua b/test/replication/hot_standby.test.lua index e52f915b86fa06c02bfd5b890db023638db34a42..560207fb6b5dd5f2b9495272dc252a75a29a32f8 100644 --- a/test/replication/hot_standby.test.lua +++ b/test/replication/hot_standby.test.lua @@ -9,7 +9,7 @@ box.schema.user.grant('guest', 'read,write,execute', 'universe') --# setopt delimiter ';' --# set connection default, hot_standby, replica fiber = require('fiber'); -while box.info.server == nil do fiber.sleep(0.01) end; +while box.info.server.id == 0 do fiber.sleep(0.01) end; while box.space['_priv']:len() < 1 do fiber.sleep(0.001) end; do local pri_id = '' @@ -56,7 +56,9 @@ end; -- set begin lsn on master, replica and hot_standby. --# set variable replica_port to 'replica.listen' -a = (require 'net.box'):new('127.0.0.1', replica_port) +REPLICA = require('uri').parse(tostring(replica_port)) +REPLICA ~= nil +a = (require 'net.box'):new(REPLICA.host, REPLICA.service) a:call('_set_pri_lsn', box.info.server.id, box.info.server.lsn) a:close() @@ -78,7 +80,9 @@ while box.info.status ~= 'running' do fiber.sleep(0.001) end -- hot_standby.listen is garbage, since hot_standby.lua -- uses MASTER environment variable for its listen --# set variable hot_standby_port to 'hot_standby.master' -a = (require 'net.box'):new('127.0.0.1', hot_standby_port) +HOT_STANDBY = require('uri').parse(tostring(hot_standby_port)) +HOT_STANDBY ~= nil +a = (require 'net.box'):new(HOT_STANDBY.host, HOT_STANDBY.service) a:call('_set_pri_lsn', box.info.server.id, box.info.server.lsn) a:close() diff --git a/test/replication/readonly.result b/test/replication/readonly.result new file mode 100644 index 0000000000000000000000000000000000000000..9a3b22b210fa4119b55ef7fd00086806a7e14693 --- /dev/null +++ b/test/replication/readonly.result @@ -0,0 +1,41 @@ +box.schema.user.grant('guest', 'read,write,execute', 'universe') +--- +... +box.info.server.id +--- +- 2 +... +box.info.server.ro +--- +- false +... +box.info.server.lsn +--- +- 0 +... +------------------------------------------------------------- +replica is read-only until receive self server_id in _cluster +------------------------------------------------------------- +box.cfg{replication_source = ""} +--- +... +box.info.server.id +--- +- 0 +... +box.info.server.ro +--- +- true +... +box.info.server.lsn +--- +- -1 +... +space = box.schema.create_space("ro") +--- +- error: Can't modify data because this server in read-only mode. +... +box.info.vclock[2] +--- +- null +... diff --git a/test/replication/readonly.test.py b/test/replication/readonly.test.py new file mode 100644 index 0000000000000000000000000000000000000000..24789c51a77e804d1b4b369e189a7d2e7bc5251c --- /dev/null +++ b/test/replication/readonly.test.py @@ -0,0 +1,46 @@ +import os +from glob import iglob as glob +from lib.tarantool_server import TarantoolServer + +# master server +master = server +master_id = master.get_param('server')['id'] + +master.admin("box.schema.user.grant('guest', 'read,write,execute', 'universe')") + +replica = TarantoolServer(server.ini) +replica.script = 'replication/replica.lua' +replica.vardir = os.path.join(server.vardir, 'replica') +replica.rpl_master = master +replica.deploy() +replica.wait_lsn(master_id, master.get_lsn(master_id)) +replica_id = replica.get_param('server')['id'] +replica.admin('box.info.server.id') +replica.admin('box.info.server.ro') +replica.admin('box.info.server.lsn') +replica.stop() + +print '-------------------------------------------------------------' +print 'replica is read-only until receive self server_id in _cluster' +print '-------------------------------------------------------------' + +# Remove xlog retrived by SUBSCRIBE +filename = str(0).zfill(20) + ".xlog" +wal = os.path.join(replica.vardir, filename) +os.remove(wal) + +# Start replica without master +server.stop() +replica.start() +replica.admin('box.cfg{replication_source = ""}') + +# Check that replica in read-only mode +replica.admin('box.info.server.id') +replica.admin('box.info.server.ro') +replica.admin('box.info.server.lsn') +replica.admin('space = box.schema.create_space("ro")') +replica.admin('box.info.vclock[%d]' % replica_id) + +replica.stop() +replica.cleanup(True) +server.deploy() diff --git a/test/replication/swap.result b/test/replication/swap.result index 5badc7052d0fff463c4f1fca6ffc8953d3e48e84..7264bc985d053c0fb122f80eeda232b9e9e736eb 100644 --- a/test/replication/swap.result +++ b/test/replication/swap.result @@ -4,7 +4,7 @@ box.schema.user.create('test', { password = 'pass123456'}) box.schema.user.grant('test', 'read,write,execute', 'universe') --- ... -while box.info.server == nil do require('fiber').sleep(0.01) end +while box.info.server.id == 0 do require('fiber').sleep(0.01) end --- ... while box.space['_priv']:len() < 1 do require('fiber').sleep(0.01) end diff --git a/test/replication/swap.test.py b/test/replication/swap.test.py index 49088df3f94ba61fb7a623c70903340463802149..74cd85a7b37e7d7042bb79fc03c6f29b04ba8c02 100644 --- a/test/replication/swap.test.py +++ b/test/replication/swap.test.py @@ -7,7 +7,6 @@ import yaml REPEAT = 20 ID_BEGIN = 0 ID_STEP = 5 -HOST = '127.0.0.1' LOGIN = 'test' PASSWORD = 'pass123456' @@ -24,7 +23,7 @@ master = server master.admin("box.schema.user.create('%s', { password = '%s'})" % (LOGIN, PASSWORD)) master.admin("box.schema.user.grant('%s', 'read,write,execute', 'universe')" % LOGIN) master.sql.py_con.authenticate(LOGIN, PASSWORD) -master.uri = '%s:%s@%s:%s' % (LOGIN, PASSWORD, HOST, master.sql.port) +master.uri = '%s:%s@%s' % (LOGIN, PASSWORD, master.sql.uri) os.putenv('MASTER', master.uri) # replica server @@ -32,8 +31,8 @@ replica = TarantoolServer() replica.script = "replication/replica.lua" replica.vardir = os.path.join(server.vardir, 'replica') replica.deploy() -replica.admin("while box.info.server == nil do require('fiber').sleep(0.01) end") -replica.uri = '%s:%s@%s:%s' % (LOGIN, PASSWORD, HOST, replica.sql.port) +replica.admin("while box.info.server.id == 0 do require('fiber').sleep(0.01) end") +replica.uri = '%s:%s@%s' % (LOGIN, PASSWORD, replica.sql.uri) replica.admin("while box.space['_priv']:len() < 1 do require('fiber').sleep(0.01) end") replica.sql.py_con.authenticate(LOGIN, PASSWORD) @@ -42,7 +41,7 @@ master.admin("s:create_index('primary', {type = 'hash'})") ### gh-343: replica.cc must not add login and password to proc title #status = replica.get_param("status") -#host_port = "%s:%s" % (HOST, master.sql.port) +#host_port = "%s:%s" % master.sql.uri #m = re.search(r'replica/(.*)/.*', status) #if not m or m.group(1) != host_port: # print 'invalid box.info.status', status, 'expected host:port', host_port diff --git a/test/sophia/box.lua b/test/sophia/box.lua new file mode 100644 index 0000000000000000000000000000000000000000..c9e32af1c76f0ff7bc75aa7409cf1f262d39e14a --- /dev/null +++ b/test/sophia/box.lua @@ -0,0 +1,23 @@ +#!/usr/bin/env tarantool +os = require('os') + +box.cfg{ + listen = os.getenv("LISTEN"), + slab_alloc_arena = 0.1, + pid_file = "tarantool.pid", + rows_per_wal = 50, + sophia_dir = "sophia_test" +} + +require('console').listen(os.getenv('ADMIN')) + +function sophia_printdir() + f = io.popen("ls -1 sophia_test") + ls = f:read("*all") + unused = f:close() + return ls +end + +function sophia_rmdir(dir) + os.execute("rm -rf sophia_test") +end diff --git a/test/sophia/crud.result b/test/sophia/crud.result new file mode 100644 index 0000000000000000000000000000000000000000..52822918ea54bc3c82205c05c31912985589da3d --- /dev/null +++ b/test/sophia/crud.result @@ -0,0 +1,1178 @@ +sophia_rmdir() +--- +... +-- insert +space = box.schema.create_space('test', { engine = 'sophia', id = 100 }) +--- +... +space:create_index('primary', { type = 'tree', parts = {1, 'num'} }) +--- +... +for key = 1, 132 do space:insert({key}) end +--- +... +t = {} +--- +... +for key = 1, 132 do table.insert(t, space:get({key})) end +--- +... +t +--- +- - [1] + - [2] + - [3] + - [4] + - [5] + - [6] + - [7] + - [8] + - [9] + - [10] + - [11] + - [12] + - [13] + - [14] + - [15] + - [16] + - [17] + - [18] + - [19] + - [20] + - [21] + - [22] + - [23] + - [24] + - [25] + - [26] + - [27] + - [28] + - [29] + - [30] + - [31] + - [32] + - [33] + - [34] + - [35] + - [36] + - [37] + - [38] + - [39] + - [40] + - [41] + - [42] + - [43] + - [44] + - [45] + - [46] + - [47] + - [48] + - [49] + - [50] + - [51] + - [52] + - [53] + - [54] + - [55] + - [56] + - [57] + - [58] + - [59] + - [60] + - [61] + - [62] + - [63] + - [64] + - [65] + - [66] + - [67] + - [68] + - [69] + - [70] + - [71] + - [72] + - [73] + - [74] + - [75] + - [76] + - [77] + - [78] + - [79] + - [80] + - [81] + - [82] + - [83] + - [84] + - [85] + - [86] + - [87] + - [88] + - [89] + - [90] + - [91] + - [92] + - [93] + - [94] + - [95] + - [96] + - [97] + - [98] + - [99] + - [100] + - [101] + - [102] + - [103] + - [104] + - [105] + - [106] + - [107] + - [108] + - [109] + - [110] + - [111] + - [112] + - [113] + - [114] + - [115] + - [116] + - [117] + - [118] + - [119] + - [120] + - [121] + - [122] + - [123] + - [124] + - [125] + - [126] + - [127] + - [128] + - [129] + - [130] + - [131] + - [132] +... +-- replace/get +for key = 1, 132 do space:replace({key, key}) end +--- +... +t = {} +--- +... +for key = 1, 132 do table.insert(t, space:get({key})) end +--- +... +t +--- +- - [1, 1] + - [2, 2] + - [3, 3] + - [4, 4] + - [5, 5] + - [6, 6] + - [7, 7] + - [8, 8] + - [9, 9] + - [10, 10] + - [11, 11] + - [12, 12] + - [13, 13] + - [14, 14] + - [15, 15] + - [16, 16] + - [17, 17] + - [18, 18] + - [19, 19] + - [20, 20] + - [21, 21] + - [22, 22] + - [23, 23] + - [24, 24] + - [25, 25] + - [26, 26] + - [27, 27] + - [28, 28] + - [29, 29] + - [30, 30] + - [31, 31] + - [32, 32] + - [33, 33] + - [34, 34] + - [35, 35] + - [36, 36] + - [37, 37] + - [38, 38] + - [39, 39] + - [40, 40] + - [41, 41] + - [42, 42] + - [43, 43] + - [44, 44] + - [45, 45] + - [46, 46] + - [47, 47] + - [48, 48] + - [49, 49] + - [50, 50] + - [51, 51] + - [52, 52] + - [53, 53] + - [54, 54] + - [55, 55] + - [56, 56] + - [57, 57] + - [58, 58] + - [59, 59] + - [60, 60] + - [61, 61] + - [62, 62] + - [63, 63] + - [64, 64] + - [65, 65] + - [66, 66] + - [67, 67] + - [68, 68] + - [69, 69] + - [70, 70] + - [71, 71] + - [72, 72] + - [73, 73] + - [74, 74] + - [75, 75] + - [76, 76] + - [77, 77] + - [78, 78] + - [79, 79] + - [80, 80] + - [81, 81] + - [82, 82] + - [83, 83] + - [84, 84] + - [85, 85] + - [86, 86] + - [87, 87] + - [88, 88] + - [89, 89] + - [90, 90] + - [91, 91] + - [92, 92] + - [93, 93] + - [94, 94] + - [95, 95] + - [96, 96] + - [97, 97] + - [98, 98] + - [99, 99] + - [100, 100] + - [101, 101] + - [102, 102] + - [103, 103] + - [104, 104] + - [105, 105] + - [106, 106] + - [107, 107] + - [108, 108] + - [109, 109] + - [110, 110] + - [111, 111] + - [112, 112] + - [113, 113] + - [114, 114] + - [115, 115] + - [116, 116] + - [117, 117] + - [118, 118] + - [119, 119] + - [120, 120] + - [121, 121] + - [122, 122] + - [123, 123] + - [124, 124] + - [125, 125] + - [126, 126] + - [127, 127] + - [128, 128] + - [129, 129] + - [130, 130] + - [131, 131] + - [132, 132] +... +-- update/get +for key = 1, 132 do space:update({key}, {{'+', 2, key}}) end +--- +... +t = {} +--- +... +for key = 1, 132 do table.insert(t, space:get({key})) end +--- +... +t +--- +- - [1, 2] + - [2, 4] + - [3, 6] + - [4, 8] + - [5, 10] + - [6, 12] + - [7, 14] + - [8, 16] + - [9, 18] + - [10, 20] + - [11, 22] + - [12, 24] + - [13, 26] + - [14, 28] + - [15, 30] + - [16, 32] + - [17, 34] + - [18, 36] + - [19, 38] + - [20, 40] + - [21, 42] + - [22, 44] + - [23, 46] + - [24, 48] + - [25, 50] + - [26, 52] + - [27, 54] + - [28, 56] + - [29, 58] + - [30, 60] + - [31, 62] + - [32, 64] + - [33, 66] + - [34, 68] + - [35, 70] + - [36, 72] + - [37, 74] + - [38, 76] + - [39, 78] + - [40, 80] + - [41, 82] + - [42, 84] + - [43, 86] + - [44, 88] + - [45, 90] + - [46, 92] + - [47, 94] + - [48, 96] + - [49, 98] + - [50, 100] + - [51, 102] + - [52, 104] + - [53, 106] + - [54, 108] + - [55, 110] + - [56, 112] + - [57, 114] + - [58, 116] + - [59, 118] + - [60, 120] + - [61, 122] + - [62, 124] + - [63, 126] + - [64, 128] + - [65, 130] + - [66, 132] + - [67, 134] + - [68, 136] + - [69, 138] + - [70, 140] + - [71, 142] + - [72, 144] + - [73, 146] + - [74, 148] + - [75, 150] + - [76, 152] + - [77, 154] + - [78, 156] + - [79, 158] + - [80, 160] + - [81, 162] + - [82, 164] + - [83, 166] + - [84, 168] + - [85, 170] + - [86, 172] + - [87, 174] + - [88, 176] + - [89, 178] + - [90, 180] + - [91, 182] + - [92, 184] + - [93, 186] + - [94, 188] + - [95, 190] + - [96, 192] + - [97, 194] + - [98, 196] + - [99, 198] + - [100, 200] + - [101, 202] + - [102, 204] + - [103, 206] + - [104, 208] + - [105, 210] + - [106, 212] + - [107, 214] + - [108, 216] + - [109, 218] + - [110, 220] + - [111, 222] + - [112, 224] + - [113, 226] + - [114, 228] + - [115, 230] + - [116, 232] + - [117, 234] + - [118, 236] + - [119, 238] + - [120, 240] + - [121, 242] + - [122, 244] + - [123, 246] + - [124, 248] + - [125, 250] + - [126, 252] + - [127, 254] + - [128, 256] + - [129, 258] + - [130, 260] + - [131, 262] + - [132, 264] +... +-- delete/get +for key = 1, 132 do space:delete({key}) end +--- +... +for key = 1, 132 do assert(space:get({key}) == nil) end +--- +... +-- select +for key = 1, 96 do space:insert({key}) end +--- +... +index = space.index[0] +--- +... +index:select({}, {iterator = box.index.ALL}) +--- +- - [1] + - [2] + - [3] + - [4] + - [5] + - [6] + - [7] + - [8] + - [9] + - [10] + - [11] + - [12] + - [13] + - [14] + - [15] + - [16] + - [17] + - [18] + - [19] + - [20] + - [21] + - [22] + - [23] + - [24] + - [25] + - [26] + - [27] + - [28] + - [29] + - [30] + - [31] + - [32] + - [33] + - [34] + - [35] + - [36] + - [37] + - [38] + - [39] + - [40] + - [41] + - [42] + - [43] + - [44] + - [45] + - [46] + - [47] + - [48] + - [49] + - [50] + - [51] + - [52] + - [53] + - [54] + - [55] + - [56] + - [57] + - [58] + - [59] + - [60] + - [61] + - [62] + - [63] + - [64] + - [65] + - [66] + - [67] + - [68] + - [69] + - [70] + - [71] + - [72] + - [73] + - [74] + - [75] + - [76] + - [77] + - [78] + - [79] + - [80] + - [81] + - [82] + - [83] + - [84] + - [85] + - [86] + - [87] + - [88] + - [89] + - [90] + - [91] + - [92] + - [93] + - [94] + - [95] + - [96] +... +index:select({}, {iterator = box.index.GE}) +--- +- - [1] + - [2] + - [3] + - [4] + - [5] + - [6] + - [7] + - [8] + - [9] + - [10] + - [11] + - [12] + - [13] + - [14] + - [15] + - [16] + - [17] + - [18] + - [19] + - [20] + - [21] + - [22] + - [23] + - [24] + - [25] + - [26] + - [27] + - [28] + - [29] + - [30] + - [31] + - [32] + - [33] + - [34] + - [35] + - [36] + - [37] + - [38] + - [39] + - [40] + - [41] + - [42] + - [43] + - [44] + - [45] + - [46] + - [47] + - [48] + - [49] + - [50] + - [51] + - [52] + - [53] + - [54] + - [55] + - [56] + - [57] + - [58] + - [59] + - [60] + - [61] + - [62] + - [63] + - [64] + - [65] + - [66] + - [67] + - [68] + - [69] + - [70] + - [71] + - [72] + - [73] + - [74] + - [75] + - [76] + - [77] + - [78] + - [79] + - [80] + - [81] + - [82] + - [83] + - [84] + - [85] + - [86] + - [87] + - [88] + - [89] + - [90] + - [91] + - [92] + - [93] + - [94] + - [95] + - [96] +... +index:select(4, {iterator = box.index.GE}) +--- +- - [4] + - [5] + - [6] + - [7] + - [8] + - [9] + - [10] + - [11] + - [12] + - [13] + - [14] + - [15] + - [16] + - [17] + - [18] + - [19] + - [20] + - [21] + - [22] + - [23] + - [24] + - [25] + - [26] + - [27] + - [28] + - [29] + - [30] + - [31] + - [32] + - [33] + - [34] + - [35] + - [36] + - [37] + - [38] + - [39] + - [40] + - [41] + - [42] + - [43] + - [44] + - [45] + - [46] + - [47] + - [48] + - [49] + - [50] + - [51] + - [52] + - [53] + - [54] + - [55] + - [56] + - [57] + - [58] + - [59] + - [60] + - [61] + - [62] + - [63] + - [64] + - [65] + - [66] + - [67] + - [68] + - [69] + - [70] + - [71] + - [72] + - [73] + - [74] + - [75] + - [76] + - [77] + - [78] + - [79] + - [80] + - [81] + - [82] + - [83] + - [84] + - [85] + - [86] + - [87] + - [88] + - [89] + - [90] + - [91] + - [92] + - [93] + - [94] + - [95] + - [96] +... +index:select({}, {iterator = box.index.GT}) +--- +- - [1] + - [2] + - [3] + - [4] + - [5] + - [6] + - [7] + - [8] + - [9] + - [10] + - [11] + - [12] + - [13] + - [14] + - [15] + - [16] + - [17] + - [18] + - [19] + - [20] + - [21] + - [22] + - [23] + - [24] + - [25] + - [26] + - [27] + - [28] + - [29] + - [30] + - [31] + - [32] + - [33] + - [34] + - [35] + - [36] + - [37] + - [38] + - [39] + - [40] + - [41] + - [42] + - [43] + - [44] + - [45] + - [46] + - [47] + - [48] + - [49] + - [50] + - [51] + - [52] + - [53] + - [54] + - [55] + - [56] + - [57] + - [58] + - [59] + - [60] + - [61] + - [62] + - [63] + - [64] + - [65] + - [66] + - [67] + - [68] + - [69] + - [70] + - [71] + - [72] + - [73] + - [74] + - [75] + - [76] + - [77] + - [78] + - [79] + - [80] + - [81] + - [82] + - [83] + - [84] + - [85] + - [86] + - [87] + - [88] + - [89] + - [90] + - [91] + - [92] + - [93] + - [94] + - [95] + - [96] +... +index:select(4, {iterator = box.index.GT}) +--- +- - [5] + - [6] + - [7] + - [8] + - [9] + - [10] + - [11] + - [12] + - [13] + - [14] + - [15] + - [16] + - [17] + - [18] + - [19] + - [20] + - [21] + - [22] + - [23] + - [24] + - [25] + - [26] + - [27] + - [28] + - [29] + - [30] + - [31] + - [32] + - [33] + - [34] + - [35] + - [36] + - [37] + - [38] + - [39] + - [40] + - [41] + - [42] + - [43] + - [44] + - [45] + - [46] + - [47] + - [48] + - [49] + - [50] + - [51] + - [52] + - [53] + - [54] + - [55] + - [56] + - [57] + - [58] + - [59] + - [60] + - [61] + - [62] + - [63] + - [64] + - [65] + - [66] + - [67] + - [68] + - [69] + - [70] + - [71] + - [72] + - [73] + - [74] + - [75] + - [76] + - [77] + - [78] + - [79] + - [80] + - [81] + - [82] + - [83] + - [84] + - [85] + - [86] + - [87] + - [88] + - [89] + - [90] + - [91] + - [92] + - [93] + - [94] + - [95] + - [96] +... +index:select({}, {iterator = box.index.LE}) +--- +- - [96] + - [95] + - [94] + - [93] + - [92] + - [91] + - [90] + - [89] + - [88] + - [87] + - [86] + - [85] + - [84] + - [83] + - [82] + - [81] + - [80] + - [79] + - [78] + - [77] + - [76] + - [75] + - [74] + - [73] + - [72] + - [71] + - [70] + - [69] + - [68] + - [67] + - [66] + - [65] + - [64] + - [63] + - [62] + - [61] + - [60] + - [59] + - [58] + - [57] + - [56] + - [55] + - [54] + - [53] + - [52] + - [51] + - [50] + - [49] + - [48] + - [47] + - [46] + - [45] + - [44] + - [43] + - [42] + - [41] + - [40] + - [39] + - [38] + - [37] + - [36] + - [35] + - [34] + - [33] + - [32] + - [31] + - [30] + - [29] + - [28] + - [27] + - [26] + - [25] + - [24] + - [23] + - [22] + - [21] + - [20] + - [19] + - [18] + - [17] + - [16] + - [15] + - [14] + - [13] + - [12] + - [11] + - [10] + - [9] + - [8] + - [7] + - [6] + - [5] + - [4] + - [3] + - [2] + - [1] +... +index:select(7, {iterator = box.index.LE}) +--- +- - [7] + - [6] + - [5] + - [4] + - [3] + - [2] + - [1] +... +index:select({}, {iterator = box.index.LT}) +--- +- - [96] + - [95] + - [94] + - [93] + - [92] + - [91] + - [90] + - [89] + - [88] + - [87] + - [86] + - [85] + - [84] + - [83] + - [82] + - [81] + - [80] + - [79] + - [78] + - [77] + - [76] + - [75] + - [74] + - [73] + - [72] + - [71] + - [70] + - [69] + - [68] + - [67] + - [66] + - [65] + - [64] + - [63] + - [62] + - [61] + - [60] + - [59] + - [58] + - [57] + - [56] + - [55] + - [54] + - [53] + - [52] + - [51] + - [50] + - [49] + - [48] + - [47] + - [46] + - [45] + - [44] + - [43] + - [42] + - [41] + - [40] + - [39] + - [38] + - [37] + - [36] + - [35] + - [34] + - [33] + - [32] + - [31] + - [30] + - [29] + - [28] + - [27] + - [26] + - [25] + - [24] + - [23] + - [22] + - [21] + - [20] + - [19] + - [18] + - [17] + - [16] + - [15] + - [14] + - [13] + - [12] + - [11] + - [10] + - [9] + - [8] + - [7] + - [6] + - [5] + - [4] + - [3] + - [2] + - [1] +... +index:select(7, {iterator = box.index.LT}) +--- +- - [6] + - [5] + - [4] + - [3] + - [2] + - [1] +... +-- random +dofile('index_random_test.lua') +--- +... +index_random_test(space, 'primary') +--- +- true +... +space:drop() +--- +... +-- +sophia_rmdir() +--- +... diff --git a/test/sophia/crud.test.lua b/test/sophia/crud.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..191a58057830fb0de8478d8a21cbcf01e88b9e29 --- /dev/null +++ b/test/sophia/crud.test.lua @@ -0,0 +1,55 @@ + +sophia_rmdir() + +-- insert + +space = box.schema.create_space('test', { engine = 'sophia', id = 100 }) +space:create_index('primary', { type = 'tree', parts = {1, 'num'} }) +for key = 1, 132 do space:insert({key}) end +t = {} +for key = 1, 132 do table.insert(t, space:get({key})) end +t + +-- replace/get + +for key = 1, 132 do space:replace({key, key}) end +t = {} +for key = 1, 132 do table.insert(t, space:get({key})) end +t + +-- update/get + +for key = 1, 132 do space:update({key}, {{'+', 2, key}}) end +t = {} +for key = 1, 132 do table.insert(t, space:get({key})) end +t + +-- delete/get + +for key = 1, 132 do space:delete({key}) end +for key = 1, 132 do assert(space:get({key}) == nil) end + +-- select + +for key = 1, 96 do space:insert({key}) end +index = space.index[0] +index:select({}, {iterator = box.index.ALL}) +index:select({}, {iterator = box.index.GE}) +index:select(4, {iterator = box.index.GE}) +index:select({}, {iterator = box.index.GT}) +index:select(4, {iterator = box.index.GT}) +index:select({}, {iterator = box.index.LE}) +index:select(7, {iterator = box.index.LE}) +index:select({}, {iterator = box.index.LT}) +index:select(7, {iterator = box.index.LT}) + +-- random + +dofile('index_random_test.lua') +index_random_test(space, 'primary') + +space:drop() + +-- + +sophia_rmdir() diff --git a/test/sophia/dml.result b/test/sophia/dml.result new file mode 100644 index 0000000000000000000000000000000000000000..69b0f8746bf5b7d9d09d73126652466522b10167 --- /dev/null +++ b/test/sophia/dml.result @@ -0,0 +1,171 @@ +sophia_rmdir() +--- +... +-- space create/drop +space = box.schema.create_space('test', { id = 100, engine = 'sophia' }) +--- +... +sophia_printdir() +--- +- +... +space:drop() +--- +... +sophia_printdir() +--- +- +... +-- index create/drop +space = box.schema.create_space('test', { id = 101, engine = 'sophia' }) +--- +... +space:create_index('primary') +--- +... +sophia_printdir() +--- +- '101 + +' +... +space:drop() +--- +... +sophia_printdir() +--- +- +... +-- index create/drop alter +space = box.schema.create_space('test', { id = 102, engine = 'sophia' }) +--- +... +space:create_index('primary') +--- +... +sophia_printdir() +--- +- '102 + +' +... +_index = box.space[box.schema.INDEX_ID] +--- +... +_index:delete{102, 0} +--- +- [102, 0, 'primary', 'tree', 1, 1, 0, 'num'] +... +sophia_printdir() +--- +- +... +space:drop() +--- +... +-- index create/drop tree string +space = box.schema.create_space('test', { id = 103, engine = 'sophia' }) +--- +... +space:create_index('primary', {type = 'tree', parts = {1, 'STR'}}) +--- +... +space:insert({'test'}) +--- +- ['test'] +... +sophia_printdir() +--- +- '103 + +' +... +space:drop() +--- +... +-- index create/drop tree num +space = box.schema.create_space('test', { id = 104, engine = 'sophia' }) +--- +... +space:create_index('primary', {type = 'tree', parts = {1, 'num'}}) +--- +... +space:insert({13}) +--- +- [13] +... +sophia_printdir() +--- +- '104 + +' +... +space:drop() +--- +... +-- index create hash +space = box.schema.create_space('test', { id = 105, engine = 'sophia' }) +--- +... +space:create_index('primary', {type = 'hash'}) +--- +- error: Unsupported index type supplied for index 0 in space 105 +... +space:drop() +--- +... +-- secondary index create +space = box.schema.create_space('test', { id = 106, engine = 'sophia' }) +--- +... +space:create_index('primary') +--- +... +space:create_index('secondary') +--- +- error: 'Can''t create or modify index 1 in space 106: Sophia TREE secondary indexes + are not supported' +... +space:drop() +--- +... +sophia_printdir() +--- +- +... +-- index size +space = box.schema.create_space('test', { id = 107, engine = 'sophia' }) +--- +... +space:create_index('primary') +--- +... +primary = space.index[0] +--- +... +primary:len() +--- +- 0 +... +space:insert({13}) +--- +- [13] +... +space:insert({14}) +--- +- [14] +... +space:insert({15}) +--- +- [15] +... +primary:len() +--- +- 3 +... +space:drop() +--- +... +sophia_rmdir() +--- +... diff --git a/test/sophia/dml.test.lua b/test/sophia/dml.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..56ca115287d3c6edca13fda99bc4e70c403e45c4 --- /dev/null +++ b/test/sophia/dml.test.lua @@ -0,0 +1,71 @@ + +sophia_rmdir() + +-- space create/drop + +space = box.schema.create_space('test', { id = 100, engine = 'sophia' }) +sophia_printdir() +space:drop() +sophia_printdir() + +-- index create/drop + +space = box.schema.create_space('test', { id = 101, engine = 'sophia' }) +space:create_index('primary') +sophia_printdir() +space:drop() +sophia_printdir() + +-- index create/drop alter + +space = box.schema.create_space('test', { id = 102, engine = 'sophia' }) +space:create_index('primary') +sophia_printdir() +_index = box.space[box.schema.INDEX_ID] +_index:delete{102, 0} +sophia_printdir() +space:drop() + +-- index create/drop tree string + +space = box.schema.create_space('test', { id = 103, engine = 'sophia' }) +space:create_index('primary', {type = 'tree', parts = {1, 'STR'}}) +space:insert({'test'}) +sophia_printdir() +space:drop() + +-- index create/drop tree num + +space = box.schema.create_space('test', { id = 104, engine = 'sophia' }) +space:create_index('primary', {type = 'tree', parts = {1, 'num'}}) +space:insert({13}) +sophia_printdir() +space:drop() + +-- index create hash + +space = box.schema.create_space('test', { id = 105, engine = 'sophia' }) +space:create_index('primary', {type = 'hash'}) +space:drop() + +-- secondary index create + +space = box.schema.create_space('test', { id = 106, engine = 'sophia' }) +space:create_index('primary') +space:create_index('secondary') +space:drop() +sophia_printdir() + +-- index size + +space = box.schema.create_space('test', { id = 107, engine = 'sophia' }) +space:create_index('primary') +primary = space.index[0] +primary:len() +space:insert({13}) +space:insert({14}) +space:insert({15}) +primary:len() +space:drop() + +sophia_rmdir() diff --git a/test/box/sophia.test.lua b/test/sophia/gh.result similarity index 64% rename from test/box/sophia.test.lua rename to test/sophia/gh.result index d91a685e0711acee86fef224471b92fb8374a0c1..7debe9511955e359d13fe24eb09354eca7aebd68 100644 --- a/test/box/sophia.test.lua +++ b/test/sophia/gh.result @@ -1,127 +1,183 @@ -os.execute("rm -rf sophia") - -space = box.schema.create_space('tweedledum', { id = 123, engine = 'sophia' }) -space:create_index('primary', { type = 'tree', parts = {1, 'num'} }) - -for v=1, 10 do space:insert({v}) end - -t = space.index[0]:select({}, {iterator = box.index.ALL}) -t - -t = space.index[0]:select({}, {iterator = box.index.GE}) -t - -t = space.index[0]:select(4, {iterator = box.index.GE}) -t - -t = space.index[0]:select({}, {iterator = box.index.LE}) -t - -t = space.index[0]:select(7, {iterator = box.index.LE}) -t - -t = {} -for v=1, 10 do table.insert(t, space:get({v})) end -t - -space:drop() -box.snapshot() - --- +sophia_rmdir() +--- +... -- gh-283: Sophia: hang after three creates and drops --- - s = box.schema.create_space('space0', {id = 33, engine='sophia'}) +--- +... i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}}) +--- +... s:insert{'a', 'b', 'c'} +--- +- ['a', 'b', 'c'] +... s:drop() - +--- +... s = box.schema.create_space('space0', {id = 33, engine='sophia'}) +--- +... i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}}) +--- +... s:insert{'a', 'b', 'c'} +--- +- ['a', 'b', 'c'] +... t = s.index[0]:select({}, {iterator = box.index.ALL}) +--- +... t +--- +- - ['a', 'b', 'c'] +... s:drop() - +--- +... s = box.schema.create_space('space0', {id = 33, engine='sophia'}) +--- +... i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}}) +--- +... s:insert{'a', 'b', 'c'} +--- +- ['a', 'b', 'c'] +... t = s.index[0]:select({}, {iterator = box.index.ALL}) +--- +... t +--- +- - ['a', 'b', 'c'] +... s:drop() - --- +--- +... -- gh-280: Sophia: crash if insert without index --- - s = box.schema.create_space('test', {engine='sophia'}) +--- +... s:insert{'a'} -s:drop() - --- ---- gh-431: Sophia: assertion if box.begin +- error: 'No index #0 is defined in space ''test''' +... +s:drop() --- - -box.cfg{} +... +-- gh-431: Sophia: assertion if box.begin s = box.schema.create_space('tester',{engine='sophia'}) +--- +... s:create_index('sophia_index', {}) +--- +... s:insert{10000, 'Hilton'} +--- +- [10000, 'Hilton'] +... box.begin() +--- +... s:delete{10000} -- exception +--- +- error: sophia does not support transactions +... box.rollback() -s:select{10000} -s:drop() - --- ---- gh-456: Sophia: index size() is unsupported +... +s:select{10000} --- - -box.cfg{} -s = box.schema.create_space('tester',{engine='sophia'}) -s:create_index('sophia_index', {}) -s.index[0]:len() -- exception -box.error() +- - [10000, 'Hilton'] +... s:drop() - ---- ---- gh-436: No error when creating temporary sophia space --- - -box.cfg{} +... +-- gh-436: No error when creating temporary sophia space s = box.schema.create_space('tester',{engine='sophia', temporary=true}) - --- ---- gh-432: Sophia: ignored limit ---- - +- error: 'Can''t modify space 512: space does not support temporary flag' +... +-- gh-432: Sophia: ignored limit s = box.schema.create_space('tester',{id = 89, engine='sophia'}) +--- +... s:create_index('sophia_index', {}) +--- +... for v=1, 100 do s:insert({v}) end +--- +... t = s:select({''},{iterator='GT', limit =1}) +--- +- error: 'Supplied key type of part 0 does not match index part type: expected NUM' +... t +--- +- - ['a', 'b', 'c'] +... t = s:select({},{iterator='GT', limit =1}) +--- +... t +--- +- - [1] +... s:drop() - +--- +... s = box.schema.create_space('tester', {id = 90, engine='sophia'}) +--- +... s:create_index('sophia_index', {type = 'tree', parts = {1, 'STR'}}) +--- +... for v=1, 100 do s:insert({tostring(v)}) end +--- +... t = s:select({''},{iterator='GT', limit =1}) +--- +... t +--- +- - ['1'] +... t = s:select({},{iterator='GT', limit =1}) +--- +... t -s:drop() - --- ---- gh-282: Sophia: truncate() does nothing +- - ['1'] +... +s:drop() --- - +... +-- gh-282: Sophia: truncate() does nothing s = box.schema.create_space('name_of_space', {id = 33, engine='sophia'}) +--- +... i = s:create_index('name_of_index', {type = 'tree', parts = {1, 'STR'}}) +--- +... s:insert{'a', 'b', 'c'} +--- +- ['a', 'b', 'c'] +... box.space['name_of_space']:select{'a'} +--- +- - ['a', 'b', 'c'] +... box.space['name_of_space']:truncate() +--- +... box.space['name_of_space']:select{'a'} +--- +- [] +... s:drop() - -os.execute("rm -rf sophia") +--- +... +sophia_rmdir() +--- +... diff --git a/test/sophia/gh.test.lua b/test/sophia/gh.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..790863b4d17aee01ae13a365d1f4ff4f0924de0f --- /dev/null +++ b/test/sophia/gh.test.lua @@ -0,0 +1,76 @@ + +sophia_rmdir() + +-- gh-283: Sophia: hang after three creates and drops + +s = box.schema.create_space('space0', {id = 33, engine='sophia'}) +i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}}) +s:insert{'a', 'b', 'c'} +s:drop() + +s = box.schema.create_space('space0', {id = 33, engine='sophia'}) +i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}}) +s:insert{'a', 'b', 'c'} +t = s.index[0]:select({}, {iterator = box.index.ALL}) +t +s:drop() + +s = box.schema.create_space('space0', {id = 33, engine='sophia'}) +i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}}) +s:insert{'a', 'b', 'c'} +t = s.index[0]:select({}, {iterator = box.index.ALL}) +t +s:drop() + +-- gh-280: Sophia: crash if insert without index + +s = box.schema.create_space('test', {engine='sophia'}) +s:insert{'a'} +s:drop() + +-- gh-431: Sophia: assertion if box.begin + +s = box.schema.create_space('tester',{engine='sophia'}) +s:create_index('sophia_index', {}) +s:insert{10000, 'Hilton'} +box.begin() +s:delete{10000} -- exception +box.rollback() +s:select{10000} +s:drop() + +-- gh-436: No error when creating temporary sophia space + +s = box.schema.create_space('tester',{engine='sophia', temporary=true}) + +-- gh-432: Sophia: ignored limit + +s = box.schema.create_space('tester',{id = 89, engine='sophia'}) +s:create_index('sophia_index', {}) +for v=1, 100 do s:insert({v}) end +t = s:select({''},{iterator='GT', limit =1}) +t +t = s:select({},{iterator='GT', limit =1}) +t +s:drop() + +s = box.schema.create_space('tester', {id = 90, engine='sophia'}) +s:create_index('sophia_index', {type = 'tree', parts = {1, 'STR'}}) +for v=1, 100 do s:insert({tostring(v)}) end +t = s:select({''},{iterator='GT', limit =1}) +t +t = s:select({},{iterator='GT', limit =1}) +t +s:drop() + +-- gh-282: Sophia: truncate() does nothing + +s = box.schema.create_space('name_of_space', {id = 33, engine='sophia'}) +i = s:create_index('name_of_index', {type = 'tree', parts = {1, 'STR'}}) +s:insert{'a', 'b', 'c'} +box.space['name_of_space']:select{'a'} +box.space['name_of_space']:truncate() +box.space['name_of_space']:select{'a'} +s:drop() + +sophia_rmdir() diff --git a/test/sophia/index_random_test.lua b/test/sophia/index_random_test.lua new file mode 100644 index 0000000000000000000000000000000000000000..00838e83e1d78527af6fbb6041899831fdcc368b --- /dev/null +++ b/test/sophia/index_random_test.lua @@ -0,0 +1,33 @@ + +function index_random_test(space, index_no) + local COUNT = 1028 + -- clear the space + space:truncate() + -- randomize + math.randomseed(os.time()) + -- insert values into the index + for k=1,COUNT,1 do space:insert{k} end + local rnd_start = math.random(4294967296) + -- try to get all values from the index using index.random + local tuples = {} + local found = 0 + while found < COUNT do + local rnd = math.random(4294967296) + if rnd == rnd_start then + error('too many iterations') + return nil + end + local tuple = space.index[index_no]:random(rnd) + if tuple == nil then + error('nil returned') + return nil + end + local k = tuple[1] + if tuples[k] == nil then + found = found + 1 + end + tuples[k] = 1 + end + + return true +end diff --git a/test/sophia/recover.result b/test/sophia/recover.result new file mode 100644 index 0000000000000000000000000000000000000000..4903baa4388743108b9dc90789309e54c050a27b --- /dev/null +++ b/test/sophia/recover.result @@ -0,0 +1,30 @@ +sophia_rmdir() +--- +... +-- snapshot +space = box.schema.create_space('test', { id = 100, engine = 'sophia' }) +--- +... +space:create_index('primary') +--- +... +sophia_printdir() +--- +- '100 + +' +... +box.snapshot() +--- +- ok +... +space:drop() +--- +... +box.snapshot() +--- +- ok +... +sophia_rmdir() +--- +... diff --git a/test/sophia/recover.test.lua b/test/sophia/recover.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..ffea2d43ca920888f7cbd065477306ab3d28ab6e --- /dev/null +++ b/test/sophia/recover.test.lua @@ -0,0 +1,13 @@ + +sophia_rmdir() + +-- snapshot + +space = box.schema.create_space('test', { id = 100, engine = 'sophia' }) +space:create_index('primary') +sophia_printdir() +box.snapshot() +space:drop() +box.snapshot() + +sophia_rmdir() diff --git a/test/sophia/suite.ini b/test/sophia/suite.ini new file mode 100644 index 0000000000000000000000000000000000000000..ddf62d5dadc3cadb5233e84cb7d7eed7348221ba --- /dev/null +++ b/test/sophia/suite.ini @@ -0,0 +1,9 @@ +[default] +core = tarantool +description = sophia integration tests +script = box.lua +disabled = +valgrind_disabled = +release_disabled = +lua_libs = index_random_test.lua +use_unix_sockets = True diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index dc1ae0a7765590755fa51deae03b855f99289f04..32306d8db765db812ed0f6190d3d4700bd21a375 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -7,7 +7,7 @@ include_directories(${PROJECT_BINARY_DIR}/src) include_directories(${PROJECT_SOURCE_DIR}/src/lib) include_directories(${CMAKE_SOURCE_DIR}/third_party) add_executable(rlist.test rlist.c test.c ${CMAKE_SOURCE_DIR}/src/lib/salad/rlist.c) -add_executable(uri.test uri.cc test.c ${CMAKE_SOURCE_DIR}/src/uri.cc) +add_executable(uri.test uri.c test.c ${CMAKE_SOURCE_DIR}/src/uri.c) add_executable(fiob.test test.c fiob.c ${CMAKE_SOURCE_DIR}/src/fiob.c) add_executable(queue.test queue.c) add_executable(mhash.test mhash.c) diff --git a/test/unit/fiob.skipcond b/test/unit/fiob.skipcond new file mode 100644 index 0000000000000000000000000000000000000000..d246d3b7c4bf083f7654bd631877fc1579adaedf --- /dev/null +++ b/test/unit/fiob.skipcond @@ -0,0 +1,17 @@ +# vim: set ft=python : +import re +import os +import os.path +import tempfile + +dir = tempfile.mkdtemp() +file = os.path.join(dir, 'test-o-direct') + +try: + fh = os.open(file, os.O_CREAT | os.O_DIRECT | os.O_TRUNC | os.O_RDWR) + os.unlink(file) + os.rmdir(dir) +except: + self.skip = 1 + + diff --git a/test/unit/uri.c b/test/unit/uri.c new file mode 100644 index 0000000000000000000000000000000000000000..b978a12233d7fb5dd181878f468160aec878dd49 --- /dev/null +++ b/test/unit/uri.c @@ -0,0 +1,222 @@ +#include "test.h" +#include <uri.h> +#include <string.h> + +int +test(const char *s, const char *scheme, const char *login, const char *password, + const char *host, const char *service, const char *path, + const char *query, const char *fragment, int host_hint) +{ + plan(10); + + struct uri uri; + is(uri_parse(&uri, s), 0, "%s: parse", s); + /* fprintf(stdout, #key ": %p %d %.*s\n", uri.key, + (int) uri.key ## _len, (int) uri.key ## _len, uri.key); */ + +#define chk(key) do { \ + ok((key && uri.key && strlen(key) == uri.key ## _len && \ + memcmp(key, uri.key, uri.key ## _len) == 0) || \ + (!key && !uri.key), "%s: " #key, s); } while (0); + + chk(scheme); + chk(login); + chk(password); + chk(host); + chk(service); + chk(path); + chk(query); + chk(fragment); + is(uri.host_hint, host_hint, "%s: host_hint", s); + +#undef chk + return check_plan(); +} + +int +test_invalid() +{ + plan(2); + + /* Invalid */ + struct uri u; + isnt(uri_parse(&u, ""), 0 , "empty is invalid"); + isnt(uri_parse(&u, "://"), 0 , ":// is invalid"); + + return check_plan(); +} + +int +main(void) +{ + plan(60); + + /* General */ + test("host", NULL, NULL, NULL, "host", NULL, NULL, NULL, NULL, 0); + test("host/", NULL, NULL, NULL, "host", NULL, "/", NULL, NULL, 0); + test("host/path1/path2/path3", NULL, NULL, NULL, "host", NULL, + "/path1/path2/path3", NULL, NULL, 0); + test("host/path1/path2/path3?q1=v1&q2=v2#fragment", NULL, NULL, + NULL, "host", NULL, "/path1/path2/path3", + "q1=v1&q2=v2", "fragment", 0); + + test("host:service", NULL, NULL, NULL, "host", "service", NULL, NULL, + NULL, 0); + + test("host:service/", NULL, NULL, NULL, "host", "service", "/", NULL, + NULL, 0); + + test("host:service/path1/path2/path3", NULL, NULL, NULL, "host", + "service", "/path1/path2/path3", NULL, NULL, 0); + test("host:service/path1/path2/path3?q1=v1&q2=v2#fragment", NULL, NULL, + NULL, "host", "service", "/path1/path2/path3", + "q1=v1&q2=v2", "fragment", 0); + + test("login@host", NULL, "login", NULL, "host", NULL, NULL, NULL, + NULL, 0); + test("login@host/", NULL, "login", NULL, "host", NULL, "/", NULL, + NULL, 0); + test("login@host/path1/path2/path3", NULL, "login", NULL, "host", NULL, + "/path1/path2/path3", NULL, NULL, 0); + test("login@host/path1/path2/path3?q1=v1&q2=v2#fragment", NULL, "login", + NULL, "host", NULL, "/path1/path2/path3", + "q1=v1&q2=v2", "fragment", 0); + + test("login:password@host", NULL, "login", "password", "host", NULL, + NULL, NULL, NULL, 0); + test("login:password@host/", NULL, "login", "password", "host", NULL, + "/", NULL, NULL, 0); + test("login:password@host/path1/path2/path3", NULL, "login", "password", + "host", NULL, "/path1/path2/path3", NULL, NULL, 0); + test("login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment", + NULL, "login", "password", "host", NULL, "/path1/path2/path3", + "q1=v1&q2=v2", "fragment", 0); + + test("login:password@host:service", NULL, "login", "password", "host", + "service", NULL, NULL, NULL, 0); + test("login:password@host:service/", NULL, "login", "password", "host", + "service", "/", NULL, NULL, 0); + test("login:password@host:service/path1/path2/path3", NULL, "login", + "password", "host", "service", "/path1/path2/path3", NULL, + NULL, 0); + test("login:password@host:service/path1/path2/path3?q1=v1&q2=v2" + "#fragment", NULL, "login", "password", "host", "service", + "/path1/path2/path3", "q1=v1&q2=v2", "fragment", 0); + + test("scheme://login:password@host:service", "scheme", "login", + "password", "host", "service", NULL, NULL, NULL, 0); + test("scheme://login:password@host:service/", "scheme", "login", + "password", "host", "service", "/", NULL, NULL, 0); + test("scheme://login:password@host:service/path1/path2/path3", "scheme", + "login", "password", "host", "service", "/path1/path2/path3", + NULL, NULL, 0); + test("scheme://login:password@host:service/path1/path2/path3?" + "q1=v1&q2=v2#fragment", "scheme", "login", "password", "host", + "service", "/path1/path2/path3", "q1=v1&q2=v2", "fragment", 0); + + test("host/path", NULL, NULL, NULL, "host", NULL, "/path", NULL, + NULL, 0); + test("host//", NULL, NULL, NULL, "host", NULL, "//", NULL, NULL, 0); + test("host//path", NULL, NULL, NULL, "host", NULL, "//path", NULL, + NULL, 0); + test("host/;abc?q", NULL, NULL, NULL, "host", NULL, "/;abc", "q", + NULL, 0); + + test("scheme://login:password@host:service/@path1/:path2?" + "q1=v1&q2=v2#fragment", "scheme", "login", "password", "host", + "service", "/@path1/:path2", "q1=v1&q2=v2", "fragment", 0); + test("host/~user", NULL, NULL, NULL, "host", NULL, "/~user", NULL, + NULL, 0); + + /* Host */ + test("try.tarantool.org", NULL, NULL, NULL, "try.tarantool.org", NULL, + NULL, NULL, NULL, 0); + + test("try.tarantool.org", NULL, NULL, NULL, "try.tarantool.org", NULL, + NULL, NULL, NULL, 0); + + test("www.llanfairpwllgwyngyllgogerychwyrndrobwyll-" + "llantysiliogogogoch.com", NULL, NULL, NULL, + "www.llanfairpwllgwyngyllgogerychwyrndrobwyll-" + "llantysiliogogogoch.com", NULL, NULL, NULL, NULL, 0); + + /* IPv4 / IPv6 addreses */ + test("0.0.0.0", NULL, NULL, NULL, "0.0.0.0", NULL, NULL, NULL, NULL, 1); + test("127.0.0.1", NULL, NULL, NULL, "127.0.0.1", NULL, NULL, NULL, + NULL, 1); + test("127.0.0.1:3313", NULL, NULL, NULL, "127.0.0.1", "3313", NULL, + NULL, NULL, 1); + + test("scheme://login:password@127.0.0.1:3313", "scheme", "login", + "password", "127.0.0.1", "3313", NULL, NULL, NULL, 1); + + test("[2001::11a3:09d7::1]", NULL, NULL, NULL, "2001::11a3:09d7::1", + NULL, NULL, NULL, NULL, 2); + test("scheme://login:password@[2001::11a3:09d7::1]:3313", "scheme", + "login", "password", "2001::11a3:09d7::1", "3313", NULL, NULL, + NULL, 2); + test("scheme://[2001:0db8:11a3:09d7::1]", "scheme", NULL, NULL, + "2001:0db8:11a3:09d7::1", NULL, NULL, NULL, NULL, 2); + + test("[::ffff:11.2.3.4]", NULL, NULL, NULL, "::ffff:11.2.3.4", + NULL, NULL, NULL, NULL, 2); + test("scheme://login:password@[::ffff:11.2.3.4]:3313", "scheme", + "login", "password", "::ffff:11.2.3.4", "3313", NULL, NULL, + NULL, 2); + + /* Port */ + test("1", NULL, NULL, NULL, NULL, "1", NULL, NULL, NULL, 0); + test("10", NULL, NULL, NULL, NULL, "10", NULL, NULL, NULL, 0); + test("331", NULL, NULL, NULL, NULL, "331", NULL, NULL, NULL,0); + test("3313", NULL, NULL, NULL, NULL, "3313", NULL, NULL, NULL, 0); + + /* Unix */ + test("/", NULL, NULL, NULL, "unix/", "/", NULL, NULL, NULL, 3); + test("/path1/path2/path3", NULL, NULL, NULL, "unix/", + "/path1/path2/path3", NULL, NULL, NULL, 3); + test("login:password@/path1/path2/path3", NULL, "login", "password", + "unix/", "/path1/path2/path3", NULL, NULL, NULL, 3); + test("unix/:/path1/path2/path3", NULL, NULL, NULL, "unix/", + "/path1/path2/path3", NULL, NULL, NULL, 3); + test("unix/:/path1/path2/path3:", NULL, NULL, NULL, "unix/", + "/path1/path2/path3", NULL, NULL, NULL, 3); + test("unix/:/path1/path2/path3:/", NULL, NULL, NULL, "unix/", + "/path1/path2/path3", "/", NULL, NULL, 3); + test("unix/:/path1/path2/path3?q1=v1&q2=v2#fragment", NULL, NULL, NULL, + "unix/", "/path1/path2/path3", NULL, "q1=v1&q2=v2", "fragment", 3); + test("unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment", + NULL, NULL, NULL, "unix/", "/path1/path2/path3", "/p1/p2", + "q1=v1&q2=v2", "fragment", 3); +#if 0 + /* Broken due to grammar limitations. */ + test("login:password@unix/:/path1/path2/path3", NULL, "login", + "password", "unix/", "/path1/path2/path3", NULL, NULL, NULL, 3); +#endif + test("scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3", + "scheme", "login", "password", "unix/", "/tmp/unix.sock", + "/path1/path2/path3", NULL, NULL, 3); + test("unix/:./relative/path.sock:/test", NULL, NULL, NULL, "unix/", + "./relative/path.sock", "/test", NULL, NULL, 3); + test("scheme://unix/:./relative/path.sock:/test", "scheme", NULL, NULL, + "unix/", "./relative/path.sock", "/test", NULL, NULL, 3); + + /* Web */ + test("http://tarantool.org/dist/master/debian/pool/main/t/tarantool/" + "tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz", + "http", NULL, NULL, "tarantool.org", NULL, + "/dist/master/debian/pool/main/t/tarantool/" + "tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz", + NULL, NULL, 0); + + test("https://www.google.com/search?" + "safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool" + "&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl", + "https", NULL, NULL, "www.google.com", NULL, "/search", + "safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool" + "&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl", + NULL, 0); + + test_invalid(); + + return check_plan(); +} diff --git a/test/unit/uri.cc b/test/unit/uri.cc deleted file mode 100644 index d07b410c777e072263b40eb6a0765ebb405a6f69..0000000000000000000000000000000000000000 --- a/test/unit/uri.cc +++ /dev/null @@ -1,98 +0,0 @@ -#include "test.h" -#include <uri.h> -#include <string.h> - -#define PLAN 40 - -int -main(void) -{ - plan(PLAN); - - struct uri uri; - - is(uri_parse(&uri, "/file"), 0, "/file"); - is(strcmp(uri_to_string(&uri), "unix:///file"), 0, - "to_string"); - is(strcmp(uri.schema, "unix"), 0, "unix://"); - - - is(uri_parse(&uri, "unix://file"), 0, "unix://file"); - is(strcmp(uri_to_string(&uri), "unix://file"), 0, - "to_string"); - is(strcmp(uri.schema, "unix"), 0, "unix://"); - - - is(uri_parse(&uri, "123"), 0, "123"); - is(strcmp(uri.schema, "tcp"), 0, "tcp://"); - is(strcmp(uri_to_string(&uri), "0.0.0.0:123"), 0, - "to_string"); - - - - is(uri_parse(&uri, "http://11.2.3.4:123"), 0, - "http://11.2.3.4:123"); - is(strcmp(uri.schema, "http"), 0, "http://"); - is(strcmp(uri_to_string(&uri), "http://11.2.3.4:123"), 0, - "to_string"); - - is(uri_parse(&uri, "http://[::fFff:11.2.3.4]:123"), 0, - "http://11.2.3.4:123"); - is(strcmp(uri.schema, "http"), 0, "http://"); - is(strcmp(uri_to_string(&uri), "http://11.2.3.4:123"), 0, - "to_string"); - is(uri_parse(&uri, "http://user:pass@127.0.0.1:12345"), 0, - "http://user:pass@127.0.0.1:12345"); - is(strcmp(uri.login, "user"), 0, "user"); - is(strcmp(uri.password, "pass"), 0, "pass"); - is(strcmp(uri.schema, "http"), 0, "http"); - - - is(uri_parse(&uri, "schema://[2001:0db8:11a3:09d7::1]"), - 0, "schema://[2001:0db8:11a3:09d7::1]"); - is(strcmp(uri_to_string(&uri), - "schema://[2001:db8:11a3:9d7::1]:0"), 0, "to_string"); - - - isnt(uri_parse(&uri, "schema://[2001::11a3:09d7::1]"), - 0, "invalid schema://[2001::11a3:09d7::1]"); - - - - - is(uri_parse(&uri, "128.0.0.1"), 0, "127.0.0.1"); - is(strcmp(uri_to_string(&uri), "128.0.0.1:0"), 0, - "to_string"); - - is(uri_parse(&uri, "128.0.0.1:22"), 0, "127.0.0.1:22"); - is(strcmp(uri_to_string(&uri), "128.0.0.1:22"), 0, - "to_string"); - - is(uri_parse(&uri, "login:password@127.0.0.1"), 0, - "login:password@127.0.0.1"); - is(strcmp(uri.login, "login"), 0, "login"); - is(strcmp(uri.password, "password"), 0, "password"); - is(strcmp(uri.schema, "tcp"), 0, "default schema"); - - is(uri_parse(&uri, "unix://login:password@/path/to"), 0, - "unix://login:password@/path/to"); - is(strcmp(uri.login, "login"), 0, "login"); - is(strcmp(uri.password, "password"), 0, "password"); - is(strcmp(uri.schema, "unix"), 0, "unix"); - is(strcmp(uri_to_string(&uri), "unix:///path/to"), 0, - "to_string"); - - isnt(uri_parse(&uri, "tcp://abc.cde:90"), 0, "invalid uri"); - - is(uri_parse(&uri, "http://127.0.0.1:http"), 0, - "valid uri"); - is(strcmp(uri_to_string(&uri), "http://127.0.0.1:80"), 0, - "service to port number"); - - is(uri_parse(&uri, "mail.ru:https"), 0, "valid uri"); - - isnt(strstr(uri_to_string(&uri), ":443"), 0, - "service converted"); - - return check_plan(); -} diff --git a/test/unit/uri.result b/test/unit/uri.result index 751cc2083c973c2a58075ea17d8b6c07a5a55dff..7218a95036131d2b4315ffccf3b86a3b749689ed 100644 --- a/test/unit/uri.result +++ b/test/unit/uri.result @@ -1,41 +1,713 @@ -1..40 -ok 1 - /file -ok 2 - to_string -ok 3 - unix:// -ok 4 - unix://file -ok 5 - to_string -ok 6 - unix:// -ok 7 - 123 -ok 8 - tcp:// -ok 9 - to_string -ok 10 - http://11.2.3.4:123 -ok 11 - http:// -ok 12 - to_string -ok 13 - http://11.2.3.4:123 -ok 14 - http:// -ok 15 - to_string -ok 16 - http://user:pass@127.0.0.1:12345 -ok 17 - user -ok 18 - pass -ok 19 - http -ok 20 - schema://[2001:0db8:11a3:09d7::1] -ok 21 - to_string -ok 22 - invalid schema://[2001::11a3:09d7::1] -ok 23 - 127.0.0.1 -ok 24 - to_string -ok 25 - 127.0.0.1:22 -ok 26 - to_string -ok 27 - login:password@127.0.0.1 -ok 28 - login -ok 29 - password -ok 30 - default schema -ok 31 - unix://login:password@/path/to -ok 32 - login -ok 33 - password -ok 34 - unix -ok 35 - to_string -ok 36 - invalid uri -ok 37 - valid uri -ok 38 - service to port number -ok 39 - valid uri -ok 40 - service converted +1..60 + 1..10 + ok 1 - host: parse + ok 2 - host: scheme + ok 3 - host: login + ok 4 - host: password + ok 5 - host: host + ok 6 - host: service + ok 7 - host: path + ok 8 - host: query + ok 9 - host: fragment + ok 10 - host: host_hint +ok 1 - subtests + 1..10 + ok 1 - host/: parse + ok 2 - host/: scheme + ok 3 - host/: login + ok 4 - host/: password + ok 5 - host/: host + ok 6 - host/: service + ok 7 - host/: path + ok 8 - host/: query + ok 9 - host/: fragment + ok 10 - host/: host_hint +ok 2 - subtests + 1..10 + ok 1 - host/path1/path2/path3: parse + ok 2 - host/path1/path2/path3: scheme + ok 3 - host/path1/path2/path3: login + ok 4 - host/path1/path2/path3: password + ok 5 - host/path1/path2/path3: host + ok 6 - host/path1/path2/path3: service + ok 7 - host/path1/path2/path3: path + ok 8 - host/path1/path2/path3: query + ok 9 - host/path1/path2/path3: fragment + ok 10 - host/path1/path2/path3: host_hint +ok 3 - subtests + 1..10 + ok 1 - host/path1/path2/path3?q1=v1&q2=v2#fragment: parse + ok 2 - host/path1/path2/path3?q1=v1&q2=v2#fragment: scheme + ok 3 - host/path1/path2/path3?q1=v1&q2=v2#fragment: login + ok 4 - host/path1/path2/path3?q1=v1&q2=v2#fragment: password + ok 5 - host/path1/path2/path3?q1=v1&q2=v2#fragment: host + ok 6 - host/path1/path2/path3?q1=v1&q2=v2#fragment: service + ok 7 - host/path1/path2/path3?q1=v1&q2=v2#fragment: path + ok 8 - host/path1/path2/path3?q1=v1&q2=v2#fragment: query + ok 9 - host/path1/path2/path3?q1=v1&q2=v2#fragment: fragment + ok 10 - host/path1/path2/path3?q1=v1&q2=v2#fragment: host_hint +ok 4 - subtests + 1..10 + ok 1 - host:service: parse + ok 2 - host:service: scheme + ok 3 - host:service: login + ok 4 - host:service: password + ok 5 - host:service: host + ok 6 - host:service: service + ok 7 - host:service: path + ok 8 - host:service: query + ok 9 - host:service: fragment + ok 10 - host:service: host_hint +ok 5 - subtests + 1..10 + ok 1 - host:service/: parse + ok 2 - host:service/: scheme + ok 3 - host:service/: login + ok 4 - host:service/: password + ok 5 - host:service/: host + ok 6 - host:service/: service + ok 7 - host:service/: path + ok 8 - host:service/: query + ok 9 - host:service/: fragment + ok 10 - host:service/: host_hint +ok 6 - subtests + 1..10 + ok 1 - host:service/path1/path2/path3: parse + ok 2 - host:service/path1/path2/path3: scheme + ok 3 - host:service/path1/path2/path3: login + ok 4 - host:service/path1/path2/path3: password + ok 5 - host:service/path1/path2/path3: host + ok 6 - host:service/path1/path2/path3: service + ok 7 - host:service/path1/path2/path3: path + ok 8 - host:service/path1/path2/path3: query + ok 9 - host:service/path1/path2/path3: fragment + ok 10 - host:service/path1/path2/path3: host_hint +ok 7 - subtests + 1..10 + ok 1 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: parse + ok 2 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: scheme + ok 3 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: login + ok 4 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: password + ok 5 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: host + ok 6 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: service + ok 7 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: path + ok 8 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: query + ok 9 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: fragment + ok 10 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: host_hint +ok 8 - subtests + 1..10 + ok 1 - login@host: parse + ok 2 - login@host: scheme + ok 3 - login@host: login + ok 4 - login@host: password + ok 5 - login@host: host + ok 6 - login@host: service + ok 7 - login@host: path + ok 8 - login@host: query + ok 9 - login@host: fragment + ok 10 - login@host: host_hint +ok 9 - subtests + 1..10 + ok 1 - login@host/: parse + ok 2 - login@host/: scheme + ok 3 - login@host/: login + ok 4 - login@host/: password + ok 5 - login@host/: host + ok 6 - login@host/: service + ok 7 - login@host/: path + ok 8 - login@host/: query + ok 9 - login@host/: fragment + ok 10 - login@host/: host_hint +ok 10 - subtests + 1..10 + ok 1 - login@host/path1/path2/path3: parse + ok 2 - login@host/path1/path2/path3: scheme + ok 3 - login@host/path1/path2/path3: login + ok 4 - login@host/path1/path2/path3: password + ok 5 - login@host/path1/path2/path3: host + ok 6 - login@host/path1/path2/path3: service + ok 7 - login@host/path1/path2/path3: path + ok 8 - login@host/path1/path2/path3: query + ok 9 - login@host/path1/path2/path3: fragment + ok 10 - login@host/path1/path2/path3: host_hint +ok 11 - subtests + 1..10 + ok 1 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: parse + ok 2 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: scheme + ok 3 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: login + ok 4 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: password + ok 5 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: host + ok 6 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: service + ok 7 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: path + ok 8 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: query + ok 9 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: fragment + ok 10 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: host_hint +ok 12 - subtests + 1..10 + ok 1 - login:password@host: parse + ok 2 - login:password@host: scheme + ok 3 - login:password@host: login + ok 4 - login:password@host: password + ok 5 - login:password@host: host + ok 6 - login:password@host: service + ok 7 - login:password@host: path + ok 8 - login:password@host: query + ok 9 - login:password@host: fragment + ok 10 - login:password@host: host_hint +ok 13 - subtests + 1..10 + ok 1 - login:password@host/: parse + ok 2 - login:password@host/: scheme + ok 3 - login:password@host/: login + ok 4 - login:password@host/: password + ok 5 - login:password@host/: host + ok 6 - login:password@host/: service + ok 7 - login:password@host/: path + ok 8 - login:password@host/: query + ok 9 - login:password@host/: fragment + ok 10 - login:password@host/: host_hint +ok 14 - subtests + 1..10 + ok 1 - login:password@host/path1/path2/path3: parse + ok 2 - login:password@host/path1/path2/path3: scheme + ok 3 - login:password@host/path1/path2/path3: login + ok 4 - login:password@host/path1/path2/path3: password + ok 5 - login:password@host/path1/path2/path3: host + ok 6 - login:password@host/path1/path2/path3: service + ok 7 - login:password@host/path1/path2/path3: path + ok 8 - login:password@host/path1/path2/path3: query + ok 9 - login:password@host/path1/path2/path3: fragment + ok 10 - login:password@host/path1/path2/path3: host_hint +ok 15 - subtests + 1..10 + ok 1 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: parse + ok 2 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: scheme + ok 3 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: login + ok 4 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: password + ok 5 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: host + ok 6 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: service + ok 7 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: path + ok 8 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: query + ok 9 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: fragment + ok 10 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: host_hint +ok 16 - subtests + 1..10 + ok 1 - login:password@host:service: parse + ok 2 - login:password@host:service: scheme + ok 3 - login:password@host:service: login + ok 4 - login:password@host:service: password + ok 5 - login:password@host:service: host + ok 6 - login:password@host:service: service + ok 7 - login:password@host:service: path + ok 8 - login:password@host:service: query + ok 9 - login:password@host:service: fragment + ok 10 - login:password@host:service: host_hint +ok 17 - subtests + 1..10 + ok 1 - login:password@host:service/: parse + ok 2 - login:password@host:service/: scheme + ok 3 - login:password@host:service/: login + ok 4 - login:password@host:service/: password + ok 5 - login:password@host:service/: host + ok 6 - login:password@host:service/: service + ok 7 - login:password@host:service/: path + ok 8 - login:password@host:service/: query + ok 9 - login:password@host:service/: fragment + ok 10 - login:password@host:service/: host_hint +ok 18 - subtests + 1..10 + ok 1 - login:password@host:service/path1/path2/path3: parse + ok 2 - login:password@host:service/path1/path2/path3: scheme + ok 3 - login:password@host:service/path1/path2/path3: login + ok 4 - login:password@host:service/path1/path2/path3: password + ok 5 - login:password@host:service/path1/path2/path3: host + ok 6 - login:password@host:service/path1/path2/path3: service + ok 7 - login:password@host:service/path1/path2/path3: path + ok 8 - login:password@host:service/path1/path2/path3: query + ok 9 - login:password@host:service/path1/path2/path3: fragment + ok 10 - login:password@host:service/path1/path2/path3: host_hint +ok 19 - subtests + 1..10 + ok 1 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: parse + ok 2 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: scheme + ok 3 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: login + ok 4 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: password + ok 5 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: host + ok 6 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: service + ok 7 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: path + ok 8 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: query + ok 9 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: fragment + ok 10 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: host_hint +ok 20 - subtests + 1..10 + ok 1 - scheme://login:password@host:service: parse + ok 2 - scheme://login:password@host:service: scheme + ok 3 - scheme://login:password@host:service: login + ok 4 - scheme://login:password@host:service: password + ok 5 - scheme://login:password@host:service: host + ok 6 - scheme://login:password@host:service: service + ok 7 - scheme://login:password@host:service: path + ok 8 - scheme://login:password@host:service: query + ok 9 - scheme://login:password@host:service: fragment + ok 10 - scheme://login:password@host:service: host_hint +ok 21 - subtests + 1..10 + ok 1 - scheme://login:password@host:service/: parse + ok 2 - scheme://login:password@host:service/: scheme + ok 3 - scheme://login:password@host:service/: login + ok 4 - scheme://login:password@host:service/: password + ok 5 - scheme://login:password@host:service/: host + ok 6 - scheme://login:password@host:service/: service + ok 7 - scheme://login:password@host:service/: path + ok 8 - scheme://login:password@host:service/: query + ok 9 - scheme://login:password@host:service/: fragment + ok 10 - scheme://login:password@host:service/: host_hint +ok 22 - subtests + 1..10 + ok 1 - scheme://login:password@host:service/path1/path2/path3: parse + ok 2 - scheme://login:password@host:service/path1/path2/path3: scheme + ok 3 - scheme://login:password@host:service/path1/path2/path3: login + ok 4 - scheme://login:password@host:service/path1/path2/path3: password + ok 5 - scheme://login:password@host:service/path1/path2/path3: host + ok 6 - scheme://login:password@host:service/path1/path2/path3: service + ok 7 - scheme://login:password@host:service/path1/path2/path3: path + ok 8 - scheme://login:password@host:service/path1/path2/path3: query + ok 9 - scheme://login:password@host:service/path1/path2/path3: fragment + ok 10 - scheme://login:password@host:service/path1/path2/path3: host_hint +ok 23 - subtests + 1..10 + ok 1 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: parse + ok 2 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: scheme + ok 3 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: login + ok 4 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: password + ok 5 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: host + ok 6 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: service + ok 7 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: path + ok 8 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: query + ok 9 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: fragment + ok 10 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: host_hint +ok 24 - subtests + 1..10 + ok 1 - host/path: parse + ok 2 - host/path: scheme + ok 3 - host/path: login + ok 4 - host/path: password + ok 5 - host/path: host + ok 6 - host/path: service + ok 7 - host/path: path + ok 8 - host/path: query + ok 9 - host/path: fragment + ok 10 - host/path: host_hint +ok 25 - subtests + 1..10 + ok 1 - host//: parse + ok 2 - host//: scheme + ok 3 - host//: login + ok 4 - host//: password + ok 5 - host//: host + ok 6 - host//: service + ok 7 - host//: path + ok 8 - host//: query + ok 9 - host//: fragment + ok 10 - host//: host_hint +ok 26 - subtests + 1..10 + ok 1 - host//path: parse + ok 2 - host//path: scheme + ok 3 - host//path: login + ok 4 - host//path: password + ok 5 - host//path: host + ok 6 - host//path: service + ok 7 - host//path: path + ok 8 - host//path: query + ok 9 - host//path: fragment + ok 10 - host//path: host_hint +ok 27 - subtests + 1..10 + ok 1 - host/;abc?q: parse + ok 2 - host/;abc?q: scheme + ok 3 - host/;abc?q: login + ok 4 - host/;abc?q: password + ok 5 - host/;abc?q: host + ok 6 - host/;abc?q: service + ok 7 - host/;abc?q: path + ok 8 - host/;abc?q: query + ok 9 - host/;abc?q: fragment + ok 10 - host/;abc?q: host_hint +ok 28 - subtests + 1..10 + ok 1 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: parse + ok 2 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: scheme + ok 3 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: login + ok 4 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: password + ok 5 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: host + ok 6 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: service + ok 7 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: path + ok 8 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: query + ok 9 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: fragment + ok 10 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: host_hint +ok 29 - subtests + 1..10 + ok 1 - host/~user: parse + ok 2 - host/~user: scheme + ok 3 - host/~user: login + ok 4 - host/~user: password + ok 5 - host/~user: host + ok 6 - host/~user: service + ok 7 - host/~user: path + ok 8 - host/~user: query + ok 9 - host/~user: fragment + ok 10 - host/~user: host_hint +ok 30 - subtests + 1..10 + ok 1 - try.tarantool.org: parse + ok 2 - try.tarantool.org: scheme + ok 3 - try.tarantool.org: login + ok 4 - try.tarantool.org: password + ok 5 - try.tarantool.org: host + ok 6 - try.tarantool.org: service + ok 7 - try.tarantool.org: path + ok 8 - try.tarantool.org: query + ok 9 - try.tarantool.org: fragment + ok 10 - try.tarantool.org: host_hint +ok 31 - subtests + 1..10 + ok 1 - try.tarantool.org: parse + ok 2 - try.tarantool.org: scheme + ok 3 - try.tarantool.org: login + ok 4 - try.tarantool.org: password + ok 5 - try.tarantool.org: host + ok 6 - try.tarantool.org: service + ok 7 - try.tarantool.org: path + ok 8 - try.tarantool.org: query + ok 9 - try.tarantool.org: fragment + ok 10 - try.tarantool.org: host_hint +ok 32 - subtests + 1..10 + ok 1 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: parse + ok 2 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: scheme + ok 3 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: login + ok 4 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: password + ok 5 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: host + ok 6 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: service + ok 7 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: path + ok 8 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: query + ok 9 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: fragment + ok 10 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: host_hint +ok 33 - subtests + 1..10 + ok 1 - 0.0.0.0: parse + ok 2 - 0.0.0.0: scheme + ok 3 - 0.0.0.0: login + ok 4 - 0.0.0.0: password + ok 5 - 0.0.0.0: host + ok 6 - 0.0.0.0: service + ok 7 - 0.0.0.0: path + ok 8 - 0.0.0.0: query + ok 9 - 0.0.0.0: fragment + ok 10 - 0.0.0.0: host_hint +ok 34 - subtests + 1..10 + ok 1 - 127.0.0.1: parse + ok 2 - 127.0.0.1: scheme + ok 3 - 127.0.0.1: login + ok 4 - 127.0.0.1: password + ok 5 - 127.0.0.1: host + ok 6 - 127.0.0.1: service + ok 7 - 127.0.0.1: path + ok 8 - 127.0.0.1: query + ok 9 - 127.0.0.1: fragment + ok 10 - 127.0.0.1: host_hint +ok 35 - subtests + 1..10 + ok 1 - 127.0.0.1:3313: parse + ok 2 - 127.0.0.1:3313: scheme + ok 3 - 127.0.0.1:3313: login + ok 4 - 127.0.0.1:3313: password + ok 5 - 127.0.0.1:3313: host + ok 6 - 127.0.0.1:3313: service + ok 7 - 127.0.0.1:3313: path + ok 8 - 127.0.0.1:3313: query + ok 9 - 127.0.0.1:3313: fragment + ok 10 - 127.0.0.1:3313: host_hint +ok 36 - subtests + 1..10 + ok 1 - scheme://login:password@127.0.0.1:3313: parse + ok 2 - scheme://login:password@127.0.0.1:3313: scheme + ok 3 - scheme://login:password@127.0.0.1:3313: login + ok 4 - scheme://login:password@127.0.0.1:3313: password + ok 5 - scheme://login:password@127.0.0.1:3313: host + ok 6 - scheme://login:password@127.0.0.1:3313: service + ok 7 - scheme://login:password@127.0.0.1:3313: path + ok 8 - scheme://login:password@127.0.0.1:3313: query + ok 9 - scheme://login:password@127.0.0.1:3313: fragment + ok 10 - scheme://login:password@127.0.0.1:3313: host_hint +ok 37 - subtests + 1..10 + ok 1 - [2001::11a3:09d7::1]: parse + ok 2 - [2001::11a3:09d7::1]: scheme + ok 3 - [2001::11a3:09d7::1]: login + ok 4 - [2001::11a3:09d7::1]: password + ok 5 - [2001::11a3:09d7::1]: host + ok 6 - [2001::11a3:09d7::1]: service + ok 7 - [2001::11a3:09d7::1]: path + ok 8 - [2001::11a3:09d7::1]: query + ok 9 - [2001::11a3:09d7::1]: fragment + ok 10 - [2001::11a3:09d7::1]: host_hint +ok 38 - subtests + 1..10 + ok 1 - scheme://login:password@[2001::11a3:09d7::1]:3313: parse + ok 2 - scheme://login:password@[2001::11a3:09d7::1]:3313: scheme + ok 3 - scheme://login:password@[2001::11a3:09d7::1]:3313: login + ok 4 - scheme://login:password@[2001::11a3:09d7::1]:3313: password + ok 5 - scheme://login:password@[2001::11a3:09d7::1]:3313: host + ok 6 - scheme://login:password@[2001::11a3:09d7::1]:3313: service + ok 7 - scheme://login:password@[2001::11a3:09d7::1]:3313: path + ok 8 - scheme://login:password@[2001::11a3:09d7::1]:3313: query + ok 9 - scheme://login:password@[2001::11a3:09d7::1]:3313: fragment + ok 10 - scheme://login:password@[2001::11a3:09d7::1]:3313: host_hint +ok 39 - subtests + 1..10 + ok 1 - scheme://[2001:0db8:11a3:09d7::1]: parse + ok 2 - scheme://[2001:0db8:11a3:09d7::1]: scheme + ok 3 - scheme://[2001:0db8:11a3:09d7::1]: login + ok 4 - scheme://[2001:0db8:11a3:09d7::1]: password + ok 5 - scheme://[2001:0db8:11a3:09d7::1]: host + ok 6 - scheme://[2001:0db8:11a3:09d7::1]: service + ok 7 - scheme://[2001:0db8:11a3:09d7::1]: path + ok 8 - scheme://[2001:0db8:11a3:09d7::1]: query + ok 9 - scheme://[2001:0db8:11a3:09d7::1]: fragment + ok 10 - scheme://[2001:0db8:11a3:09d7::1]: host_hint +ok 40 - subtests + 1..10 + ok 1 - [::ffff:11.2.3.4]: parse + ok 2 - [::ffff:11.2.3.4]: scheme + ok 3 - [::ffff:11.2.3.4]: login + ok 4 - [::ffff:11.2.3.4]: password + ok 5 - [::ffff:11.2.3.4]: host + ok 6 - [::ffff:11.2.3.4]: service + ok 7 - [::ffff:11.2.3.4]: path + ok 8 - [::ffff:11.2.3.4]: query + ok 9 - [::ffff:11.2.3.4]: fragment + ok 10 - [::ffff:11.2.3.4]: host_hint +ok 41 - subtests + 1..10 + ok 1 - scheme://login:password@[::ffff:11.2.3.4]:3313: parse + ok 2 - scheme://login:password@[::ffff:11.2.3.4]:3313: scheme + ok 3 - scheme://login:password@[::ffff:11.2.3.4]:3313: login + ok 4 - scheme://login:password@[::ffff:11.2.3.4]:3313: password + ok 5 - scheme://login:password@[::ffff:11.2.3.4]:3313: host + ok 6 - scheme://login:password@[::ffff:11.2.3.4]:3313: service + ok 7 - scheme://login:password@[::ffff:11.2.3.4]:3313: path + ok 8 - scheme://login:password@[::ffff:11.2.3.4]:3313: query + ok 9 - scheme://login:password@[::ffff:11.2.3.4]:3313: fragment + ok 10 - scheme://login:password@[::ffff:11.2.3.4]:3313: host_hint +ok 42 - subtests + 1..10 + ok 1 - 1: parse + ok 2 - 1: scheme + ok 3 - 1: login + ok 4 - 1: password + ok 5 - 1: host + ok 6 - 1: service + ok 7 - 1: path + ok 8 - 1: query + ok 9 - 1: fragment + ok 10 - 1: host_hint +ok 43 - subtests + 1..10 + ok 1 - 10: parse + ok 2 - 10: scheme + ok 3 - 10: login + ok 4 - 10: password + ok 5 - 10: host + ok 6 - 10: service + ok 7 - 10: path + ok 8 - 10: query + ok 9 - 10: fragment + ok 10 - 10: host_hint +ok 44 - subtests + 1..10 + ok 1 - 331: parse + ok 2 - 331: scheme + ok 3 - 331: login + ok 4 - 331: password + ok 5 - 331: host + ok 6 - 331: service + ok 7 - 331: path + ok 8 - 331: query + ok 9 - 331: fragment + ok 10 - 331: host_hint +ok 45 - subtests + 1..10 + ok 1 - 3313: parse + ok 2 - 3313: scheme + ok 3 - 3313: login + ok 4 - 3313: password + ok 5 - 3313: host + ok 6 - 3313: service + ok 7 - 3313: path + ok 8 - 3313: query + ok 9 - 3313: fragment + ok 10 - 3313: host_hint +ok 46 - subtests + 1..10 + ok 1 - /: parse + ok 2 - /: scheme + ok 3 - /: login + ok 4 - /: password + ok 5 - /: host + ok 6 - /: service + ok 7 - /: path + ok 8 - /: query + ok 9 - /: fragment + ok 10 - /: host_hint +ok 47 - subtests + 1..10 + ok 1 - /path1/path2/path3: parse + ok 2 - /path1/path2/path3: scheme + ok 3 - /path1/path2/path3: login + ok 4 - /path1/path2/path3: password + ok 5 - /path1/path2/path3: host + ok 6 - /path1/path2/path3: service + ok 7 - /path1/path2/path3: path + ok 8 - /path1/path2/path3: query + ok 9 - /path1/path2/path3: fragment + ok 10 - /path1/path2/path3: host_hint +ok 48 - subtests + 1..10 + ok 1 - login:password@/path1/path2/path3: parse + ok 2 - login:password@/path1/path2/path3: scheme + ok 3 - login:password@/path1/path2/path3: login + ok 4 - login:password@/path1/path2/path3: password + ok 5 - login:password@/path1/path2/path3: host + ok 6 - login:password@/path1/path2/path3: service + ok 7 - login:password@/path1/path2/path3: path + ok 8 - login:password@/path1/path2/path3: query + ok 9 - login:password@/path1/path2/path3: fragment + ok 10 - login:password@/path1/path2/path3: host_hint +ok 49 - subtests + 1..10 + ok 1 - unix/:/path1/path2/path3: parse + ok 2 - unix/:/path1/path2/path3: scheme + ok 3 - unix/:/path1/path2/path3: login + ok 4 - unix/:/path1/path2/path3: password + ok 5 - unix/:/path1/path2/path3: host + ok 6 - unix/:/path1/path2/path3: service + ok 7 - unix/:/path1/path2/path3: path + ok 8 - unix/:/path1/path2/path3: query + ok 9 - unix/:/path1/path2/path3: fragment + ok 10 - unix/:/path1/path2/path3: host_hint +ok 50 - subtests + 1..10 + ok 1 - unix/:/path1/path2/path3:: parse + ok 2 - unix/:/path1/path2/path3:: scheme + ok 3 - unix/:/path1/path2/path3:: login + ok 4 - unix/:/path1/path2/path3:: password + ok 5 - unix/:/path1/path2/path3:: host + ok 6 - unix/:/path1/path2/path3:: service + ok 7 - unix/:/path1/path2/path3:: path + ok 8 - unix/:/path1/path2/path3:: query + ok 9 - unix/:/path1/path2/path3:: fragment + ok 10 - unix/:/path1/path2/path3:: host_hint +ok 51 - subtests + 1..10 + ok 1 - unix/:/path1/path2/path3:/: parse + ok 2 - unix/:/path1/path2/path3:/: scheme + ok 3 - unix/:/path1/path2/path3:/: login + ok 4 - unix/:/path1/path2/path3:/: password + ok 5 - unix/:/path1/path2/path3:/: host + ok 6 - unix/:/path1/path2/path3:/: service + ok 7 - unix/:/path1/path2/path3:/: path + ok 8 - unix/:/path1/path2/path3:/: query + ok 9 - unix/:/path1/path2/path3:/: fragment + ok 10 - unix/:/path1/path2/path3:/: host_hint +ok 52 - subtests + 1..10 + ok 1 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: parse + ok 2 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: scheme + ok 3 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: login + ok 4 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: password + ok 5 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: host + ok 6 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: service + ok 7 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: path + ok 8 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: query + ok 9 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: fragment + ok 10 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: host_hint +ok 53 - subtests + 1..10 + ok 1 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: parse + ok 2 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: scheme + ok 3 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: login + ok 4 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: password + ok 5 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: host + ok 6 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: service + ok 7 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: path + ok 8 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: query + ok 9 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: fragment + ok 10 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: host_hint +ok 54 - subtests + 1..10 + ok 1 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: parse + ok 2 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: scheme + ok 3 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: login + ok 4 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: password + ok 5 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: host + ok 6 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: service + ok 7 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: path + ok 8 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: query + ok 9 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: fragment + ok 10 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: host_hint +ok 55 - subtests + 1..10 + ok 1 - unix/:./relative/path.sock:/test: parse + ok 2 - unix/:./relative/path.sock:/test: scheme + ok 3 - unix/:./relative/path.sock:/test: login + ok 4 - unix/:./relative/path.sock:/test: password + ok 5 - unix/:./relative/path.sock:/test: host + ok 6 - unix/:./relative/path.sock:/test: service + ok 7 - unix/:./relative/path.sock:/test: path + ok 8 - unix/:./relative/path.sock:/test: query + ok 9 - unix/:./relative/path.sock:/test: fragment + ok 10 - unix/:./relative/path.sock:/test: host_hint +ok 56 - subtests + 1..10 + ok 1 - scheme://unix/:./relative/path.sock:/test: parse + ok 2 - scheme://unix/:./relative/path.sock:/test: scheme + ok 3 - scheme://unix/:./relative/path.sock:/test: login + ok 4 - scheme://unix/:./relative/path.sock:/test: password + ok 5 - scheme://unix/:./relative/path.sock:/test: host + ok 6 - scheme://unix/:./relative/path.sock:/test: service + ok 7 - scheme://unix/:./relative/path.sock:/test: path + ok 8 - scheme://unix/:./relative/path.sock:/test: query + ok 9 - scheme://unix/:./relative/path.sock:/test: fragment + ok 10 - scheme://unix/:./relative/path.sock:/test: host_hint +ok 57 - subtests + 1..10 + ok 1 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: parse + ok 2 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: scheme + ok 3 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: login + ok 4 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: password + ok 5 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: host + ok 6 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: service + ok 7 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: path + ok 8 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: query + ok 9 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: fragment + ok 10 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: host_hint +ok 58 - subtests + 1..10 + ok 1 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: parse + ok 2 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: scheme + ok 3 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: login + ok 4 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: password + ok 5 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: host + ok 6 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: service + ok 7 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: path + ok 8 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: query + ok 9 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: fragment + ok 10 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: host_hint +ok 59 - subtests + 1..2 + ok 1 - empty is invalid + ok 2 - :// is invalid +ok 60 - subtests diff --git a/third_party/base64.c b/third_party/base64.c index e2fb9785c43ce65a76c2077455a1e18a0b4126a1..49a4f2492d28ab85fee030b550cd3c0f84978c38 100644 --- a/third_party/base64.c +++ b/third_party/base64.c @@ -35,6 +35,9 @@ /* {{{ encode */ +extern inline int +base64_bufsize(int binsize); + enum base64_encodestep { step_A, step_B, step_C }; struct base64_encodestate { diff --git a/third_party/base64.h b/third_party/base64.h index d590820ddb775f816cce7ef9941d47cd8cd70890..a52a5e91f7e767a3694f2efb9a70271279230187 100644 --- a/third_party/base64.h +++ b/third_party/base64.h @@ -39,7 +39,7 @@ extern "C" { #define BASE64_CHARS_PER_LINE 72 -static inline int +inline int base64_bufsize(int binsize) { int datasize = binsize * 4/3 + 4; diff --git a/third_party/sophia b/third_party/sophia index 3889eb4777fdff520c140467eab477c0af3ca7c9..6c6c69d376d8452a7dfefd2086c4934065ab89cc 160000 --- a/third_party/sophia +++ b/third_party/sophia @@ -1 +1 @@ -Subproject commit 3889eb4777fdff520c140467eab477c0af3ca7c9 +Subproject commit 6c6c69d376d8452a7dfefd2086c4934065ab89cc