Example #1
0
static int Request_is_websocket(Request *req)
{
    bstring upgrade,connection;

    if(req->ws_flags != 0)
    {
        return req->ws_flags == 1;
    }

    if (Request_get(req, &WS_SEC_WS_KEY) !=NULL &&
        Request_get(req, &WS_SEC_WS_VER) !=NULL &&
        Request_get(req, &WS_HOST) !=NULL &&
        (upgrade = Request_get(req, &WS_UPGRADE)) != NULL &&
        (connection = Request_get(req, &WS_CONNECTION)) != NULL)
    {
        if (BSTR_ERR != binstrcaseless(connection,0,&WS_UPGRADE) &&
                !bstrcmp(upgrade,&WS_WEBSOCKET))
        {
            req->ws_flags =1;
            return 1;
        }
    }
    req->ws_flags =2;
    return 0;
}
Example #2
0
static inline bstring Dir_calculate_response(Request *req, FileRecord *file)
{
    int if_unmodified_since = 0;
    int if_modified_since = 0;
    bstring if_match = NULL;
    bstring if_none_match = NULL;

    if(file) {
        if(file->is_dir)
            return bformat(DIR_REDIRECT_FORMAT, bdata(req->host),
                           bdata(req->uri));

        if_match = Request_get(req, &HTTP_IF_MATCH);

        if(!if_match || biseqcstr(if_match, "*") || bstring_match(if_match, &ETAG_PATTERN)) {
            if_none_match = Request_get(req, &HTTP_IF_NONE_MATCH);
            if_unmodified_since = Request_get_date(req, &HTTP_IF_UNMODIFIED_SINCE, RFC_822_TIME);
            if_modified_since = Request_get_date(req, &HTTP_IF_MODIFIED_SINCE, RFC_822_TIME);

            debug("TESTING WITH: if_match: %s, if_none_match: %s, if_unmodified_since: %d, if_modified_since: %d",
                    bdata(if_match), bdata(if_none_match), if_unmodified_since, if_modified_since);

            if(if_unmodified_since) {
                if(file->sb.st_mtime > if_unmodified_since) {
                    req->status_code = 412;
                    return &HTTP_412;
                } else if(if_none_match) {
                    return Dir_none_match(req, file, if_modified_since, if_none_match);
                } else if(if_modified_since) {
                    return Dir_if_modified_since(req, file, if_modified_since);
                }
            } else if(if_none_match) {
                return Dir_none_match(req, file, if_modified_since, if_none_match);
            } else if(if_modified_since) {
                return Dir_if_modified_since(req, file, if_modified_since);
            } else {
                // they've got nothing, 200
                req->status_code = 200;
                return NULL;
            }
        } else {
            req->status_code = 412;
            return &HTTP_412;
        }
    } else {
        req->status_code = 404;
        return &HTTP_404;
    }

    req->status_code = 500;
    return &HTTP_500;
}
Example #3
0
char *test_Request_create() 
{
    int rc = 0;
    size_t nparsed = 0;
    bstring fake_sender = bfromcstr("FAKESENDER");

    Request_init();

    Request *req = Request_create();
    mu_assert(req != NULL, "Failed to create parser for request.");

    FILE *infile = fopen("tests/and_suite/ex_httpd_tst_16", "r");
    mu_assert(infile != NULL, "Failed to open test file.");

    bstring data = bread((bNread)fread, infile);
    fclose(infile);
    mu_assert(data != NULL, "Failed to read test file.");
    mu_assert(blength(data) > 0, "Nothing in that file.");

    Request_start(req);

    rc = Request_parse(req, bdata(data), blength(data), &nparsed);

    mu_assert(rc == 1, "It should parse.");
    mu_assert(nparsed > 0, "Should have parsed something.");

    bstring payload = Request_to_payload(req, fake_sender, 0, "", 0,conn, NULL);
    debug("PAYLOAD IS: %s", bdata(payload));
    bdestroy(payload);

    payload = Request_to_tnetstring(req, fake_sender, 0, "", 0,conn, NULL);
    debug("TNETSTRING PAYLOAD: '%.*s'", blength(payload), bdata(payload));

    mu_assert(Request_get(req, &HTTP_IF_MODIFIED_SINCE) != NULL,
            "Should have an if-modified-since header.");
    mu_assert(req->host != NULL, "Should have Host header.");
    mu_assert(Request_get_date(req, &HTTP_IF_MODIFIED_SINCE, RFC_822_TIME) > 0, 
            "Wrong time from header.");

    mu_assert(Request_get_date(req, &HTTP_IF_UNMODIFIED_SINCE, RFC_822_TIME) == 0,
            "Unmodified since should be invalid.");

    mu_assert(Request_get_date(req, &HTTP_IF_NONE_MATCH, RFC_822_TIME) == 0,
            "None match shouldn't even be a date.");

    Request_start(req);

    Request_destroy(req);

    // test with null
    Request_destroy(NULL);
    bdestroy(payload);
    bdestroy(fake_sender);
    bdestroy(data);

    return NULL;
}
Example #4
0
static void header_done_cb(void *data, const char *at, size_t length)
{
    (void)at;
    (void)length;

    Request *req = (Request *)data;

    // extract content_len
    const char *clen = bdata(Request_get(req, &HTTP_CONTENT_LENGTH));
    if(clen) req->parser.content_len = atoi(clen);

    // extract host header
    req->host = Request_get(req, &HTTP_HOST);
    int colon = bstrchr(req->host, ':');
    if(req->host) {
        req->host_name = colon > 0 ? bHead(req->host, colon) : bstrcpy(req->host);
    }
}
Example #5
0
static inline void check_should_close(Connection *conn, Request *req)
{
    if(req->version && biseqcstr(req->version, "HTTP/1.0")) {
        debug("HTTP 1.0 request coming in from %s", conn->remote);
        conn->close = 1;
    } else {
        bstring conn_close = Request_get(req, &HTTP_CONNECTION);

        if(conn_close && biseqcstrcaseless(conn_close, "close")) {
            conn->close = 1;
        } else {
            conn->close = 0;
        }
    }
}
Example #6
0
int Request_get_date(Request *req, bstring field, const char *format)
{
    struct tm tm_val;
    bstring value = Request_get(req, field);

    if(value) {
        memset(&tm_val, 0, sizeof(struct tm));
        if(strptime(bdata(value), format, &tm_val) == NULL) {
            return 0;
        } else {
            return (int)mktime(&tm_val);
        }
    } else {
        return 0;
    }
}
Example #7
0
char *test_Multiple_Header_Request() 
{
    int rc = 0;
    size_t nparsed = 0;

    Request_init();

    Request *req = Request_create();
    mu_assert(req != NULL, "Failed to create parser for request.");

    FILE *infile = fopen("tests/and_suite/ex_httpd_tst_21", "r");
    mu_assert(infile != NULL, "Failed to open test file.");

    bstring data = bread((bNread)fread, infile);
    fclose(infile);
    mu_assert(data != NULL, "Failed to read test file.");
    mu_assert(blength(data) > 0, "Nothing in that file.");

    Request_start(req);

    rc = Request_parse(req, bdata(data), blength(data), &nparsed);

    mu_assert(rc == 1, "It should parse.");
    mu_assert(nparsed > 0, "Should have parsed something.");

    mu_assert(Request_get(req, &COOKIE_HEADER) != NULL,
            "Should have an cookie header.");

    bstring payload = Request_to_payload(req, &JSON_METHOD, 0, "", 0,conn, NULL);
    debug("PAYLOAD IS: %s", bdata(payload));

    mu_assert(bstrcmp(payload, &EXPECTED_COOKIE_HEADER) == 0,
            "Expected header not in correct format.");

    Request_destroy(req);
    bdestroy(payload);
    bdestroy(data);

    return NULL;
}
Example #8
0
int bbcp_Protocol::Request(bbcp_Node *Node)
{
   long long totsz=0;
   int  retc, numfiles, texists;
   int  outDir = (bbcp_Config.Options & bbcp_OUTDIR) != 0;
   bbcp_FileSpec *fp;
   char buff[1024];

// Establish all connections
//
   if (Node->Start(this, !(bbcp_Config.Options & bbcp_CON2SRC))
   ||  Node->getBuffers(1)) return 2;
   Local = Node;

// Establish the target directory
//
   if ((texists = !bbcp_Config.snkSpec->Stat(0))
   &&  bbcp_Config.snkSpec->Info.Otype == 'd')
       tdir = bbcp_Config.snkSpec->pathname;
      else {int plen;
            if (plen = bbcp_Config.snkSpec->filename -
                       bbcp_Config.snkSpec->pathname)
               strncpy(buff, bbcp_Config.snkSpec->pathname, plen-1);
               else {buff[0] = '.'; plen = 2;}
            tdir = buff; buff[plen-1] = '\0';
           }

// Generate a target directory ID. This will also uncover a missing directory.
//
   fs_obj = bbcp_Config.snkSpec->FSys();
   if (texists &&  bbcp_Config.snkSpec->Info.Otype == 'd')
      tdir_id = bbcp_Config.snkSpec->Info.fileid;
      else {bbcp_FileInfo Tinfo;
            if (!fs_obj || (!(retc = fs_obj->Stat(tdir, &Tinfo))
            && Tinfo.Otype != 'd') && outDir) retc = ENOTDIR;
            if (retc) {bbcp_Fmsg("Request","Target directory",
                                 bbcp_Config.snkSpec->pathname,"not found");
                       return Request_exit(2);
                      }
            tdir_id = Tinfo.fileid;
           }

// The first step is to perform an flist to get the list of files
//
   if ((numfiles = Request_flist(totsz)) <= 0) 
      return Request_exit((numfiles  < 0 ? 22 : 0));

// If we have a number files, the target had better be a directory
//
   if (numfiles > 1 || outDir)
      {if (!texists)
          {bbcp_Fmsg("Request", "Target directory",
                     bbcp_Config.snkSpec->pathname, "not found.");
           return Request_exit(2);
          }
       if (bbcp_Config.snkSpec->Info.Otype != 'd')
          {bbcp_Fmsg("Request", "Target", bbcp_Config.snkSpec->pathname,
                     "is not a directory.");
           return Request_exit(20);
          }
       bbcp_Config.Options |= bbcp_OUTDIR;
      }

// Make sure we have enough space in the filesystem
//
   DEBUG("Preparing to copy " <<numfiles <<" file(s); bytes=" <<totsz);
   if (!(bbcp_Config.Options & bbcp_NOSPCHK) && !fs_obj->Enough(totsz, numfiles))
      {bbcp_Fmsg("Sink", "Insufficient space to copy all the files from",
                               Remote->NodeName());
       return Request_exit(28);
      }

// Create all of the required directories
//
   retc = 0;
   fp = bbcp_Config.srcPath;
   while(fp && !(retc = fp->Create_Path()))  fp = fp->next;
   if (retc) return Request_exit(retc);

// Get each source file
//
   fp = bbcp_Config.srcSpec;
   while(fp && !(retc=Request_get(fp)) && !(retc=Local->RecvFile(fp,Remote)))
        {if (bbcp_Config.Options & bbcp_APPEND) totsz -= fp->targetsz;
         fp = fp->next;
        }

// Now determine if we need to reset the stat info on any paths we created
//
   if ((fp = bbcp_Config.srcPath))
      {if (bbcp_Config.Options & bbcp_PCOPY)
          {while(fp && fp->setStat()) fp = fp->next;}
          else if (bbcp_Config.ModeD != bbcp_Config.ModeDC)
                  {while(fp && fp->setMode(bbcp_Config.ModeD)) fp = fp->next;}
      }

// Report back how many files and bytes were received
//
   cout <<"200 End: " <<numfiles <<' ' <<totsz <<endl;

// All done
//
   return Request_exit(retc);
}
Example #9
0
int connection_http_to_handler(Connection *conn)
{
    int content_len = Request_content_length(conn->req);
    int rc = 0;
    char *body = NULL;

    Handler *handler = Request_get_action(conn->req, handler);
    error_unless(handler, conn, 404, "No action for request: %s", bdata(Request_path(conn->req)));

    bstring expects = Request_get(conn->req, &HTTP_EXPECT);

    if (expects != NULL) {
        if (biseqcstr(expects, "100-continue")) {
            Response_send_status(conn, &HTTP_100);
        } else {
            Response_send_status(conn, &HTTP_417);
            log_info("Client requested unsupported expectation: %s.", bdata(expects));
            goto error;
        }
    }

    // we don't need the header anymore, so commit the buffer and deal with the body
    check(IOBuf_read_commit(conn->iob, Request_header_length(conn->req)) != -1, "Finaly commit failed streaming the connection to http handlers.");

    if(is_websocket(conn)) {
        bstring wsKey = Request_get(conn->req, &WS_SEC_WS_KEY);
        bstring response= websocket_challenge(wsKey);
        conn->handler = handler;

        //Response_send_status(conn,response);
        bdestroy(conn->req->request_method);
        conn->req->request_method=bfromcstr("WEBSOCKET_HANDSHAKE");
        Connection_send_to_handler(conn, handler, bdata(response), blength(response));
        bdestroy(response);

        bdestroy(conn->req->request_method);
        conn->req->request_method=bfromcstr("WEBSOCKET");
        return REQ_SENT;
    }

    if(content_len == 0) {
        body = "";
        rc = Connection_send_to_handler(conn, handler, body, content_len);
        check_debug(rc == 0, "Failed to deliver to the handler.");
    } else if(content_len > MAX_CONTENT_LENGTH) {
        rc = Upload_file(conn, handler, content_len);
        check(rc == 0, "Failed to upload file.");
    } else {
        debug("READ ALL CALLED with content_len: %d, and MAX_CONTENT_LENGTH: %d", content_len, MAX_CONTENT_LENGTH);

        body = IOBuf_read_all(conn->iob, content_len, CLIENT_READ_RETRIES);
        check(body != NULL, "Client closed the connection during upload.");

        rc = Connection_send_to_handler(conn, handler, body, content_len);
        check_debug(rc == 0, "Failed to deliver to the handler.");
    }

    Log_request(conn, 200, content_len);

    return REQ_SENT;

error:
    return CLOSE;
}