From: Amos Jeffries Date: Fri, 10 Oct 2014 16:00:52 +0000 (-0700) Subject: Gopher: update to CBDATA_CLASS API X-Git-Tag: merge-candidate-3-v1~555 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2327e7c0fddaec48923a094e96c3147a86ada9b2;p=thirdparty%2Fsquid.git Gopher: update to CBDATA_CLASS API * Convert from typedef struct to full class * Convert from old CBDATA API to CBDATA_CLASS2 * Add AsyncJob-alike methods to simplify the cleanup process and future conversion. * Remove unused 'req' member * Remove remove outdated doxygen documentation --- diff --git a/src/gopher.cc b/src/gopher.cc index d659077b6e..141aea5ee1 100644 --- a/src/gopher.cc +++ b/src/gopher.cc @@ -34,75 +34,73 @@ #include "MemObject.h" #endif -/** - \defgroup ServerProtocolGopherInternal Server-Side Gopher Internals - \ingroup ServerProtocolGopherAPI - * Gopher is somewhat complex and gross because it must convert from - * the Gopher protocol to HTTP. - */ - /* gopher type code from rfc. Anawat. */ -/// \ingroup ServerProtocolGopherInternal #define GOPHER_FILE '0' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_DIRECTORY '1' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_CSO '2' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_ERROR '3' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_MACBINHEX '4' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_DOSBIN '5' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_UUENCODED '6' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_INDEX '7' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_TELNET '8' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_BIN '9' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_REDUNT '+' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_3270 'T' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_GIF 'g' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_IMAGE 'I' -/// \ingroup ServerProtocolGopherInternal -#define GOPHER_HTML 'h' /* HTML */ -/// \ingroup ServerProtocolGopherInternal +#define GOPHER_HTML 'h' #define GOPHER_INFO 'i' -/** - \ingroup ServerProtocolGopherInternal - W3 address - */ + +/// W3 address #define GOPHER_WWW 'w' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_SOUND 's' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_PLUS_IMAGE ':' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_PLUS_MOVIE ';' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_PLUS_SOUND '<' -/// \ingroup ServerProtocolGopherInternal #define GOPHER_PORT 70 -/// \ingroup ServerProtocolGopherInternal #define TAB '\t' -/// \ingroup ServerProtocolGopherInternal -/// \todo CODE: should this be a protocol-specific thing? + +// TODO CODE: should this be a protocol-specific thing? #define TEMP_BUF_SIZE 4096 -/// \ingroup ServerProtocolGopherInternal + #define MAX_CSO_RESULT 1024 -/// \ingroup ServerProtocolGopherInternal -typedef struct gopher_ds { +/** + * Gopher Gateway Internals + * + * Gopher is somewhat complex and gross because it must convert from + * the Gopher protocol to HTTP. + */ +class GopherStateData +{ +public: + GopherStateData(FwdState *aFwd) : + entry(aFwd->entry), + conversion(NORMAL), + HTML_header_added(0), + HTML_pre(0), + type_id(GOPHER_FILE /* '0' */), + cso_recno(0), + len(0), + buf(NULL), + fwd(aFwd) + { + *request = 0; + buf = (char *)memAllocate(MEM_4K_BUF); + entry->lock("gopherState"); + *replybuf = 0; + } + + /* AsyncJob API emulated */ + void deleteThis(const char *aReason); + void swanSong(); + +public: StoreEntry *entry; enum { NORMAL, @@ -120,10 +118,14 @@ typedef struct gopher_ds { int len; char *buf; /* pts to a 4k page */ Comm::ConnectionPointer serverConn; - HttpRequest *req; FwdState::Pointer fwd; char replybuf[BUFSIZ]; -} GopherStateData; + +private: + CBDATA_CLASS2(GopherStateData); +}; + +CBDATA_CLASS_INIT(GopherStateData); static CLCB gopherStateFree; static void gopherMimeCreate(GopherStateData *); @@ -137,13 +139,10 @@ static IOCB gopherReadReply; static IOCB gopherSendComplete; static PF gopherSendRequest; -/// \ingroup ServerProtocolGopherInternal static char def_gopher_bin[] = "www/unknown"; -/// \ingroup ServerProtocolGopherInternal static char def_gopher_text[] = "text/plain"; -/// \ingroup ServerProtocolGopherInternal static void gopherStateFree(const CommCloseCbParams ¶ms) { @@ -152,21 +151,27 @@ gopherStateFree(const CommCloseCbParams ¶ms) if (gopherState == NULL) return; - if (gopherState->entry) { - gopherState->entry->unlock("gopherState"); - } + gopherState->deleteThis("gopherStateFree"); +} - HTTPMSGUNLOCK(gopherState->req); +void +GopherStateData::deleteThis(const char *reason) +{ + swanSong(); + delete this; +} - gopherState->fwd = NULL; // refcounted +void +GopherStateData::swanSong() +{ + if (entry) + entry->unlock("gopherState"); - memFree(gopherState->buf, MEM_4K_BUF); - gopherState->buf = NULL; - cbdataFree(gopherState); + if (buf) + memFree(buf, MEM_4K_BUF); } /** - \ingroup ServerProtocolGopherInternal * Create MIME Header for Gopher Data */ static void @@ -245,7 +250,6 @@ gopherMimeCreate(GopherStateData * gopherState) } /** - \ingroup ServerProtocolGopherInternal * Parse a gopher request into components. By Anawat. */ static void @@ -274,12 +278,11 @@ gopher_request_parse(const HttpRequest * req, char *type_id, char *request) } /** - \ingroup ServerProtocolGopherAPI * Parse the request to determine whether it is cachable. * - \param req Request data. - \retval 0 Not cachable. - \retval 1 Cachable. + * \param req Request data. + * \retval 0 Not cachable. + * \retval 1 Cachable. */ int gopherCachable(const HttpRequest * req) @@ -310,7 +313,6 @@ gopherCachable(const HttpRequest * req) return cachable; } -/// \ingroup ServerProtocolGopherInternal static void gopherHTMLHeader(StoreEntry * e, const char *title, const char *substring) { @@ -324,7 +326,6 @@ gopherHTMLHeader(StoreEntry * e, const char *title, const char *substring) storeAppendPrintf(e, "\n"); } -/// \ingroup ServerProtocolGopherInternal static void gopherHTMLFooter(StoreEntry * e) { @@ -337,7 +338,6 @@ gopherHTMLFooter(StoreEntry * e) storeAppendPrintf(e, "\n"); } -/// \ingroup ServerProtocolGopherInternal static void gopherEndHTML(GopherStateData * gopherState) { @@ -354,9 +354,8 @@ gopherEndHTML(GopherStateData * gopherState) } /** - \ingroup ServerProtocolGopherInternal * Convert Gopher to HTML. - \par + * * Borrow part of code from libwww2 came with Mosaic distribution. */ static void @@ -381,7 +380,7 @@ gopherToHTML(GopherStateData * gopherState, char *inbuf, int len) entry = gopherState->entry; - if (gopherState->conversion == gopher_ds::HTML_INDEX_PAGE) { + if (gopherState->conversion == GopherStateData::HTML_INDEX_PAGE) { char *html_url = html_quote(entry->url()); gopherHTMLHeader(entry, "Gopher Index %s", html_url); storeAppendPrintf(entry, @@ -396,7 +395,7 @@ gopherToHTML(GopherStateData * gopherState, char *inbuf, int len) return; } - if (gopherState->conversion == gopher_ds::HTML_CSO_PAGE) { + if (gopherState->conversion == GopherStateData::HTML_CSO_PAGE) { char *html_url = html_quote(entry->url()); gopherHTMLHeader(entry, "CSO Search of %s", html_url); storeAppendPrintf(entry, @@ -414,7 +413,7 @@ gopherToHTML(GopherStateData * gopherState, char *inbuf, int len) String outbuf; if (!gopherState->HTML_header_added) { - if (gopherState->conversion == gopher_ds::HTML_CSO_RESULT) + if (gopherState->conversion == GopherStateData::HTML_CSO_RESULT) gopherHTMLHeader(entry, "CSO Search Result", NULL); else gopherHTMLHeader(entry, "Gopher Menu", NULL); @@ -471,9 +470,9 @@ gopherToHTML(GopherStateData * gopherState, char *inbuf, int len) switch (gopherState->conversion) { - case gopher_ds::HTML_INDEX_RESULT: + case GopherStateData::HTML_INDEX_RESULT: - case gopher_ds::HTML_DIR: { + case GopherStateData::HTML_DIR: { tline = line; gtype = *tline; ++tline; @@ -618,7 +617,7 @@ gopherToHTML(GopherStateData * gopherState, char *inbuf, int len) break; } /* HTML_DIR, HTML_INDEX_RESULT */ - case gopher_ds::HTML_CSO_RESULT: { + case GopherStateData::HTML_CSO_RESULT: { if (line[0] == '-') { int code, recno; char *s_code, *s_recno, *result; @@ -699,7 +698,6 @@ gopherToHTML(GopherStateData * gopherState, char *inbuf, int len) return; } -/// \ingroup ServerProtocolGopherInternal static void gopherTimeout(const CommTimeoutCbParams &io) { @@ -713,7 +711,6 @@ gopherTimeout(const CommTimeoutCbParams &io) } /** - \ingroup ServerProtocolGopherInternal * This will be called when data is ready to be read from fd. * Read until error or connection closed. */ @@ -796,7 +793,7 @@ gopherReadReply(const Comm::ConnectionPointer &conn, char *buf, size_t len, Comm /* Connection closed; retrieval done. */ /* flush the rest of data in temp buf if there is one. */ - if (gopherState->conversion != gopher_ds::NORMAL) + if (gopherState->conversion != GopherStateData::NORMAL) gopherEndHTML(gopherState); entry->timestampsSet(); @@ -804,7 +801,7 @@ gopherReadReply(const Comm::ConnectionPointer &conn, char *buf, size_t len, Comm gopherState->fwd->complete(); gopherState->serverConn->close(); } else { - if (gopherState->conversion != gopher_ds::NORMAL) { + if (gopherState->conversion != GopherStateData::NORMAL) { gopherToHTML(gopherState, buf, len); } else { entry->append(buf, len); @@ -816,7 +813,6 @@ gopherReadReply(const Comm::ConnectionPointer &conn, char *buf, size_t len, Comm } /** - \ingroup ServerProtocolGopherInternal * This will be called when request write is complete. Schedule read of reply. */ static void @@ -859,25 +855,25 @@ gopherSendComplete(const Comm::ConnectionPointer &conn, char *buf, size_t size, case GOPHER_DIRECTORY: /* we got to convert it first */ - gopherState->conversion = gopher_ds::HTML_DIR; + gopherState->conversion = GopherStateData::HTML_DIR; gopherState->HTML_header_added = 0; break; case GOPHER_INDEX: /* we got to convert it first */ - gopherState->conversion = gopher_ds::HTML_INDEX_RESULT; + gopherState->conversion = GopherStateData::HTML_INDEX_RESULT; gopherState->HTML_header_added = 0; break; case GOPHER_CSO: /* we got to convert it first */ - gopherState->conversion = gopher_ds::HTML_CSO_RESULT; + gopherState->conversion = GopherStateData::HTML_CSO_RESULT; gopherState->cso_recno = 0; gopherState->HTML_header_added = 0; break; default: - gopherState->conversion = gopher_ds::NORMAL; + gopherState->conversion = GopherStateData::NORMAL; entry->flush(); } @@ -891,7 +887,6 @@ gopherSendComplete(const Comm::ConnectionPointer &conn, char *buf, size_t size, } /** - \ingroup ServerProtocolGopherInternal * This will be called when connect completes. Write request. */ static void @@ -928,25 +923,12 @@ gopherSendRequest(int fd, void *data) gopherState->entry->makePublic(); } -/// \ingroup ServerProtocolGopherInternal -CBDATA_TYPE(GopherStateData); - -/// \ingroup ServerProtocolGopherAPI void gopherStart(FwdState * fwd) { - StoreEntry *entry = fwd->entry; - GopherStateData *gopherState; - CBDATA_INIT_TYPE(GopherStateData); - gopherState = cbdataAlloc(GopherStateData); - gopherState->buf = (char *)memAllocate(MEM_4K_BUF); - - entry->lock("gopherState"); - gopherState->entry = entry; - - gopherState->fwd = fwd; + GopherStateData *gopherState = new GopherStateData(fwd); - debugs(10, 3, "gopherStart: " << entry->url() ); + debugs(10, 3, gopherState->entry->url()); ++ statCounter.server.all.requests; @@ -965,12 +947,12 @@ gopherStart(FwdState * fwd) gopherMimeCreate(gopherState); if (gopherState->type_id == GOPHER_INDEX) { - gopherState->conversion = gopher_ds::HTML_INDEX_PAGE; + gopherState->conversion = GopherStateData::HTML_INDEX_PAGE; } else { if (gopherState->type_id == GOPHER_CSO) { - gopherState->conversion = gopher_ds::HTML_CSO_PAGE; + gopherState->conversion = GopherStateData::HTML_CSO_PAGE; } else { - gopherState->conversion = gopher_ds::HTML_INDEX_PAGE; + gopherState->conversion = GopherStateData::HTML_INDEX_PAGE; } }