{"thread":{"id":"56323","subject":"[PATCH] add http.maxReceiveSpeed to limit git-receive-pack receiving speed","startedAt":"2021-08-19T09:14:50Z","lastAt":"2021-08-31T04:25:44Z","messageCount":12,"participants":["Xia XiaoWen","Bagas Sanjaya","Xiaowen Xia","Junio C Hamano","Jeff King","Randall S. Becker","chenan.xxw","Jiang Xin"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"433121","messageId":"20210819091433.348-1-chenan.xxw@alibaba-inc.com","threadId":"56323","inReplyTo":null,"subject":"[PATCH] add http.maxReceiveSpeed to limit git-receive-pack receiving speed","fromName":"Xia XiaoWen","fromEmail":"haoyurenzhuxia@gmail.com","sentAt":"2021-08-19T09:14:33Z","receivedAt":"2021-08-19T09:14:50Z","isPatch":true,"sender":{"key":"haoyurenzhuxia@gmail.com","avatar":null},"body":"Sometimes need to limit the receive speed of git `clone/fetch`\nbecause of the limited network bandwidth, otherwise will prevent\nother applications from using the network normally.\n\nAdd `http.maxReceiveSpeed` to limit `git-receive-pack` receiving\nspeed, Can be overridden by `GIT_HTTP_MAX_RECEIVE_SPEED` eivironment\nvariable.\n\nThe default is unlimited, same if the value is 0 or negative. The\ndefault unit is Bytes/s, common unit suffixes of k, m, or g are supported.\n\nthis configuration is valid for `clone`, `fetch`, `pull` commands of the\nhttps protocol, and only supports libcurl 7.15.5 and above.\n---\n http.c | 24 +++++++++++++++++++++++-\n 1 file changed, 23 insertions(+), 1 deletion(-)\n\ndiff --git a/http.c b/http.c\nindex 8119247149..12030cf3bc 100644\n--- a/http.c\n+++ b/http.c\n@@ -83,6 +83,9 @@ static const char *ssl_pinnedkey;\n static const char *ssl_cainfo;\n static long curl_low_speed_limit = -1;\n static long curl_low_speed_time = -1;\n+#if LIBCURL_VERSION_NUM >= 0x070f05\n+static ssize_t curl_max_receive_speed = -1;\n+#endif\n static int curl_ftp_no_epsv;\n static const char *curl_http_proxy;\n static const char *http_proxy_authmethod;\n@@ -361,7 +364,12 @@ static int http_options(const char *var, const char *value, void *cb)\n \t\tcurl_low_speed_time = (long)git_config_int(var, value);\n \t\treturn 0;\n \t}\n-\n+#if LIBCURL_VERSION_NUM >= 0x070f05\n+\tif (!strcmp(\"http.maxreceivespeed\", var)) {\n+\t\tcurl_max_receive_speed = git_config_ssize_t(var, value);\n+\t\treturn 0;\n+\t}\n+#endif\n \tif (!strcmp(\"http.noepsv\", var)) {\n \t\tcurl_ftp_no_epsv = git_config_bool(var, value);\n \t\treturn 0;\n@@ -974,6 +982,12 @@ static CURL *get_curl_handle(void)\n \t\t\t\t curl_low_speed_time);\n \t}\n \n+#if LIBCURL_VERSION_NUM >= 0x070f05\n+\tif (curl_max_receive_speed > 0)\n+\t\tcurl_easy_setopt(result, CURLOPT_MAX_RECV_SPEED_LARGE,\n+\t\t\t\t curl_max_receive_speed);\n+#endif\n+\n \tcurl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);\n #if LIBCURL_VERSION_NUM >= 0x071301\n \tcurl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);\n@@ -1105,6 +1119,9 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n {\n \tchar *low_speed_limit;\n \tchar *low_speed_time;\n+#if LIBCURL_VERSION_NUM >= 0x070f05\n+\tchar *max_receive_speed;\n+#endif\n \tchar *normalized_url;\n \tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n \n@@ -1196,6 +1213,11 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n \tlow_speed_time = getenv(\"GIT_HTTP_LOW_SPEED_TIME\");\n \tif (low_speed_time != NULL)\n \t\tcurl_low_speed_time = strtol(low_speed_time, NULL, 10);\n+#if LIBCURL_VERSION_NUM >= 0x070f05\n+\tmax_receive_speed = getenv(\"GIT_HTTP_MAX_RECEIVE_SPEED\");\n+\tif (max_receive_speed && !git_parse_ssize_t(max_receive_speed, &curl_max_receive_speed))\n+\t\twarning(\"failed to parse GIT_HTTP_MAX_RECEIVE_SPEED: %s\", max_receive_speed);\n+#endif\n \n \tif (curl_ssl_verify == -1)\n \t\tcurl_ssl_verify = 1;\n-- \n2.28.1.49.gafcb914ae4.dirty.agit.6.3.1\n\n"},{"id":"433122","messageId":"a097e447-28e7-d991-ac99-ce1ffdb3ead4@gmail.com","threadId":"56323","inReplyTo":"20210819091433.348-1-chenan.xxw@alibaba-inc.com","subject":"Re: [PATCH] add http.maxReceiveSpeed to limit git-receive-pack receiving speed","fromName":"Bagas Sanjaya","fromEmail":"bagasdotme@gmail.com","sentAt":"2021-08-19T09:36:01Z","receivedAt":"2021-08-19T09:36:07Z","isPatch":true,"sender":{"key":"bagasdotme@gmail.com","avatar":"https://avatars.githubusercontent.com/u/40219486?v=4"},"body":"On 19/08/21 16.14, Xia XiaoWen wrote:\n> Sometimes need to limit the receive speed of git `clone/fetch`\n> because of the limited network bandwidth, otherwise will prevent\n> other applications from using the network normally.\n> \nI mean \"In some situations it is preferable to limit receiving speed of \ngit clone/fetch due to network bandwidth constraint, otherwise other \napplications performance will suffer from degraded network performance.\".\n\n> Add `http.maxReceiveSpeed` to limit `git-receive-pack` receiving\n> speed, Can be overridden by `GIT_HTTP_MAX_RECEIVE_SPEED` eivironment\n> variable.\n> \ns/eivironment/environment/\n\n> The default is unlimited, same if the value is 0 or negative. The\n> default unit is Bytes/s, common unit suffixes of k, m, or g are supported.\n> \n\nWouldn't it make sense for negative speed? Why don't just return error \nif negative speed is set?\n\n> this configuration is valid for `clone`, `fetch`, `pull` commands of the\n> https protocol, and only supports libcurl 7.15.5 and above.\n> ---\n>   http.c | 24 +++++++++++++++++++++++-\n>   1 file changed, 23 insertions(+), 1 deletion(-)\n> \n> diff --git a/http.c b/http.c\n> index 8119247149..12030cf3bc 100644\n> --- a/http.c\n> +++ b/http.c\n> @@ -83,6 +83,9 @@ static const char *ssl_pinnedkey;\n>   static const char *ssl_cainfo;\n>   static long curl_low_speed_limit = -1;\n>   static long curl_low_speed_time = -1;\n> +#if LIBCURL_VERSION_NUM >= 0x070f05\n> +static ssize_t curl_max_receive_speed = -1;\n> +#endif\n>   static int curl_ftp_no_epsv;\n>   static const char *curl_http_proxy;\n>   static const char *http_proxy_authmethod;\n> @@ -361,7 +364,12 @@ static int http_options(const char *var, const char *value, void *cb)\n>   \t\tcurl_low_speed_time = (long)git_config_int(var, value);\n>   \t\treturn 0;\n>   \t}\n> -\n> +#if LIBCURL_VERSION_NUM >= 0x070f05\n> +\tif (!strcmp(\"http.maxreceivespeed\", var)) {\n> +\t\tcurl_max_receive_speed = git_config_ssize_t(var, value);\n> +\t\treturn 0;\n> +\t}\n> +#endif\n>   \tif (!strcmp(\"http.noepsv\", var)) {\n>   \t\tcurl_ftp_no_epsv = git_config_bool(var, value);\n>   \t\treturn 0;\n> @@ -974,6 +982,12 @@ static CURL *get_curl_handle(void)\n>   \t\t\t\t curl_low_speed_time);\n>   \t}\n>   \n> +#if LIBCURL_VERSION_NUM >= 0x070f05\n> +\tif (curl_max_receive_speed > 0)\n> +\t\tcurl_easy_setopt(result, CURLOPT_MAX_RECV_SPEED_LARGE,\n> +\t\t\t\t curl_max_receive_speed);\n> +#endif\n> +\n>   \tcurl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);\n>   #if LIBCURL_VERSION_NUM >= 0x071301\n>   \tcurl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);\n> @@ -1105,6 +1119,9 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n>   {\n>   \tchar *low_speed_limit;\n>   \tchar *low_speed_time;\n> +#if LIBCURL_VERSION_NUM >= 0x070f05\n> +\tchar *max_receive_speed;\n> +#endif\n>   \tchar *normalized_url;\n>   \tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n>   \n> @@ -1196,6 +1213,11 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n>   \tlow_speed_time = getenv(\"GIT_HTTP_LOW_SPEED_TIME\");\n>   \tif (low_speed_time != NULL)\n>   \t\tcurl_low_speed_time = strtol(low_speed_time, NULL, 10);\n> +#if LIBCURL_VERSION_NUM >= 0x070f05\n> +\tmax_receive_speed = getenv(\"GIT_HTTP_MAX_RECEIVE_SPEED\");\n> +\tif (max_receive_speed && !git_parse_ssize_t(max_receive_speed, &curl_max_receive_speed))\n> +\t\twarning(\"failed to parse GIT_HTTP_MAX_RECEIVE_SPEED: %s\", max_receive_speed);\n> +#endif\n>   \n>   \tif (curl_ssl_verify == -1)\n>   \t\tcurl_ssl_verify = 1;\n> \n\nWhy is there boilerplate #if #endif block for libcurl 7.15.5?\n\n-- \nAn old man doll... just what I always wanted! - Clara\n"},{"id":"433128","messageId":"CAHLXgnZQmLiLbGnbC-nouE6tTJam5ZmdRmj=8E+tmM1pNLVFXw@mail.gmail.com","threadId":"56323","inReplyTo":"a097e447-28e7-d991-ac99-ce1ffdb3ead4@gmail.com","subject":"Re: [PATCH] add http.maxReceiveSpeed to limit git-receive-pack receiving speed","fromName":"Xiaowen Xia","fromEmail":"haoyurenzhuxia@gmail.com","sentAt":"2021-08-19T11:27:41Z","receivedAt":"2021-08-19T11:27:55Z","isPatch":true,"sender":{"key":"haoyurenzhuxia@gmail.com","avatar":null},"body":"> I mean \"In some situations it is preferable to limit receiving speed of\n> git clone/fetch due to network bandwidth constraint, otherwise other\n> applications performance will suffer from degraded network performance.\".\nThanks!\n\n> Wouldn't it make sense for negative speed? Why don't just return error\n> if negative speed is set?\nYou are right, negative speed doesn't make sense. but I prefer printf\na warning and continue work instead of returning an error, negative\nspeed seems not a fatal error.\n\n> Why is there boilerplate #if #endif block for libcurl 7.15.5?\nThe speed limit depends on the `CURLOPT_MAX_RECV_SPEED_LARGE` provided\nby libCURL, and libCURL added `CURLOPT_MAX_RECV_SPEED_LARGE` in\n7.15.5: https://curl.se/changes.html#7_15_5 .\n\nBagas Sanjaya <bagasdotme@gmail.com> 于2021年8月19日周四 下午5:36写道：\n>\n> On 19/08/21 16.14, Xia XiaoWen wrote:\n> > Sometimes need to limit the receive speed of git `clone/fetch`\n> > because of the limited network bandwidth, otherwise will prevent\n> > other applications from using the network normally.\n> >\n> I mean \"In some situations it is preferable to limit receiving speed of\n> git clone/fetch due to network bandwidth constraint, otherwise other\n> applications performance will suffer from degraded network performance.\".\n>\n> > Add `http.maxReceiveSpeed` to limit `git-receive-pack` receiving\n> > speed, Can be overridden by `GIT_HTTP_MAX_RECEIVE_SPEED` eivironment\n> > variable.\n> >\n> s/eivironment/environment/\n>\n> > The default is unlimited, same if the value is 0 or negative. The\n> > default unit is Bytes/s, common unit suffixes of k, m, or g are supported.\n> >\n>\n> Wouldn't it make sense for negative speed? Why don't just return error\n> if negative speed is set?\n>\n> > this configuration is valid for `clone`, `fetch`, `pull` commands of the\n> > https protocol, and only supports libcurl 7.15.5 and above.\n> > ---\n> >   http.c | 24 +++++++++++++++++++++++-\n> >   1 file changed, 23 insertions(+), 1 deletion(-)\n> >\n> > diff --git a/http.c b/http.c\n> > index 8119247149..12030cf3bc 100644\n> > --- a/http.c\n> > +++ b/http.c\n> > @@ -83,6 +83,9 @@ static const char *ssl_pinnedkey;\n> >   static const char *ssl_cainfo;\n> >   static long curl_low_speed_limit = -1;\n> >   static long curl_low_speed_time = -1;\n> > +#if LIBCURL_VERSION_NUM >= 0x070f05\n> > +static ssize_t curl_max_receive_speed = -1;\n> > +#endif\n> >   static int curl_ftp_no_epsv;\n> >   static const char *curl_http_proxy;\n> >   static const char *http_proxy_authmethod;\n> > @@ -361,7 +364,12 @@ static int http_options(const char *var, const char *value, void *cb)\n> >               curl_low_speed_time = (long)git_config_int(var, value);\n> >               return 0;\n> >       }\n> > -\n> > +#if LIBCURL_VERSION_NUM >= 0x070f05\n> > +     if (!strcmp(\"http.maxreceivespeed\", var)) {\n> > +             curl_max_receive_speed = git_config_ssize_t(var, value);\n> > +             return 0;\n> > +     }\n> > +#endif\n> >       if (!strcmp(\"http.noepsv\", var)) {\n> >               curl_ftp_no_epsv = git_config_bool(var, value);\n> >               return 0;\n> > @@ -974,6 +982,12 @@ static CURL *get_curl_handle(void)\n> >                                curl_low_speed_time);\n> >       }\n> >\n> > +#if LIBCURL_VERSION_NUM >= 0x070f05\n> > +     if (curl_max_receive_speed > 0)\n> > +             curl_easy_setopt(result, CURLOPT_MAX_RECV_SPEED_LARGE,\n> > +                              curl_max_receive_speed);\n> > +#endif\n> > +\n> >       curl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);\n> >   #if LIBCURL_VERSION_NUM >= 0x071301\n> >       curl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);\n> > @@ -1105,6 +1119,9 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n> >   {\n> >       char *low_speed_limit;\n> >       char *low_speed_time;\n> > +#if LIBCURL_VERSION_NUM >= 0x070f05\n> > +     char *max_receive_speed;\n> > +#endif\n> >       char *normalized_url;\n> >       struct urlmatch_config config = { STRING_LIST_INIT_DUP };\n> >\n> > @@ -1196,6 +1213,11 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n> >       low_speed_time = getenv(\"GIT_HTTP_LOW_SPEED_TIME\");\n> >       if (low_speed_time != NULL)\n> >               curl_low_speed_time = strtol(low_speed_time, NULL, 10);\n> > +#if LIBCURL_VERSION_NUM >= 0x070f05\n> > +     max_receive_speed = getenv(\"GIT_HTTP_MAX_RECEIVE_SPEED\");\n> > +     if (max_receive_speed && !git_parse_ssize_t(max_receive_speed, &curl_max_receive_speed))\n> > +             warning(\"failed to parse GIT_HTTP_MAX_RECEIVE_SPEED: %s\", max_receive_speed);\n> > +#endif\n> >\n> >       if (curl_ssl_verify == -1)\n> >               curl_ssl_verify = 1;\n> >\n>\n> Why is there boilerplate #if #endif block for libcurl 7.15.5?\n>\n> --\n> An old man doll... just what I always wanted! - Clara\n"},{"id":"433146","messageId":"xmqq4kbl2sre.fsf@gitster.g","threadId":"56323","inReplyTo":"20210819091433.348-1-chenan.xxw@alibaba-inc.com","subject":"Re: [PATCH] add http.maxReceiveSpeed to limit git-receive-pack receiving speed","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-08-19T18:28:53Z","receivedAt":"2021-08-19T18:28:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Xia XiaoWen <haoyurenzhuxia@gmail.com> writes:\n\n> Sometimes need to limit the receive speed of git `clone/fetch`\n> because of the limited network bandwidth, otherwise will prevent\n> other applications from using the network normally.\n\nNo subject in these two half-sentences.\n\n    In order to avoid hogging all the available bandwidth, users may\n    want to limit the speed to receive traffic for \"git clone\" or\n    \"git fetch\".\n\nperhaps.\n\n> Add `http.maxReceiveSpeed` to limit `git-receive-pack` receiving\n\n\"limit `git-receive-pack`'s\" or \"limit receiving speedk of ...\"\n\n> speed, Can be overridden by `GIT_HTTP_MAX_RECEIVE_SPEED` eivironment\n> variable.\n>\n> The default is unlimited, same if the value is 0 or negative. The\n\nLet's error it out when the configuration gives a value that does\nnot make sense instead.  That way, we could in the future use some\nof these invalid values to signal special behaviour if we wanted to.\n\n> default unit is Bytes/s, common unit suffixes of k, m, or g are supported.\n\nOK.\n\n> this configuration is valid for `clone`, `fetch`, `pull` commands of the\n\ns/this/This/\n\n> https protocol, and only supports libcurl 7.15.5 and above.\n\nWe are likely be raising the floor versions of libcURL to 7.16.0 or\neven 7.19.4 soonish.  It probably would make it easier to allow it\nunconditionally (otherwise you'd probably need to implement error or\nwarning messages when configuration is given but the libcURL version\nused is too old, etc.).\n\n> ---\n>  http.c | 24 +++++++++++++++++++++++-\n>  1 file changed, 23 insertions(+), 1 deletion(-)\n>\n> diff --git a/http.c b/http.c\n> index 8119247149..12030cf3bc 100644\n> --- a/http.c\n> +++ b/http.c\n> @@ -83,6 +83,9 @@ static const char *ssl_pinnedkey;\n>  static const char *ssl_cainfo;\n>  static long curl_low_speed_limit = -1;\n>  static long curl_low_speed_time = -1;\n> +#if LIBCURL_VERSION_NUM >= 0x070f05\n> +static ssize_t curl_max_receive_speed = -1;\n\nOn cURL side, CURLOPT_MAX_RECV_SPEED_LARGE takes curl_off_t, which\nis typically off_t (which is signed).\n\nI wonder if ssize_t is overkill for our purpose, though.  Can't this\nbe a plain vanilla \"int\" or perhaps \"long\", just like the variable\ndefined above uses \"long\" for \"speed\"?  Or is 2gb/s too low to be\npractical and we must use a 64-bit type?\n\n> +#endif\n>  static int curl_ftp_no_epsv;\n>  static const char *curl_http_proxy;\n>  static const char *http_proxy_authmethod;\n> @@ -361,7 +364,12 @@ static int http_options(const char *var, const char *value, void *cb)\n>  \t\tcurl_low_speed_time = (long)git_config_int(var, value);\n>  \t\treturn 0;\n>  \t}\n> -\n> +#if LIBCURL_VERSION_NUM >= 0x070f05\n> +\tif (!strcmp(\"http.maxreceivespeed\", var)) {\n> +\t\tcurl_max_receive_speed = git_config_ssize_t(var, value);\n\nCheck for nonsense values, so that we can later use them to mean\nsomething special.  It is good to remember is that you can always\nloosen the rules after you give your software to your users, but it\nis very hard to tighten the rules.  As you never need more than one\nway to specify \"the default\" (aka \"unlimited\"), reserving any\nnon-positive value to mean the default is a design that is\nextensible poorly.\n\nI.e. insert something like\n\n\t\tif (curl_max_receive_speed < 0)\n\t\t\tdie(\"negatigve number for %s: %s\", var, value);\n\nhere.\n\n> +\t\treturn 0;\n> +\t}\n> +#endif\n>  \tif (!strcmp(\"http.noepsv\", var)) {\n>  \t\tcurl_ftp_no_epsv = git_config_bool(var, value);\n>  \t\treturn 0;\n> @@ -974,6 +982,12 @@ static CURL *get_curl_handle(void)\n>  \t\t\t\t curl_low_speed_time);\n>  \t}\n>  \n> +#if LIBCURL_VERSION_NUM >= 0x070f05\n> +\tif (curl_max_receive_speed > 0)\n\nThe \"result\" handle was created anew in this function, so the\ndistinction does not really matter in practrice, but since you are\ncarefully initializing the variable to \"-1\" so that we can\ndifferentiate the case where it is unconfigured (hence we want to\nuse the default) and it is set to zero (hence we want to use the\ndefault), it would be more consistent and future-proof if you also\nallowed 0 to be passed here, i.e.\n\n\tif (curl_max_receive_speed >= 0)\n\n> +\t\tcurl_easy_setopt(result, CURLOPT_MAX_RECV_SPEED_LARGE,\n> +\t\t\t\t curl_max_receive_speed);\n\nThis call, if you use anything but curl_off_t as the type for\ncurl_max_receive_speed variable where it is declared, needs a cast,\nlike in the example https://curl.se/libcurl/c/CURLOPT_MAX_RECV_SPEED_LARGE.html\n\n> +#endif\n> +\n>  \tcurl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);\n>  #if LIBCURL_VERSION_NUM >= 0x071301\n>  \tcurl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);\n> @@ -1105,6 +1119,9 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n>  {\n>  \tchar *low_speed_limit;\n>  \tchar *low_speed_time;\n> +#if LIBCURL_VERSION_NUM >= 0x070f05\n> +\tchar *max_receive_speed;\n> +#endif\n>  \tchar *normalized_url;\n>  \tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n>  \n> @@ -1196,6 +1213,11 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n>  \tlow_speed_time = getenv(\"GIT_HTTP_LOW_SPEED_TIME\");\n>  \tif (low_speed_time != NULL)\n>  \t\tcurl_low_speed_time = strtol(low_speed_time, NULL, 10);\n> +#if LIBCURL_VERSION_NUM >= 0x070f05\n> +\tmax_receive_speed = getenv(\"GIT_HTTP_MAX_RECEIVE_SPEED\");\n> +\tif (max_receive_speed && !git_parse_ssize_t(max_receive_speed, &curl_max_receive_speed))\n\nOverlong line.\n\nUnlike curl_max_receive_speed that must be visible and\nunderstandable long haul in this file, the temporary string variable\nlives only during these handful of lines and shortened name is\neasier to see and understand what is going on.  Also, you can avoid\nrepeated spelling out of the environment variable name by giving a\nconstant for it near the top of this function, e.g.\n\n\tstatic const char mrs_env[] = \"GIT_HTTP_MAX_RECEIVE_SPEED\";\n\nThen this part would become:\n\n\tif (mrs) {\n\t\tif (!git_parse_ssize_t(mrs, &curl_max_receive_speed))\n\t\t\tdie(_(\"invalid number for %s: %s\", mrs_env, mrs);\n\t\tif (curl_max_receive_speed < 0)\n\t\t\tdie(_(\"negative number for %s: %s\", mrs_env, mrs);\n\t}\n\n> +\t\twarning(\"failed to parse GIT_HTTP_MAX_RECEIVE_SPEED: %s\", max_receive_speed);\n\n\nThanks.\n"},{"id":"433265","messageId":"YR/wbWhei0PPLSgX@coredump.intra.peff.net","threadId":"56323","inReplyTo":"xmqq4kbl2sre.fsf@gitster.g","subject":"Re: [PATCH] add http.maxReceiveSpeed to limit git-receive-pack receiving speed","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2021-08-20T18:11:57Z","receivedAt":"2021-08-20T18:11:59Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Aug 19, 2021 at 11:28:53AM -0700, Junio C Hamano wrote:\n\n> > https protocol, and only supports libcurl 7.15.5 and above.\n> \n> We are likely be raising the floor versions of libcURL to 7.16.0 or\n> even 7.19.4 soonish.  It probably would make it easier to allow it\n> unconditionally (otherwise you'd probably need to implement error or\n> warning messages when configuration is given but the libcURL version\n> used is too old, etc.).\n\nYeah, I agree that if we can drop the conditional totally, we should.\n\nIf we do need to make it conditional, I think there was a preference for\nshifting to checking the actual option constants, like:\n\n  #ifdef CURLOPT_MAX_RECV_SPEED_LARGE\n  ...ok, we have it...\n  #endif\n\nThe rest of your comments all seemed quite reasonable to me.\n\nAs a general feature, IMHO speed-limiting is best done outside of\napplication-level tools like Git (and instead done via proxies or kernel\nnetwork config). But since we are not building the feature ourselves,\nbut rather just plugging our config to curl's feature, I don't have any\nproblem with it here.\n\n-Peff\n"},{"id":"433267","messageId":"018c01d795f0$350a5c00$9f1f1400$@nexbridge.com","threadId":"56323","inReplyTo":"YR/wbWhei0PPLSgX@coredump.intra.peff.net","subject":"RE: [PATCH] add http.maxReceiveSpeed to limit git-receive-pack receiving speed","fromName":"Randall S. Becker","fromEmail":"rsbecker@nexbridge.com","sentAt":"2021-08-20T18:21:28Z","receivedAt":"2021-08-20T18:22:48Z","isPatch":true,"sender":{"key":"randall.becker@nexbridge.ca","avatar":"https://avatars.githubusercontent.com/u/28956764?v=4"},"body":"On August 20, 2021 2:12 PM, Jeff King wrote:\n>On Thu, Aug 19, 2021 at 11:28:53AM -0700, Junio C Hamano wrote:\n>\n>> > https protocol, and only supports libcurl 7.15.5 and above.\n>>\n>> We are likely be raising the floor versions of libcURL to 7.16.0 or\n>> even 7.19.4 soonish.  It probably would make it easier to allow it\n>> unconditionally (otherwise you'd probably need to implement error or\n>> warning messages when configuration is given but the libcURL version\n>> used is too old, etc.).\n>\n>Yeah, I agree that if we can drop the conditional totally, we should.\n>\n>If we do need to make it conditional, I think there was a preference for shifting to checking the actual option constants, like:\n>\n>  #ifdef CURLOPT_MAX_RECV_SPEED_LARGE\n>  ...ok, we have it...\n>  #endif\n>\n>The rest of your comments all seemed quite reasonable to me.\n>\n>As a general feature, IMHO speed-limiting is best done outside of application-level tools like Git (and instead done via proxies or kernel\n>network config). But since we are not building the feature ourselves, but rather just plugging our config to curl's feature, I don't have any\n>problem with it here.\n\nI second that. This should be in the realm of QoS at a managed switch/router in the consumer's network (or the upstream repo in some cases).\n-Randall\n\n"},{"id":"433299","messageId":"CAHLXgnYsQcfgddNHdH+geoczq8isgLaf-b3oLzjNS+m96N5ESg@mail.gmail.com","threadId":"56323","inReplyTo":"xmqq4kbl2sre.fsf@gitster.g","subject":"Re: [PATCH] add http.maxReceiveSpeed to limit git-receive-pack receiving speed","fromName":"Xiaowen Xia","fromEmail":"haoyurenzhuxia@gmail.com","sentAt":"2021-08-21T03:19:00Z","receivedAt":"2021-08-21T03:19:14Z","isPatch":true,"sender":{"key":"haoyurenzhuxia@gmail.com","avatar":null},"body":"Hi Junio:\n\nThank You so much for your reply!!\n\n> > The default is unlimited, same if the value is 0 or negative.\n> Let's error it out when the configuration gives a value that does\n> not make sense instead. That way, we could in the future use some\n> of these invalid values to signal special behaviour if we wanted to.\nBut this patch is similar to the `http.lowspeedlimit` and `http.lowspeedtime`.\nAnd `http.lowspeedlimit` will not error out the negative values:\n\n        if (curl_low_speed_limit > 0 && curl_low_speed_time > 0) {\n            curl_easy_setopt(result, CURLOPT_LOW_SPEED_LIMIT,\n                 curl_low_speed_limit);\n            curl_easy_setopt(result, CURLOPT_LOW_SPEED_TIME,\n                 curl_low_speed_time);\n        }\n\n> We are likely be raising the floor versions of libcURL to 7.16.0 or\n> even 7.19.4 soonish.\nOK, I will remove the #if #endif block for libcurl 7.15.5.\n\n> Let's error it out when the configuration gives a value that does\n> not make sense instead.\nThe same as above.\n\n> I wonder if ssize_t is overkill for our purpose, though.\nYou are right, I will change it to long type.\n\n> This call, if you use anything but curl_off_t as the type for\n> curl_max_receive_speed variable where it is declared, needs a cast,\nYou are right.\n\n> Unlike curl_max_receive_speed that must be visible and\n> understandable long haul in this file, the temporary string variable\n> lives only during these handful of lines and shortened name is\n> easier to see and understand what is going on.\nOK.\n\n\nJunio C Hamano <gitster@pobox.com> 于2021年8月20日周五 上午2:28写道：\n>\n> Xia XiaoWen <haoyurenzhuxia@gmail.com> writes:\n>\n> > Sometimes need to limit the receive speed of git `clone/fetch`\n> > because of the limited network bandwidth, otherwise will prevent\n> > other applications from using the network normally.\n>\n> No subject in these two half-sentences.\n>\n>     In order to avoid hogging all the available bandwidth, users may\n>     want to limit the speed to receive traffic for \"git clone\" or\n>     \"git fetch\".\n>\n> perhaps.\n>\n> > Add `http.maxReceiveSpeed` to limit `git-receive-pack` receiving\n>\n> \"limit `git-receive-pack`'s\" or \"limit receiving speedk of ...\"\n>\n> > speed, Can be overridden by `GIT_HTTP_MAX_RECEIVE_SPEED` eivironment\n> > variable.\n> >\n> > The default is unlimited, same if the value is 0 or negative. The\n>\n> Let's error it out when the configuration gives a value that does\n> not make sense instead.  That way, we could in the future use some\n> of these invalid values to signal special behaviour if we wanted to.\n>\n> > default unit is Bytes/s, common unit suffixes of k, m, or g are supported.\n>\n> OK.\n>\n> > this configuration is valid for `clone`, `fetch`, `pull` commands of the\n>\n> s/this/This/\n>\n> > https protocol, and only supports libcurl 7.15.5 and above.\n>\n> We are likely be raising the floor versions of libcURL to 7.16.0 or\n> even 7.19.4 soonish.  It probably would make it easier to allow it\n> unconditionally (otherwise you'd probably need to implement error or\n> warning messages when configuration is given but the libcURL version\n> used is too old, etc.).\n>\n> > ---\n> >  http.c | 24 +++++++++++++++++++++++-\n> >  1 file changed, 23 insertions(+), 1 deletion(-)\n> >\n> > diff --git a/http.c b/http.c\n> > index 8119247149..12030cf3bc 100644\n> > --- a/http.c\n> > +++ b/http.c\n> > @@ -83,6 +83,9 @@ static const char *ssl_pinnedkey;\n> >  static const char *ssl_cainfo;\n> >  static long curl_low_speed_limit = -1;\n> >  static long curl_low_speed_time = -1;\n> > +#if LIBCURL_VERSION_NUM >= 0x070f05\n> > +static ssize_t curl_max_receive_speed = -1;\n>\n> On cURL side, CURLOPT_MAX_RECV_SPEED_LARGE takes curl_off_t, which\n> is typically off_t (which is signed).\n>\n> I wonder if ssize_t is overkill for our purpose, though.  Can't this\n> be a plain vanilla \"int\" or perhaps \"long\", just like the variable\n> defined above uses \"long\" for \"speed\"?  Or is 2gb/s too low to be\n> practical and we must use a 64-bit type?\n>\n> > +#endif\n> >  static int curl_ftp_no_epsv;\n> >  static const char *curl_http_proxy;\n> >  static const char *http_proxy_authmethod;\n> > @@ -361,7 +364,12 @@ static int http_options(const char *var, const char *value, void *cb)\n> >               curl_low_speed_time = (long)git_config_int(var, value);\n> >               return 0;\n> >       }\n> > -\n> > +#if LIBCURL_VERSION_NUM >= 0x070f05\n> > +     if (!strcmp(\"http.maxreceivespeed\", var)) {\n> > +             curl_max_receive_speed = git_config_ssize_t(var, value);\n>\n> Check for nonsense values, so that we can later use them to mean\n> something special.  It is good to remember is that you can always\n> loosen the rules after you give your software to your users, but it\n> is very hard to tighten the rules.  As you never need more than one\n> way to specify \"the default\" (aka \"unlimited\"), reserving any\n> non-positive value to mean the default is a design that is\n> extensible poorly.\n>\n> I.e. insert something like\n>\n>                 if (curl_max_receive_speed < 0)\n>                         die(\"negatigve number for %s: %s\", var, value);\n>\n> here.\n>\n> > +             return 0;\n> > +     }\n> > +#endif\n> >       if (!strcmp(\"http.noepsv\", var)) {\n> >               curl_ftp_no_epsv = git_config_bool(var, value);\n> >               return 0;\n> > @@ -974,6 +982,12 @@ static CURL *get_curl_handle(void)\n> >                                curl_low_speed_time);\n> >       }\n> >\n> > +#if LIBCURL_VERSION_NUM >= 0x070f05\n> > +     if (curl_max_receive_speed > 0)\n>\n> The \"result\" handle was created anew in this function, so the\n> distinction does not really matter in practrice, but since you are\n> carefully initializing the variable to \"-1\" so that we can\n> differentiate the case where it is unconfigured (hence we want to\n> use the default) and it is set to zero (hence we want to use the\n> default), it would be more consistent and future-proof if you also\n> allowed 0 to be passed here, i.e.\n>\n>         if (curl_max_receive_speed >= 0)\n>\n> > +             curl_easy_setopt(result, CURLOPT_MAX_RECV_SPEED_LARGE,\n> > +                              curl_max_receive_speed);\n>\n> This call, if you use anything but curl_off_t as the type for\n> curl_max_receive_speed variable where it is declared, needs a cast,\n> like in the example https://curl.se/libcurl/c/CURLOPT_MAX_RECV_SPEED_LARGE.html\n>\n> > +#endif\n> > +\n> >       curl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);\n> >  #if LIBCURL_VERSION_NUM >= 0x071301\n> >       curl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);\n> > @@ -1105,6 +1119,9 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n> >  {\n> >       char *low_speed_limit;\n> >       char *low_speed_time;\n> > +#if LIBCURL_VERSION_NUM >= 0x070f05\n> > +     char *max_receive_speed;\n> > +#endif\n> >       char *normalized_url;\n> >       struct urlmatch_config config = { STRING_LIST_INIT_DUP };\n> >\n> > @@ -1196,6 +1213,11 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n> >       low_speed_time = getenv(\"GIT_HTTP_LOW_SPEED_TIME\");\n> >       if (low_speed_time != NULL)\n> >               curl_low_speed_time = strtol(low_speed_time, NULL, 10);\n> > +#if LIBCURL_VERSION_NUM >= 0x070f05\n> > +     max_receive_speed = getenv(\"GIT_HTTP_MAX_RECEIVE_SPEED\");\n> > +     if (max_receive_speed && !git_parse_ssize_t(max_receive_speed, &curl_max_receive_speed))\n>\n> Overlong line.\n>\n> Unlike curl_max_receive_speed that must be visible and\n> understandable long haul in this file, the temporary string variable\n> lives only during these handful of lines and shortened name is\n> easier to see and understand what is going on.  Also, you can avoid\n> repeated spelling out of the environment variable name by giving a\n> constant for it near the top of this function, e.g.\n>\n>         static const char mrs_env[] = \"GIT_HTTP_MAX_RECEIVE_SPEED\";\n>\n> Then this part would become:\n>\n>         if (mrs) {\n>                 if (!git_parse_ssize_t(mrs, &curl_max_receive_speed))\n>                         die(_(\"invalid number for %s: %s\", mrs_env, mrs);\n>                 if (curl_max_receive_speed < 0)\n>                         die(_(\"negative number for %s: %s\", mrs_env, mrs);\n>         }\n>\n> > +             warning(\"failed to parse GIT_HTTP_MAX_RECEIVE_SPEED: %s\", max_receive_speed);\n>\n>\n> Thanks.\n"},{"id":"433302","messageId":"xmqqsfz3sa0m.fsf@gitster.g","threadId":"56323","inReplyTo":"CAHLXgnYsQcfgddNHdH+geoczq8isgLaf-b3oLzjNS+m96N5ESg@mail.gmail.com","subject":"Re: [PATCH] add http.maxReceiveSpeed to limit git-receive-pack receiving speed","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-08-21T04:21:29Z","receivedAt":"2021-08-21T04:21:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Xiaowen Xia <haoyurenzhuxia@gmail.com> writes:\n\n> But this patch is similar to the `http.lowspeedlimit` and `http.lowspeedtime`.\n> And `http.lowspeedlimit` will not error out the negative values:\n\nAn earlier mistake by others does not make it OK to make the same\nmistake knowingly, though.\n\n"},{"id":"433303","messageId":"CAHLXgnYZ9Ae2+3oRxwMVtyCFAq68OCH-AcV41MxAfUzd2_GFKQ@mail.gmail.com","threadId":"56323","inReplyTo":"xmqqsfz3sa0m.fsf@gitster.g","subject":"Re: [PATCH] add http.maxReceiveSpeed to limit git-receive-pack receiving speed","fromName":"Xiaowen Xia","fromEmail":"haoyurenzhuxia@gmail.com","sentAt":"2021-08-21T05:16:18Z","receivedAt":"2021-08-21T05:16:32Z","isPatch":true,"sender":{"key":"haoyurenzhuxia@gmail.com","avatar":null},"body":"Got it.\n\nJunio C Hamano <gitster@pobox.com> 于2021年8月21日周六 下午12:21写道：\n>\n> Xiaowen Xia <haoyurenzhuxia@gmail.com> writes:\n>\n> > But this patch is similar to the `http.lowspeedlimit` and `http.lowspeedtime`.\n> > And `http.lowspeedlimit` will not error out the negative values:\n>\n> An earlier mistake by others does not make it OK to make the same\n> mistake knowingly, though.\n>\n"},{"id":"433451","messageId":"20210823160455.32397-1-chenan.xxw@alibaba-inc.com","threadId":"56323","inReplyTo":"20210819091433.348-1-chenan.xxw@alibaba-inc.com","subject":"[PATCH v2] http: add http.maxReceiveSpeed to limit receiving speed of \"git-receive-pack\"","fromName":"chenan.xxw","fromEmail":"haoyurenzhuxia@gmail.com","sentAt":"2021-08-23T16:04:55Z","receivedAt":"2021-08-23T16:05:20Z","isPatch":true,"sender":{"key":"haoyurenzhuxia@gmail.com","avatar":null},"body":"In order to avoid hogging all the available network bandwidth, users may want to\nlimit the speed of receiving traffic for \"git clone\" or \"git fetch\".\n\nAdd `http.maxReceiveSpeed` to limit receiving speed of `git-receive-pack`.\nCan be overridden by `GIT_HTTP_MAX_RECEIVE_SPEED` environment variable.\n\nThe default is unlimited, same if the value is 0. The default unit is Bytes/s,\ncommon unit suffixes of k, m, or g are supported.\n\nThis configuration is valid for `clone`, `fetch`, `pull` commands of the https\nprotocol.\n\nSigned-off-by: chenan.xxw <chenan.xxw@alibaba-inc.com>\n---\n Documentation/config/http.txt |  4 ++++\n http.c                        | 21 +++++++++++++++++++++\n 2 files changed, 25 insertions(+)\n\ndiff --git a/Documentation/config/http.txt b/Documentation/config/http.txt\nindex 7003661c0d..9b9fb5e9c7 100644\n--- a/Documentation/config/http.txt\n+++ b/Documentation/config/http.txt\n@@ -235,6 +235,10 @@ http.lowSpeedLimit, http.lowSpeedTime::\n \tCan be overridden by the `GIT_HTTP_LOW_SPEED_LIMIT` and\n \t`GIT_HTTP_LOW_SPEED_TIME` environment variables.\n \n+http.maxReceiveSpeed::\n+\tLimit the speed of receiving traffic, defaults to unlimited. Can be\n+\toverridden by the `GIT_HTTP_MAX_RECEIVE_SPEED` environment variable.\n+\n http.noEPSV::\n \tA boolean which disables using of EPSV ftp command by curl.\n \tThis can helpful with some \"poor\" ftp servers which don't\ndiff --git a/http.c b/http.c\nindex 8119247149..b12d192ffe 100644\n--- a/http.c\n+++ b/http.c\n@@ -83,6 +83,7 @@ static const char *ssl_pinnedkey;\n static const char *ssl_cainfo;\n static long curl_low_speed_limit = -1;\n static long curl_low_speed_time = -1;\n+static long curl_max_receive_speed;\n static int curl_ftp_no_epsv;\n static const char *curl_http_proxy;\n static const char *http_proxy_authmethod;\n@@ -362,6 +363,13 @@ static int http_options(const char *var, const char *value, void *cb)\n \t\treturn 0;\n \t}\n \n+\tif (!strcmp(\"http.maxreceivespeed\", var)) {\n+\t\tcurl_max_receive_speed = (long)git_config_int(var, value);\n+\t\tif (curl_max_receive_speed < 0)\n+\t\t\tdie(_(\"negative values are not allowed for http.maxreceivespeed\"));\n+\t\treturn 0;\n+\t}\n+\n \tif (!strcmp(\"http.noepsv\", var)) {\n \t\tcurl_ftp_no_epsv = git_config_bool(var, value);\n \t\treturn 0;\n@@ -974,6 +982,10 @@ static CURL *get_curl_handle(void)\n \t\t\t\t curl_low_speed_time);\n \t}\n \n+\tif (curl_max_receive_speed >= 0)\n+\t\tcurl_easy_setopt(result, CURLOPT_MAX_RECV_SPEED_LARGE,\n+\t\t\t\t (curl_off_t)curl_max_receive_speed);\n+\n \tcurl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);\n #if LIBCURL_VERSION_NUM >= 0x071301\n \tcurl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);\n@@ -1105,6 +1117,8 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n {\n \tchar *low_speed_limit;\n \tchar *low_speed_time;\n+\tchar *mrs;\n+\tstatic const char mrs_env[] = \"GIT_HTTP_MAX_RECEIVE_SPEED\";\n \tchar *normalized_url;\n \tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n \n@@ -1197,6 +1211,13 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n \tif (low_speed_time != NULL)\n \t\tcurl_low_speed_time = strtol(low_speed_time, NULL, 10);\n \n+\tmrs = getenv(mrs_env);\n+\tif (mrs != NULL) {\n+\t\tcurl_max_receive_speed = strtol(mrs, NULL, 10);\n+\t\tif (curl_max_receive_speed < 0)\n+\t\t\tdie(_(\"negative values are not allowed for %s\"), mrs_env);\n+\t}\n+\n \tif (curl_ssl_verify == -1)\n \t\tcurl_ssl_verify = 1;\n \n-- \n2.33.0.1.g26e5a845c1.dirty\n\n"},{"id":"433505","messageId":"CANYiYbEL2T897jMZFg_F-AgomrEj3EcEC2ZTyBZMB550k_PPbQ@mail.gmail.com","threadId":"56323","inReplyTo":"20210823160455.32397-1-chenan.xxw@alibaba-inc.com","subject":"Re: [PATCH v2] http: add http.maxReceiveSpeed to limit receiving speed of \"git-receive-pack\"","fromName":"Jiang Xin","fromEmail":"worldhello.net@gmail.com","sentAt":"2021-08-24T00:31:42Z","receivedAt":"2021-08-24T00:31:56Z","isPatch":true,"sender":{"key":"worldhello.net@gmail.com","avatar":"https://avatars.githubusercontent.com/u/183860?v=4"},"body":"On Tue, Aug 24, 2021 at 12:05 AM chenan.xxw <haoyurenzhuxia@gmail.com> wrote:\n>\n> In order to avoid hogging all the available network bandwidth, users may want to\n> limit the speed of receiving traffic for \"git clone\" or \"git fetch\".\n>\n> Add `http.maxReceiveSpeed` to limit receiving speed of `git-receive-pack`.\n> Can be overridden by `GIT_HTTP_MAX_RECEIVE_SPEED` environment variable.\n>\n> The default is unlimited, same if the value is 0. The default unit is Bytes/s,\n> common unit suffixes of k, m, or g are supported.\n>\n> This configuration is valid for `clone`, `fetch`, `pull` commands of the https\n> protocol.\n>\n> Signed-off-by: chenan.xxw <chenan.xxw@alibaba-inc.com>\n\nYour email address in the s-o-b is different from the \"From\" header.\nThat will generate a commit with a different author email. This is\nbecause you use gmail as the SMTP, but the value of \"user.email\"\nconfig variable is not a valid alias email of Gmail. A workaround is\nuse a different \"user.email\" config for git-send-email, and\ngit-send-email will add a \"From: your <real@email>\" as the first line\nof the body. E.g.:\n\n    git -c user.email=\"haoyurenzhuxia@gmail.com\" send-email <patch-file>\n\nBTW, use your real username (Xia Xiaowen) instead of the nickname \"chenan.xxw\".\n\n    git config --global user.name \"Xia Xiaowen\"\n    git commit --reset-author --amend\n\n\n> ---\n>  Documentation/config/http.txt |  4 ++++\n>  http.c                        | 21 +++++++++++++++++++++\n>  2 files changed, 25 insertions(+)\n>\n> diff --git a/Documentation/config/http.txt b/Documentation/config/http.txt\n> index 7003661c0d..9b9fb5e9c7 100644\n> --- a/Documentation/config/http.txt\n> +++ b/Documentation/config/http.txt\n> @@ -235,6 +235,10 @@ http.lowSpeedLimit, http.lowSpeedTime::\n>         Can be overridden by the `GIT_HTTP_LOW_SPEED_LIMIT` and\n>         `GIT_HTTP_LOW_SPEED_TIME` environment variables.\n>\n> +http.maxReceiveSpeed::\n> +       Limit the speed of receiving traffic, defaults to unlimited. Can be\n> +       overridden by the `GIT_HTTP_MAX_RECEIVE_SPEED` environment variable.\n> +\n>  http.noEPSV::\n>         A boolean which disables using of EPSV ftp command by curl.\n>         This can helpful with some \"poor\" ftp servers which don't\n> diff --git a/http.c b/http.c\n> index 8119247149..b12d192ffe 100644\n> --- a/http.c\n> +++ b/http.c\n> @@ -83,6 +83,7 @@ static const char *ssl_pinnedkey;\n>  static const char *ssl_cainfo;\n>  static long curl_low_speed_limit = -1;\n>  static long curl_low_speed_time = -1;\n> +static long curl_max_receive_speed;\n\nYou can set default value -1 for curl_max_receive_speed, just like\ncurl_low_speed_limit does.\nI wonder if you can rename the variable name to curl_max_speed_limit\nfor both upload and download.\n\n>  static int curl_ftp_no_epsv;\n>  static const char *curl_http_proxy;\n>  static const char *http_proxy_authmethod;\n> @@ -362,6 +363,13 @@ static int http_options(const char *var, const char *value, void *cb)\n>                 return 0;\n>         }\n>\n> +       if (!strcmp(\"http.maxreceivespeed\", var)) {\n\nCan we use a better name, such as \"http.maxspeedlimit\" ?  And make\nsome changes to limit both upload and download over HTTP protocol.\n\n> +               curl_max_receive_speed = (long)git_config_int(var, value);\n> +               if (curl_max_receive_speed < 0)\n> +                       die(_(\"negative values are not allowed for http.maxreceivespeed\"));\n> +               return 0;\n> +       }\n> +\n>         if (!strcmp(\"http.noepsv\", var)) {\n>                 curl_ftp_no_epsv = git_config_bool(var, value);\n>                 return 0;\n> @@ -974,6 +982,10 @@ static CURL *get_curl_handle(void)\n>                                  curl_low_speed_time);\n>         }\n>\n> +       if (curl_max_receive_speed >= 0)\n> +               curl_easy_setopt(result, CURLOPT_MAX_RECV_SPEED_LARGE,\n> +                                (curl_off_t)curl_max_receive_speed);\n> +\n\nYou can also set \"CURLOPT_MAX_SEND_SPEED_LARGE\" to limit bandwidth for git-push.\n\n>         curl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);\n>  #if LIBCURL_VERSION_NUM >= 0x071301\n>         curl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);\n> @@ -1105,6 +1117,8 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n>  {\n>         char *low_speed_limit;\n>         char *low_speed_time;\n> +       char *mrs;\n> +       static const char mrs_env[] = \"GIT_HTTP_MAX_RECEIVE_SPEED\";\n>         char *normalized_url;\n>         struct urlmatch_config config = { STRING_LIST_INIT_DUP };\n>\n> @@ -1197,6 +1211,13 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n>         if (low_speed_time != NULL)\n>                 curl_low_speed_time = strtol(low_speed_time, NULL, 10);\n>\n> +       mrs = getenv(mrs_env);\n> +       if (mrs != NULL) {\n> +               curl_max_receive_speed = strtol(mrs, NULL, 10);\n> +               if (curl_max_receive_speed < 0)\n> +                       die(_(\"negative values are not allowed for %s\"), mrs_env);\n> +       }\n\nYou introduced a new l10n message for translation. Why not make it as\nsimple as parsing env \"GIT_HTTP_LOW_SPEED_LIMIT\" or\n\"GIT_HTTP_LOW_SPEED_TIME\" above?\n\n--\nJiang Xin\n"},{"id":"434229","messageId":"CAHLXgnaS9yocd+OV=uCi+Udd419RTy+=-o7cjD79LyZR5MbpYw@mail.gmail.com","threadId":"56323","inReplyTo":"CANYiYbEL2T897jMZFg_F-AgomrEj3EcEC2ZTyBZMB550k_PPbQ@mail.gmail.com","subject":"Re: [PATCH v2] http: add http.maxReceiveSpeed to limit receiving speed of \"git-receive-pack\"","fromName":"Xiaowen Xia","fromEmail":"haoyurenzhuxia@gmail.com","sentAt":"2021-08-31T04:15:22Z","receivedAt":"2021-08-31T04:25:44Z","isPatch":true,"sender":{"key":"haoyurenzhuxia@gmail.com","avatar":null},"body":"Thanks for Jiang Xin's reply, it's very helpful.\n\nBut I carefully considered the purpose of this patch this week. As\nJeff King and Randall said, speed-limiting should be the function of\nthe operating system or the switch/router, and I agree with it. Users\nmay not need to limit the speed for `git-receive-pack` in most cases.\nOn the other side, for the ssh protocol, there is no way to limiting\nspeed in git. Please ignore this patch In general.\n"}]}