X-Git-Url: https://git.plutz.net//?a=blobdiff_plain;f=index.cgi;h=94c397041e73483d0db5bedaa5b88ab903070934;hb=1a3925fc31df0c8810d3a938e750ee2b2bf460df;hp=61f811e2a5b2b24623e6a7c34f87a7806e0c1820;hpb=fb9c64d7613820866218002d77a3f7f41d602dc0;p=rigidfind diff --git a/index.cgi b/index.cgi index 61f811e..94c3970 100755 --- a/index.cgi +++ b/index.cgi @@ -1,13 +1,17 @@ #!/bin/sh +read _DATE _date_n <<-EOF + $(date +"%s %N") + EOF + . "${_EXEC:-${0%/*}}/cgilite/cgilite.sh" . "${_EXEC:-${0%/*}}/cgilite/storage.sh" . "${_EXEC:-${0%/*}}/cgilite/json.sh" -[ "$_DATE" ] || _DATE="$(date +%s)" +debug "$REQUEST_METHOD $REQUEST_URI $SERVER_PROTOCOL $_DATE" ingest() { - local J="$1" + local J="$1" ztmp="${TMP:-/tmp}/zipfile_$$.zip" # json_get "$J" title # json_get "$J" parts.comments @@ -37,24 +41,28 @@ ingest() { | sed 's;<[^>]*>;;g' ;; *.docx) - printf %s "$content" |base64 -d \ - | unzip -qc /dev/stdin word/document.xml \ + printf %s "$content" |base64 -d >"$ztmp" + unzip -qc "$ztmp" word/document.xml \ | head -c 128M | sed 's;<[^>]*>;;g' + rm -- "$ztmp" ;; *.xlsx) - printf %s "$content" |base64 -d \ - | unzip -qc /dev/stdin xl/sharedStrings.xml \ + printf %s "$content" |base64 -d >"$ztmp" + unzip -qc "$ztmp" xl/sharedStrings.xml \ | head -c 128M | sed 's;<[^>]*>; ;g' + rm -- "$ztmp" ;; *.odt) - printf %s "$content" |base64 -d \ - | unzip -qc /dev/stdin content.xml \ + printf %s "$content" |base64 -d >"$ztmp" + unzip -qc "$ztmp" content.xml \ | head -c 128M | sed 's;<[^>]*>;;g' + rm -- "$ztmp" ;; *.ods|*.odp) - printf %s "$content" |base64 -d \ - | unzip -qc /dev/stdin content.xml \ + printf %s "$content" |base64 -d >"$ztmp" + unzip -qc "$ztmp" content.xml \ | head -c 128M | sed 's;<[^>]*>; ;g' + rm -- "$ztmp" ;; *):;; esac @@ -103,6 +111,23 @@ search() { _INDEX="${PATH_INFO#/}" _INDEX="${_INDEX%%/*}" _records="${_DATA}/${_INDEX}/_0_DOCS" +if [ "${INDEX}" -a ! -d "${_DATA}/${_INDEX}" ]; then + printf '%s\r\n' "Status: 404 Not Found" "" + exit 0 +elif authlist="$(DBM "${_DATA}/auth.db" get "${_INDEX}" )"; then + auth="$(HEADER Authorization)" auth="${auth#Basic }" + for a in $authlist deny; do + [ "$auth" = "$a" ] && break + done + if [ "$a" = "deny" -o ! "$auth" ]; then + printf '%s\r\n' "Status: 401 Unauthorized" \ + "WWW-Authenticate: Basic realm=\"Rigid Find\"" "" \ + | debug + exit 0 + fi + unset a auth authlist +fi + if [ "$REQUEST_METHOD" = "PUT" ]; then _doc="${PATH_INFO#"/${_INDEX}/_doc"}" @@ -120,15 +145,23 @@ if [ "$REQUEST_METHOD" = "PUT" ]; then s;,[ \t\r\n]*"content"[ \t\r\n]*:[ \t\r\n]*"[^"]*";; ')" J="$(json_load "${J}")" - - ingest "$J" "$content"\ - | "${_EXEC}/concordance.sh" \ - "$_DATA/$_INDEX/" "$(STRING "$_doc") $_DATE" + + debug "Content: ${#content} bytes" + debug "$(json_dump "$J")" + + if [ "${#content}" -gt 0 ]; then + ingest "$J" "$content"\ + | "${_EXEC}/concordance.sh" \ + "$_DATA/$_INDEX/" "$(STRING "$_doc") $_DATE" + fi J="${J#obj:}" J="$(DB2 "$J" set _indexdate num:"$_DATE")" - if DBM "$_records" insert "$_doc" "$J"; then + if [ "${#content}" -eq 0 ]; then + printf '%s: %s\r\n' "Status" "200 OK" + result="updated" + elif DBM "$_records" insert "$_doc" "$J"; then printf '%s: %s\r\n' "Status" "201 Created" "Location" "/${_INDEX}/_doc/$(URL "$_doc")" \ result="created" elif DBM "$_records" update "$_doc" "$J"; then @@ -139,10 +172,10 @@ if [ "$REQUEST_METHOD" = "PUT" ]; then exit 0 fi - sed 's;$;\r;' <<-EOF - X-elastic-product: Elasticsearch - content-type: application/vnd.elasticsearch+json;compatible-with=8 - + cat <<-EOF + X-elastic-product: Elasticsearch + content-type: application/vnd.elasticsearch+json;compatible-with=8 + { "_index": $(json_dump str:"${_INDEX}"), "_id": $(json_dump str:"$_doc"), "result": "$result", @@ -167,10 +200,10 @@ elif [ "$REQUEST_METHOD" = "DELETE" ]; then result="not_found" fi - sed 's;$;\r;' <<-EOF - X-elastic-product: Elasticsearch - content-type: application/vnd.elasticsearch+json;compatible-with=8 - + cat <<-EOF + X-elastic-product: Elasticsearch + content-type: application/vnd.elasticsearch+json;compatible-with=8 + { "_index": $(json_dump str:"${_INDEX}"), "_id": $(json_dump str:"$_doc"), "result": "$result", @@ -186,13 +219,16 @@ elif [ "$REQUEST_METHOD" = "POST" ]; then words="$( for j in $(DB2 "$J" iterate @); do json_get "$(UNSTRING "$j")" match_phrase_prefix.content - done 2>/dev/null + done 2>/dev/null |tr \\n ' ' )" + debug "Search words: $words" results="@ $( search "${_DATA}/${_INDEX}" $words \ | while read -r score id source; do - S="$(DB2 "" set _id str:"$(UNSTRING "${id#/}")")" + debug "Hit: $id $score" + S="$(DB2 "" set _index str:"${_INDEX}")" + S="$(DB2 "$S" set _id str:"$(UNSTRING "${id#/}")")" S="$(DB2 "$S" set _score num:"$score")" S="$(DB2 "$S" set _source obj:"$(UNSTRING "$source")")" printf 'obj:%s\t' "$(STRING "$S")" @@ -200,17 +236,18 @@ elif [ "$REQUEST_METHOD" = "POST" ]; then )" results="${results% }" - sed 's;$;\r;' <<-EOF - Status: 200 OK - X-elastic-product: Elasticsearch - Content-Type: application/vnd.elasticsearch+json;compatible-with=8 + t="$(( ${_DATE}${_date_n} - $(date +%s%N) ))" - { "took":0, + cat <<-EOF + Status: 200 OK + X-elastic-product: Elasticsearch + Content-Type: application/vnd.elasticsearch+json;compatible-with=8 + + { "took":$((t / 1000)), "timed_out":false, - "_shards":{"total":1,"successful":1,"skipped":0,"failed":0}, "hits": { "total":{"value": $(DB2 "$results" count @) ,"relation":"eq"}, - "max_score": $(json_get "arr:$results" '[0]._score' 2>&- || printf 0), + "max_score": $(json_get "arr:$results" '[0]._score' 2>/dev/null || printf 0), "hits": $(json_dump "arr:$results") } } @@ -221,74 +258,22 @@ elif [ "$REQUEST_METHOD" = "HEAD" ]; then [ ! "${accept#*"vnd.elasticsearch+json"*}" ] \ && ctype="${accept}" || ctype="application/json" - sed 's;$;\r;' <<-EOF - HTTP/1.1 200 OK - X-elastic-product: Elasticsearch - content-type: ${ctype} - - EOF - exit 0 - -elif [ "$REQUEST_METHOD" = "GET" ]; then - accept="$(HEADER Accept)" - [ ! "${accept#*"vnd.elasticsearch+json"*}" ] \ - && ctype="${accept}" || ctype="application/json" - - sed 's;$;\r;' <<-EOF - HTTP/1.1 200 OK - X-elastic-product: Elasticsearch - content-type: ${ctype} - + cat <<-EOF + Status: 200 OK + X-elastic-product: Elasticsearch + content-type: ${ctype} + EOF - - if [ "$PATH_INFO" = "/${_INDEX}/" ]; then - sed 's;$;\r;' <<-EOF - { $(json_dump str:"${_INDEX}"): { - "aliases":{}, - "mappings": { - "properties": { - "content": {"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}, - "hash":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}, - "metatags":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}, - "owner":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}, - "parts":{"properties":{"comments":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}}, - "provider":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}, - "share_names":{"properties":{"paul":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}}, - "source":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}, - "title":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}} - } - }, - "settings": { - "index": { - "routing":{"allocation":{"include":{"_tier_preference":"data_content"}}}, - "number_of_shards":"1", - "provided_name": $(json_dump str:"${_INDEX}"), - "creation_date": "$(stat -c %W "${_DATA}/${_INDEX}")", - "number_of_replicas":"1", - "uuid":"0000000000000000000000", - "version":{"created":"8500010"} - } - } - } - } - EOF - else - sed 's;$;\r;' <<-EOF - { "name" : "head", - "cluster_name" : "elasticsearch", - "version" : { - "number" : "8.12.1", - "lucene_version" : "9.9.2", - "minimum_wire_compatibility_version" : "7.17.0", - "minimum_index_compatibility_version" : "7.0.0" - }, - "tagline" : "You Know, for Search" - } - EOF - fi exit 0 else - printf '%s\r\n' "Status: 500 Internal Server Error" "" + # elif [ "$REQUEST_METHOD" = "GET" ]; then + cat <<-EOF + Status: 501 Not Implemented + X-elastic-product: Elasticsearch + content-type: text/plain + + Use the Nextcloud Elastic Search Plugin to use this service. + EOF exit 0 fi