gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnurl] 139/411: tool_writeout: add new writeout variable, %{num_headers


From: gnunet
Subject: [gnurl] 139/411: tool_writeout: add new writeout variable, %{num_headers}
Date: Wed, 13 Jan 2021 01:19:14 +0100

This is an automated email from the git hooks/post-receive script.

nikita pushed a commit to branch master
in repository gnurl.

commit 0c1e767e83ec669d213868db8887e19386f717b2
Author: anio <anio@users.noreply.github.com>
AuthorDate: Wed Sep 9 15:05:49 2020 +0000

    tool_writeout: add new writeout variable, %{num_headers}
    
    This variable gives the number of headers.
    
    Closes #5947
---
 docs/INTERNALS.md                 |  2 +-
 docs/cmdline-opts/write-out.d     |  4 ++
 src/tool_cb_hdr.c                 | 12 +++++-
 src/tool_operate.c                |  2 +-
 src/tool_operate.h                |  2 +
 src/tool_writeout.c               | 19 ++++++----
 src/tool_writeout.h               |  4 +-
 src/tool_writeout_json.c          | 22 +++++++----
 src/tool_writeout_json.h          |  4 +-
 tests/data/Makefile.inc           |  2 +-
 tests/data/test1439               |  2 +-
 tests/data/{test1439 => test3014} |  6 +--
 tests/data/test3015               | 79 +++++++++++++++++++++++++++++++++++++++
 tests/data/test970                |  2 +-
 14 files changed, 136 insertions(+), 26 deletions(-)

diff --git a/docs/INTERNALS.md b/docs/INTERNALS.md
index a15703463..863da70af 100644
--- a/docs/INTERNALS.md
+++ b/docs/INTERNALS.md
@@ -503,7 +503,7 @@ Client
  status and exits.
 
  When the operation is done, the `ourWriteOut()` function in `src/writeout.c`
- may be called to report about the operation. That function is using the
+ may be called to report about the operation. That function is mostly using the
  `curl_easy_getinfo()` function to extract useful information from the curl
  session.
 
diff --git a/docs/cmdline-opts/write-out.d b/docs/cmdline-opts/write-out.d
index 013319cc2..28b9a13a9 100644
--- a/docs/cmdline-opts/write-out.d
+++ b/docs/cmdline-opts/write-out.d
@@ -67,6 +67,10 @@ The http method used in the most recent HTTP request (Added 
in 7.72.0)
 .B num_connects
 Number of new connects made in the recent transfer. (Added in 7.12.3)
 .TP
+.B num_headers
+The number of response headers in the most recent request (restarted at each
+ redirect). Note that the status line IS NOT a header. (Added in 7.73.0)
+.TP
 .B num_redirects
 Number of redirects that were followed in the request. (Added in 7.12.3)
 .TP
diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c
index ee3ef7390..6c6c095c7 100644
--- a/src/tool_cb_hdr.c
+++ b/src/tool_cb_hdr.c
@@ -179,7 +179,17 @@ size_t tool_header_cb(char *ptr, size_t size, size_t 
nmemb, void *userdata)
     if(!outs->stream && !tool_create_output_file(outs, per->config))
       return failure;
   }
