示例#1
0
文件: lisod.c 项目: ledinhminh/Lisod
/******************************************************************************
* subroutine: serve_post                                                      *
* purpose:    return response for POST request                                *
* parameters: client_fd - client descriptor                                   *
*             context   - a pointer refers to HTTP context                    *
*             is_closed - an indicator if the current transaction is closed   *
* return:     none                                                            *
******************************************************************************/
void serve_post(int client_fd, HTTPContext *context, int *is_closed)
{
    struct tm tm;
    struct stat sbuf;
    time_t now;
    char   buf[BUF_SIZE], dbuf[MIN_LINE]; 

    // check file existence
    if (stat(context->filename, &sbuf) == 0)
    {
        serve_get(client_fd, context, is_closed);
        return;
    }

    // get time string
    now = time(0);
    tm = *gmtime(&now);
    strftime(dbuf, MIN_LINE, "%a, %d %b %Y %H:%M:%S %Z", &tm);

    // send response headers to client
    sprintf(buf, "HTTP/1.1 204 No Content\r\n");
    sprintf(buf, "%sDate: %s\r\n", buf, dbuf);
    sprintf(buf, "%sServer: Liso/1.0\r\n", buf);
    if (is_closed) sprintf(buf, "%sConnection: close\r\n", buf);
    sprintf(buf, "%sContent-Length: 0\r\n", buf);
    sprintf(buf, "%sContent-Type: text/html\r\n", buf);
    send(client_fd, buf, strlen(buf), 0);
}
示例#2
0
文件: lisod.c 项目: ledinhminh/Lisod
/******************************************************************************
* subroutine: process_request                                                 *
* purpose:    handle a single request and return responses                    *
* parameters: id        - the index of the client in the pool                 *
*             p         - a pointer of pool struct                            *
*             is_closed - idicator if the transaction is closed               *
* return:     none                                                            *
******************************************************************************/
void process_request(int id, pool *p, int *is_closed)
{
    HTTPContext *context = (HTTPContext *)calloc(1, sizeof(HTTPContext));

    Log("Start processing request. \n");

    // parse request line (get method, uri, version)
    if (parse_requestline(id, p, context, is_closed) < 0) goto Done;

    // check HTTP method (support GET, POST, HEAD now)
    if (strcasecmp(context->method, "GET")  && 
        strcasecmp(context->method, "HEAD") && 
        strcasecmp(context->method, "POST"))
    {
        *is_closed = 1;
        serve_error(p->clientfd[id], "501", "Not Implemented",
                   "The method is not valid or not implemented by the server",
                    *is_closed); 
        goto Done;
    }

    // check HTTP version
    if (strcasecmp(context->version, "HTTP/1.1"))
    {
        *is_closed = 1;
        serve_error(p->clientfd[id], "505", "HTTP Version not supported",
                    "HTTP/1.0 is not supported by Liso server", *is_closed);  
        goto Done;
    }

    // parse uri (get filename and parameters if any)
    parse_uri(context);
   
    // parse request headers 
    if (parse_requestheaders(id, p, context, is_closed) < 0) goto Done;

    // for POST, parse request body
    if (!strcasecmp(context->method, "POST"))
        if (parse_requestbody(id, p, context, is_closed) < 0) goto Done;

    // send response 
    if (!strcasecmp(context->method, "GET"))
        serve_get(p->clientfd[id], context, is_closed); 
    else if (!strcasecmp(context->method, "POST")) 
        serve_post(p->clientfd[id], context, is_closed);
    else if (!strcasecmp(context->method, "HEAD")) 
        serve_head(p->clientfd[id], context, is_closed);

    Done:
    free(context); 
    Log("End of processing request. \n");
}
示例#3
0
ec_cbrc_t serve(ec_server_t *srv, void *u0, struct timeval *tv, bool resched)
{
    ec_mt_t mta[16];
    size_t mta_sz = sizeof mta / sizeof(ec_mt_t);
    ec_rep_t *rep;
    ec_res_t *res;
    char uri[U_URI_STRMAX];
    bool is_proxy;

    u_unused_args(u0);

    /* Get the requested URI and method. */
    dbg_if (ec_request_get_uri(srv, uri, &is_proxy) == NULL);
    ec_method_t method = ec_server_get_method(srv);

    CHAT("%s %s", ec_method_str(method), uri);

    /* Tell'em to use test/proxy to support Proxy-Uri's. */
    if (is_proxy)
    {
        dbg_if (ec_response_set_code(srv, EC_PROXYING_NOT_SUPPORTED));
        return EC_CBRC_READY;
    }

    /* See if configured for separate responses. */
    if (resched == false && g_ctx.sep.tv_sec)
    {
        *tv = g_ctx.sep;
        u_con("reschedule %s() for %s in %llu seconds",
              __func__, uri, (long long) g_ctx.sep.tv_sec);
        return EC_CBRC_WAIT;
    }

    /* See if it is a query for the /.well-known/core URI. */
    if (!strcasecmp(ec_request_get_uri_path(srv), "/.well-known/core"))
    {
        (void) serve_wkc(srv, method);
        return EC_CBRC_READY;
    }

    /* Get Accept'able media types. */
    dbg_err_if(ec_request_get_acceptable_media_types(srv, mta, &mta_sz));

    /* Try to retrieve a representation that fits client request. */
    rep = ec_filesys_get_suitable_rep(g_ctx.fs, ec_server_get_url(srv), mta, 
            mta_sz, NULL);

    /* If found, craft the response. */
    if (rep)
    {
        dbg_err_if((res = ec_rep_get_res(rep)) == NULL);

        /* Make sure resource supports the requested method.
         * Bypass check for Proxy-Uri requests because of Publish admin
         * operations (will be checked in PUT/DELETE handlers.) */
        if (!ec_request_via_proxy(srv)
                && ec_resource_check_method(res, method))
        {
            (void) ec_response_set_code(srv, EC_METHOD_NOT_ALLOWED);
            return EC_CBRC_READY;
        }

        switch (method)
        {
            case EC_COAP_GET:
                (void) serve_get(srv, rep);
                return EC_CBRC_READY;

            case EC_COAP_DELETE:
                (void) serve_delete(srv, uri);
                return EC_CBRC_READY;

            case EC_COAP_PUT:
                (void) serve_put(srv, rep);
                return EC_CBRC_READY;

            case EC_COAP_POST:
                (void) serve_post(srv);
                return EC_CBRC_READY;

            default:
                ec_response_set_code(srv, EC_NOT_IMPLEMENTED);
                return EC_CBRC_READY;
        }
    }
    else
        (void) ec_response_set_code(srv, EC_NOT_FOUND);

    return EC_CBRC_READY;
err:
    return EC_CBRC_ERROR;
}