mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 16:18:28 -05:00
Gopher: initial request handling.
This commit is contained in:
parent
3de9ccf190
commit
e00b22e090
@ -164,7 +164,7 @@ endif
|
||||
|
||||
REDIS_SERVER_NAME=redis-server
|
||||
REDIS_SENTINEL_NAME=redis-sentinel
|
||||
REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o acl.o
|
||||
REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o acl.o gopher.o
|
||||
REDIS_CLI_NAME=redis-cli
|
||||
REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o siphash.o crc16.o
|
||||
REDIS_BENCHMARK_NAME=redis-benchmark
|
||||
|
74
src/gopher.c
Normal file
74
src/gopher.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Redis nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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 "server.h"
|
||||
|
||||
/* Emit an item in Gopher directory listing format:
|
||||
* <type><descr><TAB><selector><TAB><hostname><TAB><port>
|
||||
* If descr or selector are NULL, then the "(NULL)" string is used instead. */
|
||||
void addReplyGopherItem(client *c, const char *type, const char *descr,
|
||||
const char *selector, const char *hostname, int port)
|
||||
{
|
||||
sds item = sdscatfmt(sdsempty(),"%s%s\t%s\t%s\t%i\r\n",
|
||||
type, descr,
|
||||
selector ? selector : "(NULL)",
|
||||
hostname ? hostname : "(NULL)",
|
||||
port);
|
||||
addReplyProto(c,item,sdslen(item));
|
||||
sdsfree(item);
|
||||
}
|
||||
|
||||
/* This is called by processInputBuffer() when an inline request is processed
|
||||
* with Gopher mode enabled, and the request happens to have zero or just one
|
||||
* argument. In such case we get the relevant key and reply using the Gopher
|
||||
* protocol. */
|
||||
void processGopherRequest(client *c) {
|
||||
robj *keyname = c->argc == 0 ? createStringObject("/",1) : c->argv[1];
|
||||
robj *o = lookupKeyRead(c->db,keyname);
|
||||
|
||||
/* If there is no such key, return with a Gopher error. */
|
||||
if (o == NULL || o->type != OBJ_STRING) {
|
||||
char *errstr;
|
||||
if (o == NULL)
|
||||
errstr = "Error: no content at the specified key";
|
||||
else
|
||||
errstr = "Error: selected key type is invalid "
|
||||
"for Gopher output";
|
||||
addReplyGopherItem(c,"i",errstr,NULL,NULL,0);
|
||||
addReplyGopherItem(c,"i","Redis Gopher server",NULL,NULL,0);
|
||||
} else {
|
||||
}
|
||||
|
||||
/* Cleanup, also make sure to emit the final ".CRLF" line. Note that
|
||||
* the connection will be closed immediately after this because the client
|
||||
* will be flagged with CLIENT_CLOSE_AFTER_REPLY, in accordance with the
|
||||
* Gopher protocol. */
|
||||
if (c->argc == 0) decrRefCount(keyname);
|
||||
addReplyProto(c,".\r\n",3);
|
||||
}
|
@ -1564,6 +1564,14 @@ void processInputBuffer(client *c) {
|
||||
|
||||
if (c->reqtype == PROTO_REQ_INLINE) {
|
||||
if (processInlineBuffer(c) != C_OK) break;
|
||||
/* If the Gopher mode and we got zero or one argument, process
|
||||
* the request in Gopher mode. */
|
||||
if (server.gopher_enabled && (c->argc == 1 || c->argc == 0)) {
|
||||
processGopherRequest(c);
|
||||
resetClient(c);
|
||||
c->flags |= CLIENT_CLOSE_AFTER_REPLY;
|
||||
break;
|
||||
}
|
||||
} else if (c->reqtype == PROTO_REQ_MULTIBULK) {
|
||||
if (processMultibulkBuffer(c) != C_OK) break;
|
||||
} else {
|
||||
|
@ -1514,6 +1514,7 @@ void setDeferredAttributeLen(client *c, void *node, long length);
|
||||
void setDeferredPushLen(client *c, void *node, long length);
|
||||
void processInputBuffer(client *c);
|
||||
void processInputBufferAndReplicate(client *c);
|
||||
void processGopherRequest(client *c);
|
||||
void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
|
Loading…
Reference in New Issue
Block a user