aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-http-stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/camel-http-stream.c')
-rw-r--r--camel/camel-http-stream.c219
1 files changed, 114 insertions, 105 deletions
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;
+}