aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog6
-rw-r--r--camel/Makefile.am2
-rw-r--r--camel/camel-http-stream.c219
-rw-r--r--camel/camel-http-stream.h6
-rw-r--r--camel/camel-mime-utils.c4
-rw-r--r--camel/camel-mime-utils.h2
-rw-r--r--camel/camel-types.h1
7 files changed, 132 insertions, 108 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 64e6a83717..7a5b6e1fe6 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,5 +1,11 @@
2002-02-04 Jeffrey Stedfast <fejj@ximian.com>
+ * camel-http-stream.c (stream_read): Use camel_mime_parser_read to
+ read internal parser data.
+ (camel_http_stream_get_content_type): Implemented.
+
+ * camel-mime-utils.c (header_decode_int): Made public.
+
* camel-http-stream.[c,h]: Added. New stream for HTTP requests
(currently supported are GET and HEAD).
diff --git a/camel/Makefile.am b/camel/Makefile.am
index 751f293709..95b45f07e7 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -37,6 +37,7 @@ libcamel_la_SOURCES = \
camel-folder-thread.c \
camel-folder.c \
camel-html-parser.c \
+ camel-http-stream.c \
camel-internet-address.c \
camel-lock.c \
camel-lock-client.c \
@@ -125,6 +126,7 @@ libcamelinclude_HEADERS = \
camel-folder-summary.h \
camel-folder-thread.h \
camel-folder.h \
+ camel-http-stream.h \
camel-internet-address.h \
camel-lock.h \
camel-lock-client.h \
diff --git a/camel/camel-http-stream.c b/camel/camel-http-stream.c
index b7880df2e2..3dbccc88e5 100644
--- a/camel/camel-http-stream.c
+++ b/camel/camel-http-stream.c
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include <errno.h>
#include "camel-http-stream.h"
@@ -72,21 +73,22 @@ camel_http_stream_class_init (CamelHttpStreamClass *camel_http_stream_class)
static void
camel_http_stream_init (gpointer object, gpointer klass)
{
- CamelHttpStream *stream = CAMEL_HTTP_STREAM (object);
+ CamelHttpStream *http = CAMEL_HTTP_STREAM (object);
- stream->content_type = NULL;
- stream->headers = NULL;
- stream->service = NULL;
- stream->url = NULL;
- stream->raw = NULL;
+ http->parser = NULL;
+ http->content_type = NULL;
+ http->headers = NULL;
+ http->service = NULL;
+ http->url = NULL;
+ http->raw = NULL;
}
static void
-headers_free (http->headers)
+headers_free (struct _header_raw *headers)
{
struct _header_raw *node, *next;
- node = http->headers;
+ node = headers;
while (node) {
next = node->next;
g_free (node->name);
@@ -99,22 +101,25 @@ headers_free (http->headers)
static void
camel_http_stream_finalize (CamelObject *object)
{
- CamelHttpStream *stream = CAMEL_HTTP_STREAM (object);
+ CamelHttpStream *http = CAMEL_HTTP_STREAM (object);
+
+ if (http->parser)
+ camel_object_unref (CAMEL_OBJECT (http->parser));
- if (stream->content_type)
- header_content_type_unref (stream->content_type);
+ if (http->content_type)
+ header_content_type_unref (http->content_type);
- if (stream->headers)
- headers_free (stream->headers);
+ if (http->headers)
+ headers_free (http->headers);
- if (stream->service)
- camel_object_unref (CAMEL_OBJECT (service));
+ if (http->service)
+ camel_object_unref (CAMEL_OBJECT (http->service));
- if (stream->url)
- camel_url_free (stream->url);
+ if (http->url)
+ camel_url_free (http->url);
- if (stream->raw)
- camel_object_unref (CAMEL_OBJECT (stream->raw));
+ if (http->raw)
+ camel_object_unref (CAMEL_OBJECT (http->raw));
}
@@ -152,7 +157,7 @@ camel_http_stream_new (CamelHttpMethod method, CamelService *service, CamelURL *
CamelHttpStream *stream;
char *str;
- g_return_val_if_fail (!CAMEL_IS_SERVICE (service), NULL);
+ g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL);
g_return_val_if_fail (url != NULL, NULL);
stream = CAMEL_HTTP_STREAM (camel_object_new (camel_http_stream_get_type ()));
@@ -219,30 +224,29 @@ http_connect (CamelService *service, CamelURL *url)
static const char *
http_next_token (const unsigned char *in)
{
- const char *inptr = in;
+ const unsigned char *inptr = in;
- while (*inptr && !is_lwsp (*inptr))
+ while (*inptr && !isspace ((int) *inptr))
inptr++;
- while (*inptr && is_lwsp (*inptr))
+ while (*inptr && isspace ((int) *inptr))
inptr++;
- return inptr;
+ return (const char *) inptr;
}
static int
http_get_headers (CamelHttpStream *http)
{
- CamelMimeParser *mp;
struct _header_raw *headers, *node, *tail;
const char *type, *token;
+ char buffer[4096], *buf;
int status, len, err;
- char *buf;
- if (camel_stream_buffer_gets (CAMEL_STREAM_BUFFER (http->raw), buffer, 4096) <= 0)
+ if (camel_stream_buffer_gets (CAMEL_STREAM_BUFFER (http->raw), buffer, sizeof (buffer)) <= 0)
return -1;
- if (!stncasecmp (buffer, "HTTP/", 5)) {
+ if (!strncasecmp (buffer, "HTTP/", 5)) {
token = http_next_token (buffer);
status = header_decode_int (&token);
/* FIXME: don't just check for 200 */
@@ -251,15 +255,15 @@ http_get_headers (CamelHttpStream *http)
} else
goto exception;
- mp = camel_mime_parser_new ();
- camel_mime_parser_init_with_stream (mp, http->raw);
+ http->parser = camel_mime_parser_new ();
+ camel_mime_parser_init_with_stream (http->parser, http->raw);
- switch (camel_mime_parser_step (mp, &buf, &len)) {
+ switch (camel_mime_parser_step (http->parser, &buf, &len)) {
case HSCAN_MESSAGE:
case HSCAN_HEADER:
case HSCAN_MULTIPART:
/* we have the headers, build them into 'us' */
- headers = camel_mime_parser_headers_raw (mp);
+ headers = camel_mime_parser_headers_raw (http->parser);
/* if content-type exists, process it first, set for fallback charset in headers */
if (http->content_type)
@@ -289,14 +293,18 @@ http_get_headers (CamelHttpStream *http)
break;
default:
- g_warning ("Invalid state encountered???: %d", camel_mime_parser_state (mp));
+ g_warning ("Invalid state encountered???: %d", camel_mime_parser_state (http->parser));
}
- err = camel_mime_parser_errno (mp);
- camel_object_unref (CAMEL_OBJECT (mp));
+ err = camel_mime_parser_errno (http->parser);
- if (err != 0)
+ if (err != 0) {
+ camel_object_unref (CAMEL_OBJECT (http->parser));
+ http->parser = NULL;
goto exception;
+ }
+
+ camel_mime_parser_drop_step (http->parser);
return 0;
@@ -307,105 +315,82 @@ http_get_headers (CamelHttpStream *http)
return -1;
}
-
-static ssize_t
-stream_read (CamelStream *stream, char *buffer, size_t n)
+static int
+http_method_invoke (CamelHttpStream *http)
{
- CamelHttpStream *http = CAMEL_HTTP_STREAM (stream);
+ const char *method = NULL;
+ char *url;
- if (http->method != CAMEL_HTTP_METHOD_GET || http->method != CAMEL_HTTP_METHOD_HEAD) {
- errno = ENOTSUPP;
- return -1;
+ switch (http->method) {
+ case CAMEL_HTTP_METHOD_GET:
+ method = "GET";
+ break;
+ case CAMEL_HTTP_METHOD_HEAD:
+ method = "HEAD";
+ break;
+ default:
+ g_assert_not_reached ();
}
- if (!http->raw) {
- const char *method;
- char *url;
-
- http->raw = http_connect (http->service, http->url);
- if (!http->raw)
- return -1;
-
- switch (http->method) {
- case CAMEL_HTTP_METHOD_GET:
- method = "GET";
- break;
- case CAMEL_HTTP_METHOD_HEAD:
- method = "HEAD";
- break;
- }
-
- url = camel_url_to_string (http->url, 0);
- if (camel_stream_printf (http->raw, "%s %s HTTP/1.1\r\nHost: %s\r\n\r\n",
- method, http->url->path ? http->url->path : "/",
- http->url->host) == -1 ||
- camel_stream_flush (http->raw) == -1) {
- camel_object_unref (CAMEL_OBJECT (http->raw));
- http->raw = NULL;
- return -1;
- }
- g_free (url);
-
- if (http_get_headers (http) == -1)
- return -1;
+ url = camel_url_to_string (http->url, 0);
+ if (camel_stream_printf (http->raw, "%s %s HTTP/1.1\r\nHost: %s\r\n\r\n",
+ method, http->url->path ? http->url->path : "/",
+ http->url->host) == -1 ||
+ camel_stream_flush (http->raw) == -1) {
+ camel_object_unref (CAMEL_OBJECT (http->raw));
+ http->raw = NULL;
+ return -1;
}
+ g_free (url);
- return camel_stream_read (http->raw, buffer, n);
+ return 0;
}
static ssize_t
-stream_write (CamelStream *stream, const char *buffer, size_t n)
+stream_read (CamelStream *stream, char *buffer, size_t n)
{
CamelHttpStream *http = CAMEL_HTTP_STREAM (stream);
+ const char *parser_buf;
+ ssize_t nread;
- if (http->method == CAMEL_HTTP_METHOD_GET || http->method == CAMEL_HTTP_METHOD_HEAD) {
- errno = ENOTSUPP;
+ if (http->method != CAMEL_HTTP_METHOD_GET && http->method != CAMEL_HTTP_METHOD_HEAD) {
+ errno = EIO;
return -1;
}
- return -1;
-#if 0
if (!http->raw) {
- const char *method;
- char *url;
-
http->raw = http_connect (http->service, http->url);
if (!http->raw)
return -1;
- switch (http->method) {
- case CAMEL_HTTP_METHOD_PUT:
- method = "PUT";
- break;
- case CAMEL_HTTP_METHOD_POST:
- method = "POST";
- break;
- }
-
- url = camel_url_to_string (http->url, 0);
- if (camel_stream_printf (http->raw, "%s %s HTTP/1.1\r\nHost: %s\r\n\r\n",
- method, http->url->path ? http->url->path : "/",
- http->url->host) == -1 ||
- camel_stream_flush (http->raw) == -1) {
- camel_object_unref (CAMEL_OBJECT (http->raw));
- http->raw = NULL;
+ if (http_method_invoke (http) == -1)
return -1;
- }
- g_free (url);
if (http_get_headers (http) == -1)
return -1;
}
- return camel_stream_write (http->raw, buffer, n);
-#endif
+ nread = camel_mime_parser_read (http->parser, &parser_buf, n);
+
+ if (nread > 0)
+ memcpy (buffer, parser_buf, nread);
+
+ return nread;
+}
+
+static ssize_t
+stream_write (CamelStream *stream, const char *buffer, size_t n)
+{
+ return -1;
}
static int
stream_flush (CamelStream *stream)
{
- if (stream->raw)
- return camel_stream_flush (stream->raw);
+ CamelHttpStream *http = (CamelHttpStream *) stream;
+
+ if (http->raw)
+ return camel_stream_flush (http->raw);
else
return 0;
}
@@ -413,7 +398,7 @@ stream_flush (CamelStream *stream)
static int
stream_close (CamelStream *stream)
{
- CamelHttpStream *http = CAMEL_HTTP_STREAM (stream);
+ CamelHttpStream *http = (CamelHttpStream *) stream;
if (http->raw) {
if (camel_stream_close (http->raw) == -1)
@@ -439,3 +424,27 @@ stream_reset (CamelStream *stream)
return 0;
};
+
+
+CamelContentType *
+camel_http_stream_get_content_type (CamelHttpStream *http_stream)
+{
+ g_return_val_if_fail (CAMEL_IS_HTTP_STREAM (http_stream), NULL);
+
+ if (!http_stream->content_type && !http_stream->raw) {
+ http_stream->raw = http_connect (http_stream->service, http_stream->url);
+ if (!http_stream->raw)
+ return NULL;
+
+ if (http_method_invoke (http_stream) == -1)
+ return NULL;
+
+ if (http_get_headers (http_stream) == -1)
+ return NULL;
+ }
+
+ if (http_stream->content_type)
+ header_content_type_ref (http_stream->content_type);
+
+ return http_stream->content_type;
+}
diff --git a/camel/camel-http-stream.h b/camel/camel-http-stream.h
index 1ffa18d4bd..ac4b2c2a62 100644
--- a/camel/camel-http-stream.h
+++ b/camel/camel-http-stream.h
@@ -29,6 +29,7 @@ extern "C" {
#pragma }
#endif /* __cplusplus */
+#include <camel/camel-mime-parser.h>
#include <camel/camel-mime-utils.h>
#include <camel/camel-service.h>
#include <camel/camel-stream.h>
@@ -52,11 +53,12 @@ typedef enum {
typedef struct _CamelHttpStreamClass CamelHttpStreamClass;
-typedef struct _CamelHttpStream CamelHttpStream;
struct _CamelHttpStream {
CamelStream parent_object;
+ CamelMimeParser *parser;
+
CamelContentType *content_type;
struct _header_raw *headers;
@@ -79,6 +81,8 @@ CamelType camel_http_stream_get_type (void);
/* public methods */
CamelStream *camel_http_stream_new (CamelHttpMethod method, CamelService *service, CamelURL *url);
+CamelContentType *camel_http_stream_get_content_type (CamelHttpStream *http_stream);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c
index 9f0c5fa662..660cc3575d 100644
--- a/camel/camel-mime-utils.c
+++ b/camel/camel-mime-utils.c
@@ -1815,8 +1815,8 @@ header_decode_value(const char **in)
return NULL;
}
-/* shoudl this return -1 for no int? */
-static int
+/* should this return -1 for no int? */
+int
header_decode_int(const char **in)
{
const char *inptr = *in;
diff --git a/camel/camel-mime-utils.h b/camel/camel-mime-utils.h
index 7795741c48..50a3eb856b 100644
--- a/camel/camel-mime-utils.h
+++ b/camel/camel-mime-utils.h
@@ -160,6 +160,8 @@ char *header_unfold (const char *in);
/* decode a header which is a simple token */
char *header_token_decode (const char *in);
+int header_decode_int (const char **in);
+
/* decode/encode a string type, like a subject line */
char *header_decode_string (const char *in, const char *default_charset);
char *header_encode_string (const unsigned char *in);
diff --git a/camel/camel-types.h b/camel/camel-types.h
index 6765424b39..86da09cae4 100644
--- a/camel/camel-types.h
+++ b/camel/camel-types.h
@@ -71,6 +71,7 @@ typedef struct _CamelTcpStream CamelTcpStream;
typedef struct _CamelTcpStreamRaw CamelTcpStreamRaw;
typedef struct _CamelTcpStreamSSL CamelTcpStreamSSL;
typedef struct _CamelTcpStreamOpenSSL CamelTcpStreamOpenSSL;
+typedef struct _CamelHttpStream CamelHttpStream;
typedef struct _CamelTransport CamelTransport;
#ifdef __cplusplus