Пример #1
0
/**
 * Serves a PNG file of the hash.
 */
void route_image(evhtp_request_t *req, void *arg) {
    // redisReply *reply;

    evhtp_uri_t *uri = req->uri;

    int side = 128;
    char *hash = "";

    char *res = uri->path->full;
    int ind = 0;
    res = strtok((char *) res, "/");
    while (res != NULL) {
        if (ind == 0) {
            if (strlen(res) == 32) {
                hash = res;
            } else if (strcmp(res, "avatar") == 0) {
                ind--;
            } else {
                route_400(req);
                return;
            }
        }
        if (ind == 1) {
            side = atoi(res);
            if (side == 0) {
                side = defsize;
            } else if (side < minsize) {
                side = minsize;
            } else if (side > maxsize) {
                side = maxsize;
            }
        }
        res = strtok(NULL, "/");
        ind++;
    }

    char *etag = malloc(sizeof(char) * 1024);
    sprintf(etag, "\"%s-%d\"", hash, side);
    
    evhtp_kv_t *etagin = evhtp_headers_find_header(req->headers_in, "If-None-Match");
    if(etagin && strcmp(etag, etagin->val) == 0) {
        free(etag);
        evhtp_send_reply(req, 304);
        return;
    }

    make_image(hash, req->buffer_out, side);
    evhtp_headers_add_header(req->headers_out,
            evhtp_header_new("Content-Type", "image/png", 0, 0));
    evhtp_headers_add_header(req->headers_out,
            evhtp_header_new("Cache-Control", "public", 0, 0));
    evhtp_headers_add_header(req->headers_out,
            evhtp_header_new("ETag", etag, 0, 1));
    free(etag);
    evhtp_send_reply(req, 200);
}
Пример #2
0
void
zxy_send_content(
        zxy_request_context *context,
        const std::string& content
        )
{
    evhtp_header_t *header = evhtp_headers_find_header(
            context->request->headers_out,
            "Content-Type"
            );
    if ( header == NULL )
    {
        zxy_add_http_header(context, "Content-Type", "text/html");
    }
    evbuffer_add(context->request->buffer_out, content.c_str(), content.size());
}
Пример #3
0
void
zxy_printf_content(
        zxy_request_context *context,
        const char* fmt,
        ...
        )
{
    evhtp_header_t *header = evhtp_headers_find_header(
            context->request->headers_out,
            "Content-Type"
            );
    if ( header == NULL )
    {
        zxy_add_http_header(context, "Content-Type", "text/html");
    }
    va_list args;
    va_start(args, fmt);
    evbuffer_add_vprintf(context->request->buffer_out, fmt, args);
    va_end(args);
}
Пример #4
0
void
evhtp_send_reply_chunk_start(evhtp_request_t * request, evhtp_res code) {
    evhtp_header_t * content_len;

    if (evhtp_response_needs_body(code, request->method)) {
        content_len = evhtp_headers_find_header(request->headers_out, "Content-Length");

        switch (request->proto) {
            case EVHTP_PROTO_11:

                /*
                 * prefer HTTP/1.1 chunked encoding to closing the connection;
                 * note RFC 2616 section 4.4 forbids it with Content-Length:
                 * and it's not necessary then anyway.
                 */

                evhtp_kv_rm_and_free(request->headers_out, content_len);
                request->chunked = 1;
                break;
            case EVHTP_PROTO_10:
                /*
                 * HTTP/1.0 can be chunked as long as the Content-Length header
                 * is set to 0
                 */
                evhtp_kv_rm_and_free(request->headers_out, content_len);

                evhtp_headers_add_header(request->headers_out,
                                         evhtp_header_new("Content-Length", "0", 0, 0));

                request->chunked = 1;
                break;
            default:
                request->chunked = 0;
                break;
        } /* switch */
    } else {
        request->chunked = 0;
    }

    if (request->chunked == 1) {
        evhtp_headers_add_header(request->headers_out,
                                 evhtp_header_new("Transfer-Encoding", "chunked", 0, 0));

        /*
         * if data already exists on the output buffer, we automagically convert
         * it to the first chunk.
         */
        if (evbuffer_get_length(request->buffer_out) > 0) {
            char lstr[128];
            int  sres;

            sres = snprintf(lstr, sizeof(lstr), "%x\r\n",
                            (unsigned)evbuffer_get_length(request->buffer_out));

            if (sres >= sizeof(lstr) || sres < 0) {
                /* overflow condition, shouldn't ever get here, but lets
                 * terminate the connection asap */
                goto end;
            }

            evbuffer_prepend(request->buffer_out, lstr, strlen(lstr));
            evbuffer_add(request->buffer_out, "\r\n", 2);
        }
    }

end:
    evhtp_send_reply_start(request, code);
} /* evhtp_send_reply_chunk_start */