summaryrefslogtreecommitdiffstats
path: root/nanohttp/nanohttp-common.h
blob: ad00750722150a71747a274d1877a1665b9c3d8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
/******************************************************************
 *  $Id: nanohttp-common.h,v 1.38 2006/11/26 20:13:05 m0gg Exp $
 * 
 * CSOAP Project:  A http client/server library in C
 * Copyright (C) 2003-2004  Ferhat Ayaz
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 * 
 * Email: ferhatayaz@yahoo.com
 ******************************************************************/
#ifndef __nanohttp_common_h
#define __nanohttp_common_h

#define HEADER_CONTENT_ID		"Content-Id"
#define HEADER_CONTENT_TRANSFER_ENCODING "Content-Transfer-Encoding"
#define TRANSFER_ENCODING_CHUNKED	"chunked"

/** @file
 *
 * General Header Fields
 *
 * There are a few header fields which have general applicability for both
 * request and response messages, but which do not apply to the entity being
 * transferred. These header fields apply only to the message being transmitted.
 *
 * @see http://www.ietf.org/rfc/rfc/2616.txt
 *
 */

/**
 *
 * The Cache-Control general-header field is used to specify directives that MUST
 * be obeyed by all caching mechanisms along the request/response chain. The
 * directives specify behavior intended to prevent caches from adversely
 * interfering with the request or response. These directives typically override
 * the default caching algorithms. Cache directives are unidirectional in that
 * the presence of a directive in a request does not imply that the same
 * directive is to be given in the response.
 *
 */
#define HEADER_CACHE_CONTROL		"Cache-Control"

/**
 *
 * The Connection general-header field allows the sender to specify options that
 * are desired for that particular connection and MUST NOT be communicated by
 * proxies over further connections.
 *
 */
#define HEADER_CONNECTION		"Connection"

/**
 *
 * The Date general-header field represents the date and time at which the
 * message was originated, having the same semantics as orig-date in RFC 822.
 * The field value is an HTTP-date, as described in section 3.3.1; it MUST be
 * sent in RFC 1123 [8]-date format.
 *
 * @see http://www.ietf.org/rfc/rfc822.txt,
 *      http://www.ietf.org/rfc/rfc1123.txt
 *
 */
#define HEADER_DATE			"Date"

/**
 *
 * The Pragma general-header field is used to include implementation-specific
 * directives that might apply to any recipient along the request/response chain.
 * All pragma directives specify optional behavior from the viewpoint of the
 * protocol; however, some systems MAY require that behavior be consistent with
 * the directives.
 *
 */
#define HEADER_PRAGMA			"Pragma"

/**
 *
 * The Trailer general field value indicates that the given set of header fields
 * is present in the trailer of a message encoded with chunked transfer-coding.
 *
 */
#define HEADER_TRAILER			"Trailer"

/**
 *
 * The Transfer-Encoding general-header field indicates what (if any) type of
 * transformation has been applied to the message body in order to safely
 * transfer it between the sender and the recipient. This differs from the
 * content-coding in that the transfer-coding is a property of the message, not
 * of the entity.
 *
 */
#define HEADER_TRANSFER_ENCODING	"Transfer-Encoding"

/**
 *
 * The Upgrade general-header allows the client to specify what additional
 * communication protocols it supports and would like to use if the server finds
 * it appropriate to switch protocols. The server MUST use the Upgrade header
 * field within a 101 (Switching Protocols) response to indicate which
 * protocol(s) are being switched.
 *
 */
#define HEADER_UPGRADE			"Upgrade"

/**
 *
 * The Via general-header field MUST be used by gateways and proxies to indicate
 * the intermediate protocols and recipients between the user agent and the
 * server on requests, and between the origin server and the client on responses.
 * It is analogous to the "Received" field of RFC 822 and is intended to be used
 * for tracking message forwards, avoiding request loops, and identifying the
 * protocol capabilities of all senders along the request/response chain.
 *
 * @see http://www.ietf.org/rfc/rfc822.txt
 *
 */
#define HEADER_VIA			"Via"

/**
 *
 * The Warning general-header field is used to carry additional information about
 * the status or transformation of a message which might not be reflected in the
 * message. This information is typically used to warn about a possible lack of
 * semantic transparency from caching operations or transformations applied to
 * the entity body of the message.
 *
 */
#define HEADER_WARNING			"Warning"