-
+  if(hdrcbdata->config->writeout) {
+    char *value = memchr(ptr, ':', cb);
+    if(value) {
+      if(per->was_last_header_empty)
+        per->num_headers = 0;
+      per->was_last_header_empty = FALSE;
+      per->num_headers++;
+    }
+    else if(ptr[0] == '\r' || ptr[0] == '\n')
+      per->was_last_header_empty = TRUE;
+  }
   if(hdrcbdata->config->show_headers &&
     (protocol &
      (CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_RTSP|CURLPROTO_FILE))) {
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 991adfa2b..e03bbedb8 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -622,7 +622,7 @@ static CURLcode post_per_transfer(struct GlobalConfig 
*global,
     fputs("\n", per->progressbar.out);
 
   if(config->writeout)
-    ourWriteOut(per->curl, &per->outs, config->writeout);
+    ourWriteOut(per->curl, per, config->writeout);
 
   /* Close the outs file */
   if(outs->fopened && outs->stream) {
diff --git a/src/tool_operate.h b/src/tool_operate.h
index 42b1861d0..6cb3bd036 100644
--- a/src/tool_operate.h
+++ b/src/tool_operate.h
@@ -51,6 +51,8 @@ struct per_transfer {
   struct OutStruct etag_save;
   struct InStruct input;
   struct HdrCbData hdrcbdata;
+  long num_headers;
+  bool was_last_header_empty;
   char errorbuffer[CURL_ERROR_SIZE];
 
   bool added; /* set TRUE when added to the multi handle */
diff --git a/src/tool_writeout.c b/src/tool_writeout.c
index 41441ff30..63d2cd003 100644
--- a/src/tool_writeout.c
+++ b/src/tool_writeout.c
@@ -38,6 +38,8 @@ static const struct writeoutvar variables[] = {
    CURLINFO_RESPONSE_CODE, JSON_LONG},
   {"response_code", VAR_HTTP_CODE, 0,
    CURLINFO_RESPONSE_CODE, JSON_LONG},
+  {"num_headers", VAR_NUM_HEADERS, 0,
+   0, JSON_LONG},
   {"http_connect", VAR_HTTP_CODE_PROXY, 0,
    CURLINFO_HTTP_CONNECTCODE, JSON_LONG},
   {"time_total", VAR_TOTAL_TIME, 0,
@@ -104,7 +106,7 @@ static const struct writeoutvar variables[] = {
    0, JSON_NONE}
 };
 
-void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
+void ourWriteOut(CURL *curl, struct per_transfer *per, const char *writeinfo)
 {
   FILE *stream = stdout;
   const char *ptr = writeinfo;
@@ -156,6 +158,9 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const 
char *writeinfo)
                    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &longinfo))
                   fprintf(stream, "%03ld", longinfo);
                 break;
+              case VAR_NUM_HEADERS:
+                fprintf(stream, "%ld", per->num_headers);
+                break;
               case VAR_HTTP_CODE_PROXY:
                 if(CURLE_OK ==
                    curl_easy_getinfo(curl, CURLINFO_HTTP_CONNECTCODE,
@@ -275,14 +280,14 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, 
const char *writeinfo)
                   fprintf(stream, "%ld", longinfo);
                 break;
               case VAR_EFFECTIVE_FILENAME:
-                if(outs->filename)
-                  fprintf(stream, "%s", outs->filename);
+                if(per->outs.filename)
+                  fputs(per->outs.filename, stream);
                 break;
               case VAR_PRIMARY_IP:
                 if(CURLE_OK ==
                    curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP,
                                      &stringp))
-                  fprintf(stream, "%s", stringp);
+                  fputs(stringp, stream);
                 break;
               case VAR_PRIMARY_PORT:
                 if(CURLE_OK ==
@@ -294,7 +299,7 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const 
char *writeinfo)
                 if(CURLE_OK ==
                    curl_easy_getinfo(curl, CURLINFO_LOCAL_IP,
                                      &stringp))
-                  fprintf(stream, "%s", stringp);
+                  fputs(stringp, stream);
                 break;
               case VAR_LOCAL_PORT:
                 if(CURLE_OK ==
@@ -329,7 +334,7 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const 
char *writeinfo)
                 if(CURLE_OK ==
                    curl_easy_getinfo(curl, CURLINFO_SCHEME,
                                      &stringp))
-                  fprintf(stream, "%s", stringp);
+                  fputs(stringp, stream);
                 break;
               case VAR_STDOUT:
                 stream = stdout;
@@ -338,7 +343,7 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const 
char *writeinfo)
                 stream = stderr;
                 break;
               case VAR_JSON:
-                ourWriteOutJSON(variables, curl, outs, stream);
+                ourWriteOutJSON(variables, curl, per, stream);
               default:
                 break;
               }
diff --git a/src/tool_writeout.h b/src/tool_writeout.h
index 68bacb9d4..377f0b2b3 100644
--- a/src/tool_writeout.h
+++ b/src/tool_writeout.h
@@ -22,6 +22,7 @@
  *
  ***************************************************************************/
 #include "tool_setup.h"
