• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef HEADER_CURL_SENDF_H
2 #define HEADER_CURL_SENDF_H
3 /***************************************************************************
4  *                                  _   _ ____  _
5  *  Project                     ___| | | |  _ \| |
6  *                             / __| | | | |_) | |
7  *                            | (__| |_| |  _ <| |___
8  *                             \___|\___/|_| \_\_____|
9  *
10  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
11  *
12  * This software is licensed as described in the file COPYING, which
13  * you should have received as part of this distribution. The terms
14  * are also available at https://curl.se/docs/copyright.html.
15  *
16  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
17  * copies of the Software, and permit persons to whom the Software is
18  * furnished to do so, under the terms of the COPYING file.
19  *
20  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21  * KIND, either express or implied.
22  *
23  * SPDX-License-Identifier: curl
24  *
25  ***************************************************************************/
26 
27 #include "curl_setup.h"
28 
29 #include "curl_trc.h"
30 
31 /**
32  * Type of data that is being written to the client (application)
33  * - data written can be either BODY or META data
34  * - META data is either INFO or HEADER
35  * - INFO is meta information, e.g. not BODY, that cannot be interpreted
36  *   as headers of a response. Example FTP/IMAP pingpong answers.
37  * - HEADER can have additional bits set (more than one)
38  *   - STATUS special "header", e.g. response status line in HTTP
39  *   - CONNECT header was received during proxying the connection
40  *   - 1XX header is part of an intermediate response, e.g. HTTP 1xx code
41  *   - TRAILER header is trailing response data, e.g. HTTP trailers
42  * BODY, INFO and HEADER should not be mixed, as this would lead to
43  * confusion on how to interpret/format/convert the data.
44  */
45 #define CLIENTWRITE_BODY    (1<<0) /* non-meta information, BODY */
46 #define CLIENTWRITE_INFO    (1<<1) /* meta information, not a HEADER */
47 #define CLIENTWRITE_HEADER  (1<<2) /* meta information, HEADER */
48 #define CLIENTWRITE_STATUS  (1<<3) /* a special status HEADER */
49 #define CLIENTWRITE_CONNECT (1<<4) /* a CONNECT related HEADER */
50 #define CLIENTWRITE_1XX     (1<<5) /* a 1xx response related HEADER */
51 #define CLIENTWRITE_TRAILER (1<<6) /* a trailer HEADER */
52 #define CLIENTWRITE_EOS     (1<<7) /* End Of transfer download Stream */
53 
54 /**
55  * Write `len` bytes at `prt` to the client. `type` indicates what
56  * kind of data is being written.
57  */
58 CURLcode Curl_client_write(struct Curl_easy *data, int type, char *ptr,
59                            size_t len) WARN_UNUSED_RESULT;
60 
61 /**
62  * For a paused transfer, there might be buffered data held back.
63  * Attempt to flush this data to the client. This *may* trigger
64  * another pause of the transfer.
65  */
66 CURLcode Curl_client_unpause(struct Curl_easy *data);
67 
68 /**
69  * Free all resources related to client writing.
70  */
71 void Curl_client_cleanup(struct Curl_easy *data);
72 
73 /**
74  * Client Writers - a chain passing transfer BODY data to the client.
75  * Main application: HTTP and related protocols
76  * Other uses: monitoring of download progress
77  *
78  * Writers in the chain are order by their `phase`. First come all
79  * writers in CURL_CW_RAW, followed by any in CURL_CW_TRANSFER_DECODE,
80  * followed by any in CURL_CW_PROTOCOL, etc.
81  *
82  * When adding a writer, it is inserted as first in its phase. This means
83  * the order of adding writers of the same phase matters, but writers for
84  * different phases may be added in any order.
85  *
86  * Writers which do modify the BODY data written are expected to be of
87  * phases TRANSFER_DECODE or CONTENT_DECODE. The other phases are intended
88  * for monitoring writers. Which do *not* modify the data but gather
89  * statistics or update progress reporting.
90  */
91 
92 /* Phase a writer operates at. */
93 typedef enum {
94   CURL_CW_RAW,  /* raw data written, before any decoding */
95   CURL_CW_TRANSFER_DECODE, /* remove transfer-encodings */
96   CURL_CW_PROTOCOL, /* after transfer, but before content decoding */
97   CURL_CW_CONTENT_DECODE, /* remove content-encodings */
98   CURL_CW_CLIENT  /* data written to client */
99 } Curl_cwriter_phase;
100 
101 /* Client Writer Type, provides the implementation */
102 struct Curl_cwtype {
103   const char *name;        /* writer name. */
104   const char *alias;       /* writer name alias, maybe NULL. */
105   CURLcode (*do_init)(struct Curl_easy *data,
106                       struct Curl_cwriter *writer);
107   CURLcode (*do_write)(struct Curl_easy *data,
108                        struct Curl_cwriter *writer, int type,
109                        const char *buf, size_t nbytes);
110   void (*do_close)(struct Curl_easy *data,
111                    struct Curl_cwriter *writer);
112   size_t cwriter_size;  /* sizeof() allocated struct Curl_cwriter */
113 };
114 
115 /* Client writer instance */
116 struct Curl_cwriter {
117   const struct Curl_cwtype *cwt;  /* type implementation */
118   struct Curl_cwriter *next;  /* Downstream writer. */
119   Curl_cwriter_phase phase; /* phase at which it operates */
120 };
121 
122 /**
123  * Create a new cwriter instance with given type and phase. Is not
124  * inserted into the writer chain by this call.
125  * Invokes `writer->do_init()`.
126  */
127 CURLcode Curl_cwriter_create(struct Curl_cwriter **pwriter,
128                              struct Curl_easy *data,
129                              const struct Curl_cwtype *ce_handler,
130                              Curl_cwriter_phase phase);
131 
132 /**
133  * Free a cwriter instance.
134  * Invokes `writer->do_close()`.
135  */
136 void Curl_cwriter_free(struct Curl_easy *data,
137                        struct Curl_cwriter *writer);
138 
139 /**
140  * Count the number of writers installed of the given phase.
141  */
142 size_t Curl_cwriter_count(struct Curl_easy *data, Curl_cwriter_phase phase);
143 
144 /**
145  * Adds a writer to the transfer's writer chain.
146  * The writers `phase` determines where in the chain it is inserted.
147  */
148 CURLcode Curl_cwriter_add(struct Curl_easy *data,
149                           struct Curl_cwriter *writer);
150 
151 void Curl_cwriter_remove_by_name(struct Curl_easy *data,
152                                  const char *name);
153 
154 /**
155  * Convenience method for calling `writer->do_write()` that
156  * checks for NULL writer.
157  */
158 CURLcode Curl_cwriter_write(struct Curl_easy *data,
159                             struct Curl_cwriter *writer, int type,
160                             const char *buf, size_t nbytes);
161 
162 /**
163  * Default implementations for do_init, do_write, do_close that
164  * do nothing and pass the data through.
165  */
166 CURLcode Curl_cwriter_def_init(struct Curl_easy *data,
167                                struct Curl_cwriter *writer);
168 CURLcode Curl_cwriter_def_write(struct Curl_easy *data,
169                                 struct Curl_cwriter *writer, int type,
170                                 const char *buf, size_t nbytes);
171 void Curl_cwriter_def_close(struct Curl_easy *data,
172                             struct Curl_cwriter *writer);
173 
174 
175 /* internal read-function, does plain socket, SSL and krb4 */
176 CURLcode Curl_read(struct Curl_easy *data, curl_socket_t sockfd,
177                    char *buf, size_t buffersize,
178                    ssize_t *n);
179 
180 /* internal write-function, does plain socket, SSL, SCP, SFTP and krb4 */
181 CURLcode Curl_write(struct Curl_easy *data,
182                     curl_socket_t sockfd,
183                     const void *mem, size_t len,
184                     ssize_t *written);
185 
186 /* internal write-function, using sockindex for connection destination */
187 CURLcode Curl_nwrite(struct Curl_easy *data,
188                      int sockindex,
189                      const void *buf,
190                      size_t blen,
191                      ssize_t *pnwritten);
192 
193 #endif /* HEADER_CURL_SENDF_H */
194