/**
 *
 * Entity Header Fields
 *
 * Entity-header fields define metainformation about the entity-body or, if no
 * body is present, about the resource identified by the request. Some of this
 * metainformation is OPTIONAL; some might be REQUIRED by portions of this
 * specification. (see RFC2616 7.1)
 *
 * @see http://www.ietf.org/rfc/rfc2616.txt
 *
 */

/**
 *
 * The Allow entity-header field lists the set of methods supported by the
 * resource identified by the Request-URI. The purpose of this field is strictly
 * to inform the recipient of valid methods associated with the resource. An
 * Allow header field MUST be present in a 405 (Method Not Allowed) response.
 *
 */
#define HEADER_ALLOW			"Allow"

/**
 *
 * The Content-Encoding entity-header field is used as a modifier to the
 * media-type. When present, its value indicates what additional content codings
 * have been applied to the entity-body, and thus what decoding mechanisms must
 * be applied in order to obtain the media-type referenced by the Content-Type
 * header field. Content-Encoding is primarily used to allow a document to be
 * compressed without losing the identity of its underlying media type.
 *
 */
#define HEADER_CONTENT_ENCODING		"Content-Encoding"

/**
 *
 * The Content-Language entity-header field describes the natural language(s) of
 * the intended audience for the enclosed entity. Note that this might not be
 * equivalent to all the languages used within the entity-body.
 *
 */
#define HEADER_CONTENT_LANGUAGE		"Content-Language"

/**
 *
 * The Content-Length entity-header field indicates the size of the entity-body,
 * in decimal number of OCTETs, sent to the recipient or, in the case of the HEAD
 * method, the size of the entity-body that would have been sent had the request
 * been a GET.
 *
 */
#define HEADER_CONTENT_LENGTH		"Content-Length"

/**
 *
 * The Content-Location entity-header field MAY be used to supply the resource
 * location for the entity enclosed in the message when that entity is accessible
 * from a location separate from the requested resource's URI. A server SHOULD
 * provide a Content-Location for the variant corresponding to the response
 * entity; especially in the case where a resource has multiple entities
 * associated with it, and those entities actually have separate locations by
 * which they might be individually accessed, the server SHOULD provide a
 * Content-Location for the particular variant which is returned.
 *
 */
#define HEADER_CONTENT_LOCATION		"Content-Location"

/**
 *
 * The Content-MD5 entity-header field, as defined in RFC 1864, is an MD5 digest
 * of the entity-body for the purpose of providing an end-to-end message
 * integrity check (MIC) of the entity-body. (Note: a MIC is good for detecting
 * accidental modification of the entity-body in transit, but is not proof
 * against malicious attacks.)
 *
 * @see http://www.ietf.org/rfc/rfc1864.txt
 *
 */
#define HEADER_CONTENT_MD5		"Content-MD5"

/**
 *
 * The Content-Range entity-header is sent with a partial entity-body to specify
 * where in the full entity-body the partial body should be applied. Range units
 * are defined in RFC 2616 section 3.12.
 *
 * @see http://www.ietf.org/rfc/rcf2616.txt
 *
 */
#define HEADER_CONTENT_RANGE		"Content-Range"

/**
 *
 * The Content-Type entity-header field indicates the media type of the
 * entity-body sent to the recipient or, in the case of the HEAD method, the
 * media type that would have been sent had the request been a GET.
 *
 */
#define HEADER_CONTENT_TYPE		"Content-Type"

/**
 *
 * The Expires entity-header field gives the date/time after which the response
 * is considered stale. A stale cache entry may not normally be returned by a
 * cache (either a proxy cache or a user agent cache) unless it is first
 * validated with the origin server (or with an intermediate cache that has a
 * fresh copy of the entity). See RFC 2616 section 13.2 for further discussion of
 * the expiration model.
 *
 * @see http://www.ietf.org/rfc/rfc2616.txt
 *
 */
#define HEADER_EXPIRES			"Expires"

/**
 *
 * The Last-Modified entity-header field indicates the date and time at which the
 * origin server believes the variant was last modified.
 *
 */
#define HEADER_LAST_MODIFIED		"Last-Modified"

/**
 *
 * Common commandline arguments for client and server.
 *
 */
#define NHTTP_ARG_CERT		"-NHTTPcert"
#define NHTTP_ARG_CERTPASS	"-NHTTPcertpass"
#define NHTTP_ARG_CA		"-NHTTPCA"