+#include "tool_operate.h"
 
 typedef enum {
   VAR_NONE,       /* must be the first */
@@ -38,6 +39,7 @@ typedef enum {
   VAR_HTTP_CODE,
   VAR_HTTP_CODE_PROXY,
   VAR_HEADER_SIZE,
+  VAR_NUM_HEADERS,
   VAR_REQUEST_SIZE,
   VAR_EFFECTIVE_METHOD,
   VAR_EFFECTIVE_URL,
@@ -80,6 +82,6 @@ struct writeoutvar {
   jsontype jsontype;
 };
 
-void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo);
+void ourWriteOut(CURL *curl, struct per_transfer *per, const char *writeinfo);
 
 #endif /* HEADER_CURL_TOOL_WRITEOUT_H */
diff --git a/src/tool_writeout_json.c b/src/tool_writeout_json.c
index dfe51b9ff..bae7f5c15 100644
--- a/src/tool_writeout_json.c
+++ b/src/tool_writeout_json.c
@@ -103,13 +103,20 @@ static int writeString(FILE *str, CURL *curl, const char 
*key, CURLINFO ci)
   return 0;
 }
 
-static int writeLong(FILE *str, CURL *curl, const char *key, CURLINFO ci)
+static int writeLong(FILE *str, CURL *curl, const char *key, CURLINFO ci,
+                     struct per_transfer *per, const struct writeoutvar *wovar)
 {
-  long val = 0;
-  if(CURLE_OK == curl_easy_getinfo(curl, ci, &val)) {
-    fprintf(str, "\"%s\":%ld", key, val);
+  if(wovar->id == VAR_NUM_HEADERS) {
+    fprintf(str, "\"%s\":%ld", key, per->num_headers);
     return 1;
   }
+  else {
+    long val = 0;
+    if(CURLE_OK == curl_easy_getinfo(curl, ci, &val)) {
+      fprintf(str, "\"%s\":%ld", key, val);
+      return 1;
+    }
+  }
   return 0;
 }
 
@@ -149,12 +156,13 @@ static int writeVersion(FILE *str, CURL *curl, const char 
*key, CURLINFO ci)
 }
 
 void ourWriteOutJSON(const struct writeoutvar mappings[], CURL *curl,
-        struct OutStruct *outs, FILE *stream)
+                     struct per_transfer *per, FILE *stream)
 {
   int i;
 
   fputs("{", stream);
   for(i = 0; mappings[i].name != NULL; i++) {
+    const struct writeoutvar *wovar = &mappings[i];
     const char *name = mappings[i].name;
     CURLINFO cinfo = mappings[i].cinfo;
     int ok = 0;
@@ -168,7 +176,7 @@ void ourWriteOutJSON(const struct writeoutvar mappings[], 
CURL *curl,
       ok = writeString(stream, curl, name, cinfo);
       break;
     case JSON_LONG:
-      ok = writeLong(stream, curl, name, cinfo);
+      ok = writeLong(stream, curl, name, cinfo, per, wovar);
       break;
     case JSON_OFFSET:
       ok = writeOffset(stream, curl, name, cinfo);
@@ -177,7 +185,7 @@ void ourWriteOutJSON(const struct writeoutvar mappings[], 
CURL *curl,
       ok = writeTime(stream, curl, name, cinfo);
       break;
     case JSON_FILENAME:
-      ok = writeFilename(stream, name, outs->filename);
+      ok = writeFilename(stream, name, per->outs.filename);
       break;
     case JSON_VERSION:
       ok = writeVersion(stream, curl, name, cinfo);
diff --git a/src/tool_writeout_json.h b/src/tool_writeout_json.h
index d3988d521..0390ae5c8 100644
--- a/src/tool_writeout_json.h
+++ b/src/tool_writeout_json.h
@@ -24,7 +24,7 @@
 #include "tool_setup.h"
 #include "tool_writeout.h"
 
-void ourWriteOutJSON(const struct writeoutvar mappings[],
-        CURL *curl, struct OutStruct *outs, FILE *stream);
+void ourWriteOutJSON(const struct writeoutvar mappings[], CURL *curl,
+                     struct per_transfer *per, FILE *stream);
 
 #endif /* HEADER_CURL_TOOL_WRITEOUT_H */
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 606a6031a..42f427eea 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -225,4 +225,4 @@ test2080 \
 test2100 \
 \
 test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 \
-test3008 test3009 test3010 test3011 test3012 test3013
+test3008 test3009 test3010 test3011 test3012 test3013 test3014 test3015
diff --git a/tests/data/test1439 b/tests/data/test1439
index cb906adbc..91edd2248 100644
--- a/tests/data/test1439
+++ b/tests/data/test1439
@@ -26,7 +26,7 @@ http
 </server>
 
 <name>
-Check if %{scheme} returns HTTP
+Check if %{http_version} returns 1.1
 </name>
 <command>
 http://%HOSTIP:%HTTPPORT/1439 --write-out '%{http_version}'
diff --git a/tests/data/test1439 b/tests/data/test3014
similarity index 84%
copy from tests/data/test1439
copy to tests/data/test3014
index cb906adbc..7fab42fcd 100644
--- a/tests/data/test1439
+++ b/tests/data/test3014
@@ -26,10 +26,10 @@ http
 </server>
 
 <name>
-Check if %{scheme} returns HTTP
+Check if %{num_headers} returns correct number of headers
 </name>
 <command>
-http://%HOSTIP:%HTTPPORT/1439 --write-out '%{http_version}'
+http://%HOSTIP:%HTTPPORT/1439 --write-out '%{num_headers}'
 </command>
 </client>
 
@@ -43,7 +43,7 @@ Connection: close
 Content-Type: text/plain
 
 testdata
-1.1
+4
 </stdout>
 <protocol>
 GET /1439 HTTP/1.1
diff --git a/tests/data/test3015 b/tests/data/test3015
new file mode 100644
index 000000000..fbc6eadb8
--- /dev/null
+++ b/tests/data/test3015
@@ -0,0 +1,79 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+followlocation
+chunked Transfer-Encoding
+--write-out
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 302 OK
+Date: Sun, 13 Sep 2020 15:00 GMT
+Content-Length: 8
+Connection: close
+Content-Type: text/plain
+Location: ./30150001
+
+monster
+</data>
+<data1 nocheck="yes">
+HTTP/1.1 200 OK
+Date: Sun, 13 Sep 2020 15:00 GMT
+Transfer-Encoding: chunked
+Connection: close
+Content-Type: text/plain; charset=us-ascii
+
+0007
+bigger 
+0008
+monster
+
+0
+
+</data1>
+
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP GET -w num_headers with redirected fetch (2 connects)
+ </name>
+ <command>
+http://%HOSTIP:%HTTPPORT/3015 -w "%{num_headers}\n" -L -o/dev/null
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /3015 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+GET /30150001 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+</protocol>
+
+<stdout>
+4
+</stdout>
+
+</verify>
+</testcase>
diff --git a/tests/data/test970 b/tests/data/test970
index c0a88a798..bc5af5ba7 100644
--- a/tests/data/test970
+++ b/tests/data/test970
@@ -61,7 +61,7 @@ Accept: */*
 
 </protocol>
 <stdout nonewline="yes">
-{"url_effective":"http://%HOSTIP:%HTTPPORT/970","method":"GET","http_code":200,"response_code":200,"http_connect":0,"time_total":0.000013,"time_namelookup":0.000013,"time_connect":0.000013,"time_appconnect":0.000013,"time_pretransfer":0.000013,"time_starttransfer":0.000013,"size_header":4019,"size_request":4019,"size_download":445,"size_upload":0,"speed_download":13,"speed_upload":13,"content_type":"text/html","num_connects":1,"time_redirect":0.000013,"num_redirects":0,"ssl_verify_result
 [...]
+{"url_effective":"http://%HOSTIP:%HTTPPORT/970","method":"GET","http_code":200,"response_code":200,"num_headers":9,"http_connect":0,"time_total":0.000013,"time_namelookup":0.000013,"time_connect":0.000013,"time_appconnect":0.000013,"time_pretransfer":0.000013,"time_starttransfer":0.000013,"size_header":4019,"size_request":4019,"size_download":445,"size_upload":0,"speed_download":13,"speed_upload":13,"content_type":"text/html","num_connects":1,"time_redirect":0.000013,"num_redirects":0,"s
 [...]
 </stdout>
 </verify>
 </testcase>

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]