/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Originally developed by Aaron Bannert and Justin Erenkrantz, eBuilt. */ #include /* For apr_initialize */ #include #include #if APR_HAVE_STDLIB_H #include /* atexit */ #endif #include "flood_profile.h" /* FIXME: Base this on RCS ID? */ #define FLOOD_VERSION ".001" #define CRLF "\r\n" /* FIXME: replace the apr_recv logic with something sane. */ #define MAX_DOC_LENGTH 8192 #define LOCAL_SOCKET_TIMEOUT 30 * APR_USEC_PER_SEC /* Win32 doesn't have stdout or stderr. */ apr_file_t *local_stdout, *local_stderr; /* Should be the new apr_sms_t struct? Not ready yet. */ apr_pool_t *local_pool; /* Construct a request */ static void construct_request(request_t *r) { /* FIXME: Handle keepalives. */ switch (r->method) { case GET: r->rbuf = apr_psprintf(local_pool, "GET %s HTTP/1.1" CRLF "User-Agent: Flood/" FLOOD_VERSION CRLF "Host: %s" CRLF CRLF, r->parsed_uri->path, r->parsed_uri->hostinfo); r->rbuftype = POOL; r->rbufsize = strlen(r->rbuf); break; case HEAD: r->rbuf = apr_psprintf(local_pool, "HEAD %s HTTP/1.1" CRLF "User-Agent: Flood/" FLOOD_VERSION CRLF "Host: %s" CRLF CRLF, r->parsed_uri->path, r->parsed_uri->hostinfo); r->rbuftype = POOL; r->rbufsize = strlen(r->rbuf); break; case POST: /* FIXME */ r->rbuf = apr_psprintf(local_pool, "POST %s HTTP/1.1" CRLF "User-Agent: Flood/" FLOOD_VERSION CRLF "Host: %s" CRLF CRLF, r->parsed_uri->path, r->parsed_uri->hostinfo); r->rbuftype = POOL; r->rbufsize = strlen(r->rbuf); break; } } /* Open the TCP connection to the server */ static apr_socket_t* open_socket(request_t *r) { apr_status_t rv = 0; apr_sockaddr_t *destsa; /* FIXME: apr_socket_t == socket_t - fix profile.h */ apr_socket_t *socket; if ((rv = apr_sockaddr_info_get(&destsa, r->parsed_uri->hostname, APR_INET, r->parsed_uri->port, 0, local_pool)) != APR_SUCCESS) { return NULL; } if ((rv = apr_socket_create(&socket, APR_INET, SOCK_STREAM, local_pool)) != APR_SUCCESS) { return NULL; } if ((rv = apr_connect(socket, destsa)) != APR_SUCCESS) { if (APR_STATUS_IS_EINPROGRESS(rv)) { /* FIXME: Handle better */ apr_socket_close(socket); return NULL; } else { /* FIXME: Handle */ apr_socket_close(socket); return NULL; } } apr_socket_timeout_set(socket, LOCAL_SOCKET_TIMEOUT); return socket; } /* close down TCP socket */ static void close_socket(apr_socket_t *s) { /* FIXME: recording and other stuff here? */ apr_socket_close(s); } static apr_status_t write_socket(request_t *r, apr_socket_t *s) { apr_size_t l; apr_status_t e; l = r->rbufsize; e = apr_send(s, r->rbuf, &l); /* FIXME: Better error and allow restarts? */ if (l != r->rbufsize) return APR_EGENERAL; return APR_SUCCESS; } /* FIXME: poll implementation? */ static response_t *read_socket(apr_socket_t *s) { apr_status_t status; response_t *resp; resp = apr_pcalloc(local_pool, sizeof(response_t)); resp->rbuftype = POOL; resp->rbufsize = MAX_DOC_LENGTH; resp->rbuf = apr_pcalloc(local_pool, resp->rbufsize); status = apr_recv(s, resp->rbuf, &resp->rbufsize); if (status != APR_SUCCESS && status != APR_EOF) return NULL; return resp; } int main(int argc, char** argv) { request_t r; apr_socket_t *s; /* FIXME: Where is Roy's change to return the global pool... */ apr_initialize(); atexit(apr_terminate); apr_pool_create(&local_pool, NULL); /* The pool should close these file descriptors */ apr_file_open_stdout(&local_stdout, local_pool); apr_file_open_stderr(&local_stderr, local_pool); r.uri = "http://www.apachelabs.org/"; r.method = GET; r.parsed_uri = apr_pcalloc(local_pool, sizeof(*r.parsed_uri)); /* FIXME: This is the private copy. */ apr_uri_parse(local_pool, r.uri, r.parsed_uri); if (!r.parsed_uri->port) r.parsed_uri->port = 80; apr_file_printf(local_stdout, "%s\n", r.parsed_uri->hostname); construct_request(&r); s = open_socket(&r); if (s) { response_t *resp; if (write_socket(&r, s) == APR_SUCCESS) { /* Wait .25 seconds... */ /* FIXME: replace with poll. */ apr_sleep(0.25 * APR_USEC_PER_SEC); resp = read_socket(s); if (resp) apr_file_printf(local_stdout, "%s\n", (char*)resp->rbuf); } close_socket(s); } return EXIT_SUCCESS; }