#ifndef SAVE_STR
#define SAVE_STR(str) ((str==0)?("(null)"):(str))
#endif

#define BOUNDARY_LENGTH 18

#define MAX_HEADER_SIZE 4256
#define MAX_FILE_BUFFER_SIZE 4256

#define REQUEST_MAX_PATH_SIZE 1024
#define RESPONSE_MAX_DESC_SIZE 1024
      
#define URL_MAX_HOST_SIZE      120
#define URL_MAX_CONTEXT_SIZE  1024

/* TODO (#1#): find proper ports */
#define URL_DEFAULT_PORT_HTTP 80
#define URL_DEFAULT_PORT_HTTPS 81
#define URL_DEFAULT_PORT_FTP 120

/**
 *
 * Indicates the version of the used HTTP protocol.
 *
 */
typedef enum _http_version
{
  HTTP_1_0,
  HTTP_1_1                      /* default */
} http_version_t;


/**
 *
 * The set of common methods for HTTP/1.1 is defined below. Although this set
 * can be expanded, additional methods cannot be assumed to share the same
 * semantics for separately extended clients and servers.
 *
 * The Host request-header field MUST accompany all HTTP/1.1 requests.
 *
 * @see HTTP_HEADER_HOST
 *
 */
typedef enum _hreq_method
{
  /**
   *
   * The POST method is used to request that the origin server accept the entity
   * enclosed in the request as a new subordinate of the resource identified by
   * the Request-URI in the Request-Line. POST is designed to allow a uniform
   * method to cover the following functions:
   * - Annotation of existing resources;
   * - Posting a message to a bulletin board, newsgroup, mailing list, or
   *   similar group of articles;
   * - Providing a block of data, such as the result of submitting a form, to a
   *   data-handling process;
   * - Extending a database through an append operation.
   *
   */
 HTTP_REQUEST_POST,
  /**
   *
   * The GET method means retrieve whatever information (in the form of an entity)
   * is identified by the Request-URI. If the Request-URI refers to a
   * data-producing process, it is the produced data which shall be returned as
   * the entity in the response and not the source text of the process, unless
   * that text happens to be the output of the process.
   *
   */
  HTTP_REQUEST_GET,
  /**
   *
   * The OPTIONS method represents a request for information about the
   * communication options available on the request/response chain identified by
   * the Request-URI. This method allows the client to determine the options
   * and/or requirements associated with a resource, or the capabilities of a
   * server, without implying a resource action or initiating a resource
   * retrieval.
   *
   */
  HTTP_REQUEST_OPTIONS,
  /**
   *
   * The HEAD method is identical to GET except that the server MUST NOT return
   * a message-body in the response. The metainformation contained in the HTTP
   * headers in response to a HEAD request SHOULD be identical to the information
   * sent in response to a GET request. This method can be used for obtaining
   * metainformation about the entity implied by the request without transferring
   * the entity-body itself. This method is often used for testing hypertext
   * links for validity, accessibility, and recent modification.
   *
   */
  HTTP_REQUEST_HEAD,
  /**
   *
   * The PUT method requests that the enclosed entity be stored under the
   * supplied Request-URI. If the Request-URI refers to an already existing
   * resource, the enclosed entity SHOULD be considered as a modified version of
   * the one residing on the origin server. If the Request-URI does not point to
   * an existing resource, and that URI is capable of being defined as a new
   * resource by the requesting user agent, the origin server can create the
   * resource with that URI. If a new resource is created, the origin server MUST
   * inform the user agent via the 201 (Created) response. If an existing
   * resource is modified, either the 200 (OK) or 204 (No Content) response codes
   * SHOULD be sent to indicate successful completion of the request. If the
   * resource could not be created or modified with the Request-URI, an
   * appropriate error response SHOULD be given that reflects the nature of the
   * problem. The recipient of the entity MUST NOT ignore any Content-* (e.g.
   * Content-Range) headers that it does not understand or implement and MUST
   * return a 501 (Not Implemented) response in such cases.
   *
   */
  HTTP_REQUEST_PUT,
  /**
   *
   * The DELETE method requests that the origin server delete the resource
   * identified by the Request-URI. This method MAY be overridden by human
   * intervention (or other means) on the origin server. The client cannot be
   * guaranteed that the operation has been carried out, even if the status code
   * returned from the origin server indicates that the action has been completed
   * successfully. However, the server SHOULD NOT indicate success unless, at the
   * time the response is given, it intends to delete the resource or move it to
   * an inaccessible location.
   *
   */
  HTTP_REQUEST_DELETE,
  /**
   *
   * The TRACE method is used to invoke a remote, application-layer loop-back of
   * the request message. The final recipient of the request SHOULD reflect the
   * message received back to the client as the entity-body of a 200 (OK)
   * response. The final recipient is either the origin server or the first proxy
   * or gateway to receive a Max-Forwards value of zero (0) in the request (see
   * section 14.31). A TRACE request MUST NOT include an entity.
   *
   */
  HTTP_REQUEST_TRACE,
  /**
   *
   * This specification reserves the method name CONNECT for use with a proxy
   * that can dynamically switch to being a tunnel (e.g. SSL tunneling [44]).
   *
   */
  HTTP_REQUEST_CONNECT,
  HTTP_REQUEST_UNKOWN
} hreq_method_t;

