Exemple #1
0
/* IN ANY THREAD */
void
hio_output_stream_error(HioOutputStream *stream)
{
    /* incrementing error and closing will make
     * hio_output_stream_is_done() return TRUE.  At that point we need
     * to be sure done-notification happens if it hasn't.
     */

    g_atomic_int_inc(&stream->errored);

    /* close to ignore any further writes.  we want to
     * silently eat them, so errors don't have to be handled
     * by the writer. (Though writer could do so, if desired.)
     */
    hio_output_stream_close(stream);

    /* Delete any leftover buffers, in our task thread. This would not
     * work if we were already done-notified because completion would
     * be unblocked and we can't add watchers to a completed
     * task. There's no buffers if we're already done, anyhow.
     */
    if (g_atomic_int_get(&stream->done_notified) == 0) {
        hrt_task_add_immediate(stream->task,
                               on_error_drop_all_buffers,
                               g_object_ref(stream),
                               g_object_unref);
    }
}
Exemple #2
0
void
hio_response_http_send_headers(HioResponseHttp *http)
{
    /* FIXME send actual headers */

    g_mutex_lock(http->headers_lock);

    /* Sending headers twice is allowed, for example request handlers
     * can do it early, but a container might do it automatically
     * after the request handler runs. Only first send does anything
     * of course and it's an error to try to set headers after we
     * already sent them.
     */
    if (http->headers_sent) {
        g_mutex_unlock(http->headers_lock);
        return;
    }
    http->headers_sent = TRUE;

    write_to_header(http, "HTTP/1.1 200 OK\r\n");
    write_to_header(http, "Date: Wed, 21 Jul 2010 02:24:36 GMT\r\n");
    write_to_header(http, "Server: hrt/" VERSION "\r\n");
    write_to_header(http, "Last-Modified: Tue, 01 Dec 2009 23:10:05 GMT\r\n");
    write_to_header(http, "Content-Type: text/html\r\n");
    write_to_header(http, "Connection: close\r\n");
    write_to_header(http, "\r\n");

    hio_output_stream_close(http->header_stream);

    g_mutex_unlock(http->headers_lock);
}
Exemple #3
0
static gboolean
on_write_stream_task(HrtTask        *task,
                     HrtWatcherFlags flags,
                     void           *data)
{
    WriteTaskData *wtd = data;

    write_stream(wtd->stream, wtd->desc);

    hio_output_stream_close(wtd->stream);

    return FALSE;
}
Exemple #4
0
/* IN OUR TASK THREAD */
static gboolean
on_ready_to_write(HrtTask        *task,
                  HrtWatcherFlags flags,
                  void           *data)
{
    HioOutputStream *stream;

    stream = HIO_OUTPUT_STREAM(data);

    HRT_ASSERT_IN_TASK_THREAD(stream->task);

    /* ensure_current_buffer() also does drop_all_buffers()
     * if an error has occurred to be sure current_buffer
     * is NULL on error.
     */
    ensure_current_buffer(stream, NULL);

    if (stream->current_buffer != NULL) {
        if (hrt_buffer_write(stream->current_buffer,
                             g_atomic_int_get(&stream->fd),
                             &stream->current_buffer_remaining)) {
            if (stream->current_buffer_remaining == 0) {
                /* get a new current buffer, deleting this one */
                ensure_current_buffer(stream, stream->current_buffer);
            }
        } else {
            /* ERROR */
            g_atomic_int_inc(&stream->errored);
            hio_output_stream_close(stream);
            drop_all_buffers(stream);
        }
    }

    if (stream->current_buffer == NULL) {
        /* if no new buffer, we probably need removing. */
        check_write_watcher(stream);
    }

    notify_if_done(stream);

    /* stay installed until check_write_watcher() removes us. */
    return TRUE;
}
Exemple #5
0
void
hio_response_http_close(HioResponseHttp *http)
{
    hio_output_stream_close(http->body_stream);
}