aboutsummaryrefslogtreecommitdiffstats
path: root/routers/private
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2023-04-21 02:49:06 +0800
committerGitHub <noreply@github.com>2023-04-20 14:49:06 -0400
commitb9a97ccd0ea1ee44db85b0fbb80b75255af7c742 (patch)
tree300578dc3c3e62a4cf956ccdc22b8b0ad0cc6036 /routers/private
parent70fc47a22a0bfaef7fb16dcc8a6a2e011b10f8d4 (diff)
downloadgitea-b9a97ccd0ea1ee44db85b0fbb80b75255af7c742.tar.gz
gitea-b9a97ccd0ea1ee44db85b0fbb80b75255af7c742.zip
Refactor web route (#24080)
The old code is unnecessarily complex, and has many misuses. Old code "wraps" a lot, wrap wrap wrap, it's difficult to understand which kind of handler is used. The new code uses a general approach, we do not need to write all kinds of handlers into the "wrapper", do not need to wrap them again and again. New code, there are only 2 concepts: 1. HandlerProvider: `func (h any) (handlerProvider func (next) http.Handler)`, it can be used as middleware 2. Use HandlerProvider to get the final HandlerFunc, and use it for `r.Get()` And we can decouple the route package from context package (see the TODO). # FAQ ## Is `reflect` safe? Yes, all handlers are checked during startup, see the `preCheckHandler` comment. If any handler is wrong, developers could know it in the first time. ## Does `reflect` affect performance? No. https://github.com/go-gitea/gitea/pull/24080#discussion_r1164825901 1. This reflect code only runs for each web handler call, handler is far more slower: 10ms-50ms 2. The reflect is pretty fast (comparing to other code): 0.000265ms 3. XORM has more reflect operations already
Diffstat (limited to 'routers/private')
-rw-r--r--routers/private/internal.go6
1 files changed, 3 insertions, 3 deletions
diff --git a/routers/private/internal.go b/routers/private/internal.go
index b4d32c37a6..c6ea9e0263 100644
--- a/routers/private/internal.go
+++ b/routers/private/internal.go
@@ -38,12 +38,12 @@ func CheckInternalToken(next http.Handler) http.Handler {
}
// bind binding an obj to a handler
-func bind[T any](obj T) http.HandlerFunc {
- return web.Wrap(func(ctx *context.PrivateContext) {
+func bind[T any](_ T) any {
+ return func(ctx *context.PrivateContext) {
theObj := new(T) // create a new form obj for every request but not use obj directly
binding.Bind(ctx.Req, theObj)
web.SetForm(ctx, theObj)
- })
+ }
}
// Routes registers all internal APIs routes to web application.
neric.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
 * Copyright 2009-2024 Pierre Ossman for Cendio AB
 * 
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
 * USA.
 */

/////////////////////////////////////////////////////////////////////////////

// SDesktop is an interface implemented by back-ends, on which callbacks are
// made by the VNCServer as appropriate for pointer and keyboard events, etc.
// SDesktop objects are always created before the VNCServer - the SDesktop
// will be passed a pointer to the VNCServer in the start() call.  If a more
// implementation-specific pointer to the VNCServer is required then this
// can be provided to the SDesktop via an implementation-specific method.
//
// An SDesktop usually has an associated PixelBuffer which it tells the
// VNCServer via the VNCServer's setPixelBuffer() method.  It can do this at
// any time, but the PixelBuffer MUST be valid by the time the call to start()
// returns.  The PixelBuffer may be set to null again if desired when stop() is
// called.  Note that start() and stop() are guaranteed to be called
// alternately; there should never be two calls to start() without an
// intervening stop() and vice-versa.
//

#ifndef __RFB_SDESKTOP_H__
#define __RFB_SDESKTOP_H__

#include <rfb/PixelBuffer.h>
#include <rfb/VNCServer.h>
#include <rfb/InputHandler.h>
#include <rfb/screenTypes.h>

namespace network { class Socket; }

namespace rfb {

  class SDesktop : public InputHandler {
  public:
    // init() is called immediately when the VNCServer gets a reference
    // to the SDesktop, so that a reverse reference can be set up.
    virtual void init(rfb::VNCServer* vs) = 0;

    // start() is called by the server when the first client authenticates
    // successfully, and can be used to begin any expensive tasks which are not
    // needed when there are no clients.  A valid PixelBuffer must have been
    // set via the VNCServer's setPixelBuffer() method by the time this call
    // returns.

    virtual void start() = 0;

    // stop() is called by the server when there are no longer any
    // authenticated clients, and therefore the desktop can cease any
    // expensive tasks.

    virtual void stop() = 0;

    // queryConnection() is called when a connection has been
    // successfully authenticated.  The sock and userName arguments
    // identify the socket and the name of the authenticated user, if
    // any. At some point later VNCServer::approveConnection() should
    // be called to either accept or reject the client.
    virtual void queryConnection(network::Socket* sock,
                                 const char* userName) = 0;

    // terminate() is called by the server when it wishes to terminate
    // itself, e.g. because it was configured to terminate when no one is
    // using it.

    virtual void terminate() = 0;

    // setScreenLayout() requests to reconfigure the framebuffer and/or
    // the layout of screens.
    virtual unsigned int setScreenLayout(int /*fb_width*/,
                                         int /*fb_height*/,
                                         const ScreenSet& /*layout*/) {
      return resultProhibited;
    }

    // InputHandler interface
    // pointerEvent(), keyEvent() and clientCutText() are called in response to
    // the relevant RFB protocol messages from clients.
    // See InputHandler for method signatures.

    // handleClipboardRequest() is called whenever a client requests
    // the server to send over its clipboard data. It will only be
    // called after the server has first announced a clipboard change
    // via VNCServer::announceClipboard().
    virtual void handleClipboardRequest() {}

    // handleClipboardAnnounce() is called to indicate a change in the
    // clipboard on a client. Call VNCServer::requestClipboard() to
    // access the actual data.
    virtual void handleClipboardAnnounce(bool /*available*/) {}

    // handleClipboardData() is called when a client has sent over
    // the clipboard data as a result of a previous call to
    // VNCServer::requestClipboard(). Note that this function might
    // never be called if the clipboard data was no longer available
    // when the client received the request.
    virtual void handleClipboardData(const char* /*data*/) {}

  protected:
    virtual ~SDesktop() {}
  };

  // -=- SStaticDesktop
  //     Trivial implementation of the SDesktop interface, which provides
  //     dummy input handlers and event processing routine, and exports
  //     a plain black desktop of the specified format.
  class SStaticDesktop : public SDesktop {
  public:
    SStaticDesktop(const Point& size) : server(0), buffer(0) {
      PixelFormat pf;
      const uint8_t black[4] = { 0, 0, 0, 0 };
      buffer = new ManagedPixelBuffer(pf, size.x, size.y);
      if (buffer)
        buffer->fillRect(buffer->getRect(), black);
    }
    SStaticDesktop(const Point& size, const PixelFormat& pf) : buffer(0) {
      const uint8_t black[4] = { 0, 0, 0, 0 };
      buffer = new ManagedPixelBuffer(pf, size.x, size.y);
      if (buffer)
        buffer->fillRect(buffer->getRect(), black);
    }
    virtual ~SStaticDesktop() {
      if (buffer) delete buffer;
    }

    virtual void init(VNCServer* vs) {
      server = vs;
      server->setPixelBuffer(buffer);
    }
    virtual void start() {
    }
    virtual void stop() {
    }
    virtual void queryConnection(network::Socket* sock,
                                 const char* /*userName*/) {
      server->approveConnection(sock, true, NULL);
    }

  protected:
    VNCServer* server;
    ManagedPixelBuffer* buffer;
  };

};

#endif // __RFB_SDESKTOP_H__