/**
 *
 * The Status-Code element is a 3-digit integer result code of the attempt to
 * understand and satisfy the request. These codes are fully defined in section
 * 10. The Reason-Phrase is intended to give a short textual description of the
 * Status-Code. The Status-Code is intended for use by automata and the
 * Reason-Phrase is intended for the human user. The client is not required to
 * examine or display the Reason- Phrase. The first digit of the Status-Code
 * defines the class of response. The last two digits do not have any
 * categorization role. There are 5 values for the first digit: 
 *
 * - 1xx: Informational - Request received, continuing process
 * - 2xx: Success - The action was successfully received, understood, and
 *        accepted 
 * - 3xx: Redirection - Further action must be taken in order to complete the
 *        request
 * - 4xx: Client Error - The request contains bad syntax or cannot be fulfilled
 * - 5xx: Server Error - The server failed to fulfill an apparently valid request
 *
 * The individual values of the numeric status codes defined for HTTP/1.1, and an
 * example set of corresponding Reason-Phrase's, are presented below. The reason
 * phrases listed here are only recommendations -- they MAY be replaced by local
 * equivalents without affecting the protocol.
 *
 * HTTP status codes are extensible. HTTP applications are not required to
 * understand the meaning of all registered status codes, though such
 * understanding is obviously desirable. However, applications MUST understand
 * the class of any status code, as indicated by the first digit, and treat any
 * unrecognized response as being equivalent to the x00 status code of that class,
 * with the exception that an unrecognized response MUST NOT be cached. For
 * example, if an unrecognized status code of 431 is received by the client, it
 * can safely assume that there was something wrong with its request and treat
 * the response as if it had received a 400 status code. In such cases, user
 * agents SHOULD present to the user the entity returned with the response,
 * since that entity is likely to include human-readable information which will
 * explain the unusual status.
 *
 * @see http://www.ietf.org/rfc/rfc2616.txt
 *
 */
