1 // Copyright (C) 2001-2005 Open Source Telecom Corporation.
2 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 //
18 // As a special exception, you may use this file as part of a free software
19 // library without restriction.  Specifically, if other files instantiate
20 // templates or use macros or inline functions from this file, or you compile
21 // this file and link it with other files to produce an executable, this
22 // file does not by itself cause the resulting executable to be covered by
23 // the GNU General Public License.  This exception does not however
24 // invalidate any other reasons why the executable file might be covered by
25 // the GNU General Public License.
26 //
27 // This exception applies only to the code released under the name GNU
28 // Common C++.  If you copy code from other releases into a copy of GNU
29 // Common C++, as the General Public License permits, the exception does
30 // not apply to the code that you add in this way.  To avoid misleading
31 // anyone as to the status of such modified files, you must delete
32 // this exception notice from them.
33 //
34 // If you write modifications of your own for GNU Common C++, it is your choice
35 // whether to permit this exception to apply to your modifications.
36 // If you do not wish that, delete this exception notice.
37 //
38 
39 /**
40  * @file url.h
41  * @short URL streams abstraction.
42  **/
43 
44 #ifndef CCXX_URL_H_
45 #define CCXX_URL_H_
46 
47 #ifndef CCXX_CONFIG_H_
48 #include <cc++/config.h>
49 #endif
50 
51 #ifndef CCXX_SOCKET_H_
52 #include <cc++/socket.h>
53 #endif
54 
55 #ifndef CCXX_MIME_H_
56 #include <cc++/mime.h>
57 #endif
58 
59 #ifdef  CCXX_NAMESPACES
60 namespace ost {
61 #endif
62 
63 /**
64  * A URL processing version of TCPStream.
65  *
66  * @author David Sugar <dyfet@ostel.com>
67  * @short C++ url processing stream class.
68  */
69 class __EXPORT URLStream : public TCPStream
70 {
71 public:
72     /**
73      * Return error for url fetch
74      */
75     typedef enum {
76         errSuccess = 0,
77         errUnreachable,
78         errMissing,
79         errDenied,
80         errInvalid,
81         errForbidden,
82         errUnauthorized,
83         errRelocated,
84         errFailure,
85         errTimeout,
86         errInterface
87     } Error;
88 
89     /**
90      * Type of authentication
91      */
92     typedef enum {
93         authAnonymous = 0,
94         authBasic
95     } Authentication;
96 
97     /**
98      * Encoding used in transfer
99      */
100     typedef enum {
101         encodingBinary = 0,
102         encodingChunked
103     } Encoding;
104 
105     /**
106      * Type of fetch
107      */
108     typedef enum {
109         methodHttpGet,
110         methodHttpPut,
111         methodHttpPost,
112         methodHttpPostMultipart,
113         methodFtpGet,
114         methodFtpPut,
115         methodFileGet,
116         methodFilePut
117     } Method;
118 
119     /**
120      * http protocol version
121      */
122     typedef enum {
123         protocolHttp1_0,
124         protocolHttp1_1
125     } Protocol;
126 
127 private:
128     const char *agent, *referer, *cookie, *pragma, *user, *password;
129     const char *proxyUser, *proxyPasswd;
130     const char *localif;
131     IPV4Host proxyHost;
132 #ifdef  CCXX_IPV6
133     IPV6Host v6proxyHost;
134 #endif
135     tpport_t proxyPort;
136     Method urlmethod;
137     Encoding encoding;
138     Protocol protocol;
139     Authentication auth;
140     Authentication proxyAuth;
141     timeout_t timeout;
142     bool persistent;
143     bool follow;
144     unsigned chunk;
145 
146     Error getHTTPHeaders();
147     URLStream(const URLStream& rhs);
148 
149 protected:
150     ost::String m_host, m_address;
151 
152     /**
153      * Send http header to server.
154      *
155      * @param url base to send header to
156      * @param vars to post or use in get method
157      * @param bufsize of stream buffering to use
158      * @return success or class error
159      */
160     Error sendHTTPHeader(const char *url, const char **vars, size_t bufsize);
161 
162     /**
163      * Called if stream buffer needs refilling.
164      *
165      * @return number of bytes refilled or error if < 0
166      */
167     int underflow(void);
168 
169     /**
170      * Derived method for async or timed I/O function on url stream.
171      *
172      * @return number of bytes read or < 0 for error.
173      * @param buffer to read stream data into.
174      * @param len of bytes to read from stream.
175      * @param timer to wait for data in milliseconds.
176      */
177     virtual int aRead(char *buffer, size_t len, timeout_t timer);
178 
179     /**
180      * Derived method for async or timed I/O function on url stream.
181      *
182      * @return number of bytes written or < 0 for error.
183      * @param buffer to write stream data from.
184      * @param len of bytes to write to stream.
185      * @param timer to wait for data in milliseconds.
186      */
187     virtual int aWrite(char *buffer, size_t len, timeout_t timer);
188 
189     /**
190      * Derived method to receive and parse http "headers".
191      *
192      * @param header keyword.
193      * @param value header keyword value.
194      */
195     virtual void httpHeader(const char *header, const char *value);
196 
197     /**
198      * A virtual to insert additional header info into the request.
199      *
200      * @return array of header attributes to add.
201      */
202     virtual char **extraHeader(void);
203 
204 public:
205     /**
206      * Construct an instance of URL stream.
207      *
208      * @param family protocol to use.
209      * @param timer for default timeout on I/O operations.
210      */
211     URLStream(Family family = IPV4, timeout_t timer = 0);
212 
213     /**
214      * Line parsing with conversion.
215      *
216      * @return URLStream object reference.
217      * @param buffer to store.
218      * @param len maximum buffer size.
219      */
220     URLStream &getline(char *buffer, size_t len);
221 
222     /**
223      * Get URL data from a named stream of a known buffer size.
224      *
225      * @return url error code.
226      * @param url name of resource.
227      * @param buffer size of buffer.
228      */
229     Error get(const char *url, size_t buffer = 512);
230 
231     /**
232     * Get URL data from a named stream of a known buffer size.
233     * Requesting URL defined in previous calls of setAddress() and
234     * setHost() functions.
235     *
236     * @return url error code.
237     * @param buffer size of buffer.
238     */
239     Error get(size_t buffer = 512);
240 
241     /**
242      * Submit URL with vars passed as argument array.  This submit
243      * assumes "GET" method.  Use "post" member to perform post.
244      *
245      * @return url error code.
246      * @param url name of resource.
247      * @param vars to set.
248      * @param buffer size of buffer.
249      */
250     Error submit(const char *url, const char **vars, size_t buffer = 512);
251 
252     /**
253      * Post URL vars with post method.
254      *
255      * @return success or error code.
256      * @param url name of resource being posted.
257      * @param vars to set in post.
258      * @param buffer size of buffer.
259      */
260     Error post(const char *url, const char **vars, size_t buffer = 512);
261 
262     /**
263      * Post URL with MIME multipart form.
264      *
265      * @return success or error code.
266      * @param url name of resource being posted.
267      * @param form multi-part resource.
268      * @param buffer size to use.
269      */
270     Error post(const char *url, MIMEMultipartForm &form, size_t buffer = 512);
271 
272     /**
273      * Used to fetch header information for a resource.
274      *
275      * @return url error code.
276      * @param url name of resource.
277      * @param buffer size of buffer.
278      */
279     Error head(const char *url, size_t buffer = 512);
280 
281     /**
282      * Close the URL stream for a new connection.
283      */
284     void close();
285 
286     /**
287      * Set the referer url.
288      *
289      * @param str referer string.
290      */
291     void setReferer(const char *str);
292 
293     /**
294     * Set the host for the url
295     *
296     * @param str host address.
297     */
setHost(const char * str)298     inline void setHost(const char *str)
299         {m_host = str;};
300 
301     /**
302     * Set the address for the url
303     *
304     * @param str address in the URL.
305     */
setAddress(const char * str)306     inline void setAddress(const char *str)
307         {m_address = str;};
308 
309     /**
310      * Set the cookie to pass.
311      *
312      * @param str cookie string.
313      */
setCookie(const char * str)314     inline void setCookie(const char *str)
315         {cookie = str;};
316 
317     /**
318      * Set user id for the url.
319      *
320      * @param str user id.
321      */
setUser(const char * str)322     inline void setUser(const char *str)
323         {user = str;};
324 
325     /**
326      * Set password for the url.
327      *
328      * @param str password.
329      */
setPassword(const char * str)330     inline void setPassword(const char *str)
331         {password = str;};
332 
333     /**
334      * Set authentication type for the url.
335      *
336      * @param a authentication.
337      * @param str string.
338      */
339     void setAuthentication(Authentication a, const char *str = NULL);
340 
341     /**
342      * Set proxy user id for the url.
343      *
344      * @param str user id.
345      */
setProxyUser(const char * str)346     inline void setProxyUser(const char *str)
347         {proxyUser = str;};
348 
349     /**
350      * Set proxy password for the url.
351      *
352      * @param str password.
353      */
setProxyPassword(const char * str)354     inline void setProxyPassword(const char *str)
355         {proxyPasswd = str;};
356 
357     /**
358      * Set proxy authentication type for the url.
359      *
360      * @param a authentication.
361      * @param str string.
362      */
363     void setProxyAuthentication(Authentication a, const char *str = NULL);
364 
365     /**
366      * Set the pragmas.
367      *
368      * @param str pragma setting.
369      */
setPragma(const char * str)370     inline void setPragma(const char *str)
371         {pragma = str;};
372 
373     /**
374      * Set the proxy server used.
375      *
376      * @param host proxy host.
377      * @param port proxy port.
378      */
379     void setProxy(const char *host, tpport_t port);
380 
381     /**
382      * Set the agent.
383      *
384      * @param str agent value.
385      */
setAgent(const char * str)386     inline void setAgent(const char *str)
387         {agent = str;};
388 
389     /**
390      * Get url method (and protocol) employed.
391      *
392      * @return url method in effect.
393      */
getMethod(void)394     inline Method getMethod(void)
395         {return urlmethod;};
396 
397     /**
398      * Set socket timeout characteristics for processing URL
399      * requests.  Set to 0 for no default timeouts.
400      *
401      * @param to timeout to set.
402      */
setTimeout(timeout_t to)403     inline void setTimeout(timeout_t to)
404         {timeout = to;};
405 
406     /**
407      * Specify url following.  Set to false to disable following
408      * of relocation requests.
409      *
410      * @param enable true to enable following.
411      */
setFollow(bool enable)412     inline void setFollow(bool enable)
413         {follow = enable;};
414 
415     /**
416      * Specify http protocol level being used.
417      *
418      * @param pro protocol level.
419      */
setProtocol(Protocol pro)420     inline void setProtocol(Protocol pro)
421         {protocol = pro;};
422     /**
423      * Specify local interface to use
424      *
425      * @param intf Local interface name
426      */
setLocalInterface(const char * intf)427     inline void setLocalInterface(const char *intf)
428     {localif=intf;}
429 };
430 
431 /** @relates URLStream
432  * Decode an url parameter (ie "\%20" -> " ")
433  * @param source string
434  * @param dest destination buffer. If NULL source is used
435  */
436 __EXPORT char* urlDecode(char *source, char *dest = NULL);
437 
438 /** @relates URLStream
439  * Encode an url parameter (ie " " -> "+")
440  * @param source string
441  * @param dest destination buffer. Do not overlap with source
442  * @param size destination buffer size.
443  */
444 __EXPORT char* urlEncode(const char *source, char *dest, size_t size);
445 
446 /** @relates URLStream
447  * Decode a string using base64 coding.
448  * Destination size should be at least strlen(src)+1.
449  * Destination will be a string, so is always terminated .
450  * This function is deprecated, base64 can use binary source, not only string
451  * use overloaded b64Decode.
452  * @return string coded
453  * @param src  source buffer
454  * @param dest destination buffer. If NULL src is used
455  */
456 __EXPORT char* b64Decode(char *src, char *dest = NULL);
457 
458 /** @relates URLStream
459  * Encode a string using base64 coding.
460  * Destination size should be at least strlen(src)/4*3+1.
461  * Destination is string terminated.
462  * This function is deprecated, coded stream can contain terminator character
463  * use overloaded b64Encode instead.
464  * @return destination buffer
465  * @param source source string
466  * @param dest   destination octet buffer
467  * @param size   destination buffer size
468  */
469 __EXPORT char* b64Encode(const char *source, char *dest, size_t size);
470 
471 /** @relates URLStream
472  * Encode a octet stream using base64 coding.
473  * Destination size should be at least (srcsize+2)/3*4+1.
474  * Destination will be a string, so is always terminated
475  * (unless you pass dstsize == 0).
476  * @return size of string written not counting terminator
477  * @param src     source buffer
478  * @param srcsize source buffer size
479  * @param dst     destination buffer
480  * @param dstsize destination buffer size
481  */
482 __EXPORT size_t b64Encode(const unsigned char *src, size_t srcsize,
483            char *dst, size_t dstsize);
484 
485 /** @relates URLStream
486  * Decode a string using base64 coding.
487  * Destination size should be at least strlen(src)/4*3.
488  * Destination are not string terminated (It's just a octet stream).
489  * @return number of octets written into destination buffer
490  * @param src     source string
491  * @param dst     destination octet buffer
492  * @param dstsize destination buffer size
493  */
494 __EXPORT size_t b64Decode(const char *src,
495         unsigned char *dst, size_t dstsize);
496 
497 /** @relates URLStream
498  * Encode a STL string using base64 coding into a STL string
499  * @return base 64 encoded string
500  * @param src source string
501  */
502 __EXPORT String b64Encode(const String& src);
503 
504 /** @relates URLStream
505  * Decode a STL string using base64 coding into an STL String.
506  * Destination size should be at least strlen(src)/4*3.
507  * Destination are not string terminated (It's just a octet stream).
508  * @return decoded string
509  * @param src     source string
510  */
511 __EXPORT String b64Decode(const String& src);
512 
513 /** @relates URLStream
514  * Encode a octet stream using base64 coding into a STL string
515  * @return base 64 encoded string
516  * @param src     source buffer
517  * @param srcsize source buffer size
518  */
519 __EXPORT String b64Encode(const unsigned char *src, size_t srcsize);
520 
521 /** @relates URLStream
522  * Decode a string using base64 coding.
523  * Destination size should be at least strlen(src)/4*3.
524  * Destination are not string terminated (It's just a octet stream).
525  * @return number of octets written into destination buffer
526  * @param src     source string
527  * @param dst     destination octet buffer
528  * @param dstsize destination buffer size
529  */
530 __EXPORT size_t b64Decode(const String& src,
531         unsigned char *dst, size_t dstsize);
532 
533 
534 #ifdef  CCXX_NAMESPACES
535 }
536 #endif
537 
538 #endif
539 /** EMACS **
540  * Local variables:
541  * mode: c++
542  * c-basic-offset: 4
543  * End:
544  */
545