#define HTTP_STATUS_100_REASON_PHRASE	"Continue"
#define HTTP_STATUS_101_REASON_PHRASE	"Switching Protocols"
#define HTTP_STATUS_200_REASON_PHRASE	"OK"
#define HTTP_STATUS_201_REASON_PHRASE	"Created"
#define HTTP_STATUS_202_REASON_PHRASE	"Accepted"
#define HTTP_STATUS_203_REASON_PHRASE	"Non-Authoritative Information"
#define HTTP_STATUS_204_REASON_PHRASE	"No Content"
#define HTTP_STATUS_205_REASON_PHRASE	"Reset Content"
#define HTTP_STATUS_206_REASON_PHRASE	"Partial Content"
#define HTTP_STATUS_300_REASON_PHRASE	"Multiple Choices"
#define HTTP_STATUS_301_REASON_PHRASE	"Moved Permanently"
#define HTTP_STATUS_302_REASON_PHRASE	"Found"
#define HTTP_STATUS_303_REASON_PHRASE	"See Other"
#define HTTP_STATUS_304_REASON_PHRASE	"Not Modified"
#define HTTP_STATUS_305_REASON_PHRASE	"Use Proxy"
#define HTTP_STATUS_307_REASON_PHRASE	"Temporary Redirect"
#define HTTP_STATUS_400_REASON_PHRASE	"Bad Request"
#define HTTP_STATUS_401_REASON_PHRASE	"Unauthorized"
#define HTTP_STATUS_402_REASON_PHRASE	"Payment Required"
#define HTTP_STATUS_403_REASON_PHRASE	"Forbidden"
#define HTTP_STATUS_404_REASON_PHRASE	"Not Found"
#define HTTP_STATUS_405_REASON_PHRASE	"Method Not Allowed"
#define HTTP_STATUS_406_REASON_PHRASE	"Not Acceptable"
#define HTTP_STATUS_407_REASON_PHRASE	"Proxy Authentication Required"
#define HTTP_STATUS_408_REASON_PHRASE	"Request Time-out"
#define HTTP_STATUS_409_REASON_PHRASE	"Conflict"
#define HTTP_STATUS_410_REASON_PHRASE	"Gone"
#define HTTP_STATUS_411_REASON_PHRASE	"Length Required"
#define HTTP_STATUS_412_REASON_PHRASE	"Precondition Failed"
#define HTTP_STATUS_413_REASON_PHRASE	"Request Entity Too Large"
#define HTTP_STATUS_414_REASON_PHRASE	"Request-URI Too Large"
#define HTTP_STATUS_415_REASON_PHRASE	"Unsupported Media Type"
#define HTTP_STATUS_416_REASON_PHRASE	"Requested range not satisfiable"
#define HTTP_STATUS_417_REASON_PHRASE	"Expectation Failed"
#define HTTP_STATUS_500_REASON_PHRASE	"Internal Server Error"
#define HTTP_STATUS_501_REASON_PHRASE	"Not Implemented"
#define HTTP_STATUS_502_REASON_PHRASE	"Bad Gateway"
#define HTTP_STATUS_503_REASON_PHRASE	"Service Unavailable"
#define HTTP_STATUS_504_REASON_PHRASE	"Gateway Time-out"
#define HTTP_STATUS_505_REASON_PHRASE	"HTTP Version not supported"

/**
 *
 * hpairnode_t represents a pair (key, value) pair. This is also a linked list.
 *
 */
typedef struct hpair hpair_t;
struct hpair
{
  char *key;
  char *value;
  hpair_t *next;
};

/**
 *
 * The protocol types in enumeration format. Used in some other nanohttp objects
 * like hurl_t.
 *
 * @see hurl_t
 *
 */
typedef enum _hprotocol
{
  PROTOCOL_HTTP,
  PROTOCOL_HTTPS,
  PROTOCOL_FTP
} hprotocol_t;

/**
 *
 * The URL object. A representation of an URL like:
 *
 * [protocol]://[host]:[port]/[context]
 *
 * @see http://www.ietf.org/rfc/rfc2396.txt
 *
 */
typedef struct _hurl
{
  /**
   *
   * The transfer protocol. Note that only PROTOCOL_HTTP and PROTOCOL_HTTPS are
   * supported by nanohttp.
   *
   */
  hprotocol_t protocol;

  /**
   *
   * The port number. If no port number was given in the URL, one of the default
   * port numbers will be selected. 
   * - URL_HTTP_DEFAULT_PORT    
   * - URL_HTTPS_DEFAULT_PORT   
   * - URL_FTP_DEFAULT_PORT    
   *
   */
  short port;

  /**
   *
   * The hostname
   *
   */
  char host[URL_MAX_HOST_SIZE];

  /**
   *
   * The string after the hostname.
   *
   */
  char context[URL_MAX_CONTEXT_SIZE];
} hurl_t;

#ifdef __cplusplus
extern "C" {
#endif

/**
 *
 * Creates a new pair with the given parameters. Both strings key and value will
 * be cloned while creating the pair. 
 *
 * @param key the key of the (key,value) pair
 * @param value the value of the (key,value) pair
 * @param next next pair node in the linked list
 *
 * @returns A newly crated hpair_t object. Use hpair_free() or hpair_free_deep()
 *          to free the pair.
 *
 */
extern hpair_t *hpairnode_new(const char *key, const char *value, hpair_t * next);

/**
 *
 * Creates a new pair from a given string. This function will split 'str' with
 * the found first delimiter 'delim'. The 'value' field  of the newly created
 * pair will have the value "", if no delimiter was found/ Whitespaces (' ') will
 * be removed from the beginnig of the parsed value.
 *
 * @param str A string to parse
 * @param delim a delimiter to use while splitting into key,value
 * @param next next pair node in the linked list
 *
 * @returns A newly crated hpair_t object. Use hpair_free() or hpair_free_deep()
 *          to free the pair.
 *
 */
extern hpair_t *hpairnode_parse(const char *str, const char *delim, hpair_t * next);

/**
 *
 * Frees a given pair.
 *
 * @param pair the pair to free
 *
 */
extern void hpairnode_free(hpair_t * pair);

/**
 *
 * Makes a deep free operation. All pairnodes, beginning with the given pari, in
 * the linked list will be destroyed. 
 *
 * @param pair the pair to start to free the linked list
 *
 */
extern void hpairnode_free_deep(hpair_t * pair);

/**
 *
 * Returns the (key,value) pair, which key is the given 'key'.
 *
 * @param pair the first pair to start to search from.
 * @param key key to find the in the pair.
 * @returns if a value will be found, this function will 
 *
 * @return the value (do not free this string) or NULL if no pair was found with
 *         the key 'key'.
 *
 */
extern char *hpairnode_get(hpair_t * pair, const char *key);

/**
 *
 * Returns the (key,value) pair, which key is the given 'key'. The case will be
 * ignored while comparing the key strings.
 *
 * @param pair the first pair to start to search from.
 * @param key key to find the in the pair.
 * @returns if a value will be found, this function will 
 *
 * @return the value (do not free this string) or NULL if no pair was found with
 *         the key 'key'.
 *
 */
extern char *hpairnode_get_ignore_case(hpair_t * pair, const char *key);

/**
 *
 * This function will create a new pair and fills the (key,value) fields of a
 * given pair. Note that the 'next' field will not be copied.
 *
 * @param src the source pair object to copy.
 *
 * @returns a newly created pair with the same (key,value) pairs as in 'src'.
 *          This fields will be cloned. The'next' field will be set to NULL.
 *
 * @see hpairnode_copy_deep
 *
 */
extern hpair_t *hpairnode_copy(const hpair_t * src);

/**
 *
 * Clones the hole linked list. 
 *
 * @param src the source pair object to copy from
 *
 * @return the first object in the linked list. 
 *
 * @see hpairnode_copy
 *
 */
extern hpair_t *hpairnode_copy_deep(const hpair_t * src);

/**
 *
 * Debug functions
 *
 */
extern void hpairnode_dump_deep(hpair_t * pair);
extern void hpairnode_dump(hpair_t * pair);

/**
 *
 * Parses the given 'urlstr' and fills the given hurl_t object.
 *
 * @param obj the destination URL object to fill
 * @param url the URL in string format
 *
 * @returns H_OK on success or one of the following otherwise
 *          - URL_ERROR_UNKNOWN_PROTOCOL 
 *          - URL_ERROR_NO_PROTOCOL 
 *          - URL_ERROR_NO_HOST 
 *
 */
extern herror_t hurl_parse(hurl_t * obj, const char *url);

/**
 *
 * Object representation of the content-type field in a HTTP header: 
 *
 * Example:
 *
 * text/xml; key="value" key2="value2' ...
 *
 */
typedef struct _content_type
{
  char type[128];
  hpair_t *params;
} content_type_t;

/**
 *
 * Parses the given string and creates a new ccontent_type_t object. 
 *
 * @param content_type_str the string representation of the content-type field in
 *        a HTTP header.
 *
 * @return A newly created content_type_t object. Free this object with
 *         content_type_free();
 *
 * @see content_type_free
 */
extern content_type_t *content_type_new(const char *content_type_str);

/**
 *
 * Frees the given content_type_t object
 *
 */
extern void content_type_free(content_type_t * ct);

/**
 *
 * part. Attachment
 *
 */
struct part_t
{
  char id[250];
  char location[250];
  hpair_t *header;
  char content_type[128];
  char transfer_encoding[128];
  char filename[250];
  struct part_t *next;
  int deleteOnExit;             /* default is 0 */
};

extern struct part_t *part_new(const char *id, const char *filename, const char *content_type, const char *transfer_encoding, struct part_t * next);

extern void part_free(struct part_t * part);

/**
 *
 * Attachments
 *
 */
struct attachments_t
{
  struct part_t *parts;
  struct part_t *last;
  struct part_t *root_part;
};

/* should be used internally */
extern struct attachments_t *attachments_new(void);

/**
 *
 * Free a attachment. Create attachments with MIME and DIME (DIME is not
 * supported yet).
 *
 * @see mime_get_attachments
 *
 */
extern void attachments_free(struct attachments_t * message);
extern void attachments_add_part(struct attachments_t * attachments, struct part_t * part);

#ifdef __cplusplus
}
#endif

#endif