static void php_apache_sapi_flush(void *server_context) { php_struct *ctx; request_rec *r; ctx = server_context; /* If we haven't registered a server_context yet, * then don't bother flushing. */ if (!server_context) { return; } r = ctx->r; sapi_send_headers(); r->status = SG(sapi_headers).http_response_code; SG(headers_sent) = 1; if (ap_rflush(r) < 0 || r->connection->aborted) { php_handle_aborted_connection(); } }
CAMLprim value netcgi2_apache_request_rflush (value rv) { CAMLparam1 (rv); request_rec *r = Request_rec_val (rv); int i = ap_rflush (r); CAMLreturn (Val_int (i)); }
/** * Writes a single chunk of multipart/x-mixed-replace content */ static void osrfHttpTranslatorWriteChunk(osrfHttpTranslator* trans, transport_message* msg) { osrfLogInternal(OSRF_LOG_MARK, "sending multipart chunk %s", msg->body); ap_rprintf(trans->apreq, "Content-type: %s\n\n%s\n\n", JSON_CONTENT_TYPE, msg->body); //osrfLogInternal(OSRF_LOG_MARK, "Apache sending data: Content-type: %s\n\n%s\n\n", //JSON_CONTENT_TYPE, msg->body); if(trans->complete) { ap_rprintf(trans->apreq, "--%s--\n", trans->delim); //osrfLogInternal(OSRF_LOG_MARK, "Apache sending data: --%s--\n", trans->delim); } else { ap_rprintf(trans->apreq, "--%s\n", trans->delim); //osrfLogInternal(OSRF_LOG_MARK, "Apache sending data: --%s\n", trans->delim); } ap_rflush(trans->apreq); }
static int lua_ap_send(lua_State *L) { request_rec *r = CHECK_REQUEST_OBJECT(1); size_t len; const char* dat = luaL_checklstring(L, 2, &len); int flush = lua_isnone(L, 3) ? 1 : lua_toboolean(L, 3); int s = ap_rwrite(dat, len, r); if (s == len) { s = flush ? ap_rflush(r) : 0; } lua_pushboolean(L, s == 0); lua_pushinteger(L, s); return 2; }
static am_status_t set_custom_response(am_request_t *rq, const char *text, const char *cont_type) { request_rec *r = (request_rec *) (rq != NULL ? rq->ctx : NULL); if (r == NULL || !ISVALID(text)) return AM_EINVAL; if (rq->status == AM_INTERNAL_REDIRECT) { ap_internal_redirect(text, r); rq->status = AM_DONE; } else if (rq->status == AM_REDIRECT) { apr_table_add(r->headers_out, "Location", text); ap_custom_response(r, HTTP_MOVED_TEMPORARILY, text); } else { if (rq->status == AM_PDP_DONE) { request_rec *sr = ap_sub_req_method_uri(am_method_num_to_str(rq->method), rq->post_data_url, r, NULL); sr->headers_in = r->headers_in; sr->notes = r->notes; am_log_debug(rq->instance_id, "set_custom_response(): issuing sub-request %s to %s", sr->method, rq->post_data_url); ap_run_sub_req(sr); ap_destroy_sub_req(sr); rq->status = AM_DONE; } else { size_t tl = strlen(text); if (ISVALID(cont_type)) { ap_set_content_type(r, cont_type); } ap_set_content_length(r, tl); ap_rwrite(text, (int) tl, r); ap_custom_response(r, am_status_value(rq->status == AM_SUCCESS || rq->status == AM_DONE ? AM_SUCCESS : rq->status), text); ap_rflush(r); } } am_log_info(rq->instance_id, "set_custom_response(): status: %s", am_strerror(rq->status)); return AM_SUCCESS; }
static PyObject * req_write(requestobject *self, PyObject *args) { int len; int rc; char *buff; if (! PyArg_ParseTuple(args, "s#", &buff, &len)) return NULL; /* bad args */ Py_BEGIN_ALLOW_THREADS ap_rwrite(buff, len, self->request_rec); rc = ap_rflush(self->request_rec); Py_END_ALLOW_THREADS if (rc == EOF) { PyErr_SetString(PyExc_IOError, "Write failed, client closed connection."); return NULL; } Py_INCREF(Py_None); return Py_None; }
/* {{{ proto bool virtual(string uri) Perform an apache sub-request */ PHP_FUNCTION(virtual) { char *filename; size_t filename_len; request_rec *rr; if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &filename, &filename_len) == FAILURE) { return; } if (!(rr = php_apache_lookup_uri(filename))) { php_error_docref(NULL, E_WARNING, "Unable to include '%s' - URI lookup failed", filename); RETURN_FALSE; } if (rr->status != HTTP_OK) { php_error_docref(NULL, E_WARNING, "Unable to include '%s' - error finding URI", filename); ap_destroy_sub_req(rr); RETURN_FALSE; } /* Flush everything. */ php_output_end_all(); php_header(); /* Ensure that the ap_r* layer for the main request is flushed, to * work around http://issues.apache.org/bugzilla/show_bug.cgi?id=17629 */ ap_rflush(rr->main); if (ap_run_sub_req(rr)) { php_error_docref(NULL, E_WARNING, "Unable to include '%s' - request execution failed", filename); ap_destroy_sub_req(rr); RETURN_FALSE; } ap_destroy_sub_req(rr); RETURN_TRUE; }
/* * ic_transfer_response() * ---------------------- * Read the response from the Interchange server * and relay it to the client */ static int ic_transfer_response(request_rec *r,BUFF *ic_buff) { const char *location; int rc,ic_sock; char sbuf[MAX_STRING_LEN],argsbuffer[MAX_STRING_LEN]; /* * get the socket we are using to talk to the * Interchange server, and wait for Interchange to * send us some data */ ic_sock = ap_bfileno(ic_buff,B_RD); rc = ic_select(ic_sock,0,IC_DEFAULT_TIMEOUT,0); if (rc < 0){ ap_log_reason("Failed to select the response header",r->uri,r); return HTTP_INTERNAL_SERVER_ERROR; } /* * check the HTTP header to make sure that it looks valid */ if ((rc = ap_scan_script_header_err_buff(r,ic_buff,sbuf)) != OK) { if (rc == HTTP_INTERNAL_SERVER_ERROR) { ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,r,"Malformed header return by Interchange: %s",sbuf); } return rc; } /* * check the header for an HTTP redirect request */ location = ap_table_get(r->headers_out,"Location"); if (r->status == 200 && location){ fd_set sock_set; /* * check if we need to do an external redirect */ if (*location != '/') return REDIRECT; /* * we are here because we need to do an internal redirect * * soak up any data from the Interchange socket */ rc = ic_select(ic_sock,0,IC_DEFAULT_TIMEOUT,0); if (rc < 0){ ap_log_reason("Failed to select the response text",r->uri,r); return HTTP_INTERNAL_SERVER_ERROR; } /* * soak up any body-text sent by the Interchange server */ ap_soft_timeout("mod_interchange: Interchange read",r); while (ap_bgets(argsbuffer,MAX_STRING_LEN,ic_buff) > 0) ; ap_kill_timeout(r); /* * always use the GET method for internal redirects * also, unset the Content-Length so that nothing * else tries to re-read the text we just soaked up */ r->method = ap_pstrdup(r->pool,"GET"); r->method_number = M_GET; ap_table_unset(r->headers_in,"Content-Length"); ap_internal_redirect(location,r); return OK; } /* * we were not redirected, so send the HTTP headers * to the client */ ap_hard_timeout("mod_interchange: Client write",r); ap_send_http_header(r); if (ap_rflush(r) < 0){ ap_log_reason("error sending headers to client",r->uri,r); return HTTP_INTERNAL_SERVER_ERROR; } /* * if Interchange is sending body text (HTML), then * relay this to the client */ if (!r->header_only){ ap_reset_timeout(r); if ((rc = ap_bnonblock(ic_buff,B_RD)) != 0){ ap_log_reason("error turning non blocking I/O on Interchange socket",r->uri,r); return HTTP_INTERNAL_SERVER_ERROR; } ap_bsetflag(ic_buff,B_SAFEREAD,1); if (ap_send_fb(ic_buff,r) <= 0){ ap_log_reason("error sending response body to client",r->uri,r); return HTTP_INTERNAL_SERVER_ERROR; } } ap_kill_timeout(r); return OK; }
/* CONNECT handler */ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyname, apr_port_t proxyport) { apr_pool_t *p = r->pool; apr_socket_t *sock; apr_status_t err, rv; apr_size_t i, o, nbytes; char buffer[HUGE_STRING_LEN]; apr_socket_t *client_socket = ap_get_module_config(r->connection->conn_config, &core_module); int failed; apr_pollset_t *pollset; apr_pollfd_t pollfd; const apr_pollfd_t *signalled; apr_int32_t pollcnt, pi; apr_int16_t pollevent; apr_sockaddr_t *uri_addr, *connect_addr; apr_uri_t uri; const char *connectname; int connectport = 0; /* is this for us? */ if (r->method_number != M_CONNECT) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: CONNECT: declining URL %s", url); return DECLINED; } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: CONNECT: serving URL %s", url); /* * Step One: Determine Who To Connect To * * Break up the URL to determine the host to connect to */ /* we break the URL into host, port, uri */ if (APR_SUCCESS != apr_uri_parse_hostinfo(p, url, &uri)) { return ap_proxyerror(r, HTTP_BAD_REQUEST, apr_pstrcat(p, "URI cannot be parsed: ", url, NULL)); } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: CONNECT: connecting %s to %s:%d", url, uri.hostname, uri.port); /* do a DNS lookup for the destination host */ err = apr_sockaddr_info_get(&uri_addr, uri.hostname, APR_UNSPEC, uri.port, 0, p); /* are we connecting directly, or via a proxy? */ if (proxyname) { connectname = proxyname; connectport = proxyport; err = apr_sockaddr_info_get(&connect_addr, proxyname, APR_UNSPEC, proxyport, 0, p); } else { connectname = uri.hostname; connectport = uri.port; connect_addr = uri_addr; } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: CONNECT: connecting to remote proxy %s on port %d", connectname, connectport); /* check if ProxyBlock directive on this host */ if (OK != ap_proxy_checkproxyblock(r, conf, uri_addr)) { return ap_proxyerror(r, HTTP_FORBIDDEN, "Connect to remote machine blocked"); } /* Check if it is an allowed port */ if (conf->allowed_connect_ports->nelts == 0) { /* Default setting if not overridden by AllowCONNECT */ switch (uri.port) { case APR_URI_HTTPS_DEFAULT_PORT: case APR_URI_SNEWS_DEFAULT_PORT: break; default: /* XXX can we call ap_proxyerror() here to get a nice log message? */ return HTTP_FORBIDDEN; } } else if(!allowed_port(conf, uri.port)) { /* XXX can we call ap_proxyerror() here to get a nice log message? */ return HTTP_FORBIDDEN; } /* * Step Two: Make the Connection * * We have determined who to connect to. Now make the connection. */ /* get all the possible IP addresses for the destname and loop through them * until we get a successful connection */ if (APR_SUCCESS != err) { return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p, "DNS lookup failure for: ", connectname, NULL)); } /* * At this point we have a list of one or more IP addresses of * the machine to connect to. If configured, reorder this * list so that the "best candidate" is first try. "best * candidate" could mean the least loaded server, the fastest * responding server, whatever. * * For now we do nothing, ie we get DNS round robin. * XXX FIXME */ failed = ap_proxy_connect_to_backend(&sock, "CONNECT", connect_addr, connectname, conf, r->server, r->pool); /* handle a permanent error from the above loop */ if (failed) { if (proxyname) { return DECLINED; } else { return HTTP_BAD_GATEWAY; } } /* * Step Three: Send the Request * * Send the HTTP/1.1 CONNECT request to the remote server */ /* we are acting as a tunnel - the output filter stack should * be completely empty, because when we are done here we are done completely. * We add the NULL filter to the stack to do this... */ r->output_filters = NULL; r->connection->output_filters = NULL; /* If we are connecting through a remote proxy, we need to pass * the CONNECT request on to it. */ if (proxyport) { /* FIXME: Error checking ignored. */ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: CONNECT: sending the CONNECT request to the remote proxy"); nbytes = apr_snprintf(buffer, sizeof(buffer), "CONNECT %s HTTP/1.0" CRLF, r->uri); apr_socket_send(sock, buffer, &nbytes); nbytes = apr_snprintf(buffer, sizeof(buffer), "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner()); apr_socket_send(sock, buffer, &nbytes); } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: CONNECT: Returning 200 OK Status"); nbytes = apr_snprintf(buffer, sizeof(buffer), "HTTP/1.0 200 Connection Established" CRLF); ap_xlate_proto_to_ascii(buffer, nbytes); apr_socket_send(client_socket, buffer, &nbytes); nbytes = apr_snprintf(buffer, sizeof(buffer), "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner()); ap_xlate_proto_to_ascii(buffer, nbytes); apr_socket_send(client_socket, buffer, &nbytes); #if 0 /* This is safer code, but it doesn't work yet. I'm leaving it * here so that I can fix it later. */ r->status = HTTP_OK; r->header_only = 1; apr_table_set(r->headers_out, "Proxy-agent: %s", ap_get_server_banner()); ap_rflush(r); #endif } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: CONNECT: setting up poll()"); /* * Step Four: Handle Data Transfer * * Handle two way transfer of data over the socket (this is a tunnel). */ /* r->sent_bodyct = 1;*/ if ((rv = apr_pollset_create(&pollset, 2, r->pool, 0)) != APR_SUCCESS) { apr_socket_close(sock); ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy: CONNECT: error apr_pollset_create()"); return HTTP_INTERNAL_SERVER_ERROR; } /* Add client side to the poll */ pollfd.p = r->pool; pollfd.desc_type = APR_POLL_SOCKET; pollfd.reqevents = APR_POLLIN; pollfd.desc.s = client_socket; pollfd.client_data = NULL; apr_pollset_add(pollset, &pollfd); /* Add the server side to the poll */ pollfd.desc.s = sock; apr_pollset_add(pollset, &pollfd); while (1) { /* Infinite loop until error (one side closes the connection) */ if ((rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled)) != APR_SUCCESS) { apr_socket_close(sock); ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy: CONNECT: error apr_poll()"); return HTTP_INTERNAL_SERVER_ERROR; } #ifdef DEBUGGING ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: CONNECT: woke from select(), i=%d", pollcnt); #endif for (pi = 0; pi < pollcnt; pi++) { const apr_pollfd_t *cur = &signalled[pi]; if (cur->desc.s == sock) { pollevent = cur->rtnevents; if (pollevent & APR_POLLIN) { #ifdef DEBUGGING ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: CONNECT: sock was set"); #endif nbytes = sizeof(buffer); rv = apr_socket_recv(sock, buffer, &nbytes); if (rv == APR_SUCCESS) { o = 0; i = nbytes; while(i > 0) { nbytes = i; /* This is just plain wrong. No module should ever write directly * to the client. For now, this works, but this is high on my list of * things to fix. The correct line is: * if ((nbytes = ap_rwrite(buffer + o, nbytes, r)) < 0) * rbb */ rv = apr_socket_send(client_socket, buffer + o, &nbytes); if (rv != APR_SUCCESS) break; o += nbytes; i -= nbytes; } } else break; } else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) break; } else if (cur->desc.s == client_socket) { pollevent = cur->rtnevents; if (pollevent & APR_POLLIN) { #ifdef DEBUGGING ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: CONNECT: client was set"); #endif nbytes = sizeof(buffer); rv = apr_socket_recv(client_socket, buffer, &nbytes); if (rv == APR_SUCCESS) { o = 0; i = nbytes; #ifdef DEBUGGING ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: CONNECT: read %d from client", i); #endif while(i > 0) { nbytes = i; rv = apr_socket_send(sock, buffer + o, &nbytes); if (rv != APR_SUCCESS) break; o += nbytes; i -= nbytes; } } else break; } else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) { rv = APR_EOF; break; } } else break; } if (rv != APR_SUCCESS) { break; } } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: CONNECT: finished with poll() - cleaning up"); /* * Step Five: Clean Up * * Close the socket and clean up */ apr_socket_close(sock); return OK; }
/** * Handle a request. */ static int caucho_request(request_rec *r) { config_t *config = cse_get_module_config(r); resin_host_t *host = 0; stream_t s; int retval; int keepalive = 0; int reuse; int session_index; int backup_index; char *ip; time_t now = r->request_time; char *session_id = 0; if (! config) return HTTP_SERVICE_UNAVAILABLE; if ((retval = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK))) return retval; /* ap_soft_timeout("servlet request", r); */ if (r->request_config && ! *config->alt_session_url_prefix && ((session_id = ap_get_module_config(r->request_config, &caucho_module)) || r->prev && (session_id = ap_get_module_config(r->prev->request_config, &caucho_module)))) { /* *session_id = *config->session_url_prefix; */ } session_index = get_session_index(config, r, &backup_index); ip = r->connection->remote_ip; if (host) { } else if (config->manual_host) host = config->manual_host; else { host = cse_match_host(config, ap_get_server_name(r), ap_get_server_port(r), now); } if (! host || ! cse_open_connection(&s, &host->cluster, session_index, backup_index, now, r->pool)) { return HTTP_SERVICE_UNAVAILABLE; } reuse = write_request(&s, r, config, &host->cluster, &keepalive, session_index, backup_index, ip, session_id); /* ap_kill_timeout(r); */ ap_rflush(r); if (reuse == HMUX_QUIT) cse_recycle(&s, now); else cse_close(&s, "no reuse"); if (reuse == HTTP_SERVICE_UNAVAILABLE) return reuse; else return OK; }
static void do_flush( void *_c ) { mcontext *c = (mcontext*)_c; ap_rflush(c->r); }
/** cgi_flush : void -> void <doc>Flush the data written so it's immediatly sent to the client</doc> **/ static value cgi_flush() { ap_rflush(CONTEXT()->r); return val_null; }
/* CONNECT handler */ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyname, apr_port_t proxyport) { connect_conf *c_conf = ap_get_module_config(r->server->module_config, &proxy_connect_module); apr_pool_t *p = r->pool; apr_socket_t *sock; conn_rec *c = r->connection; conn_rec *backconn; apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc); apr_status_t rv; apr_size_t nbytes; char buffer[HUGE_STRING_LEN]; apr_socket_t *client_socket = ap_get_conn_socket(c); int failed, rc; int client_error = 0; apr_pollset_t *pollset; apr_pollfd_t pollfd; const apr_pollfd_t *signalled; apr_int32_t pollcnt, pi; apr_int16_t pollevent; apr_sockaddr_t *nexthop; apr_uri_t uri; const char *connectname; int connectport = 0; /* is this for us? */ if (r->method_number != M_CONNECT) { ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "declining URL %s", url); return DECLINED; } ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "serving URL %s", url); /* * Step One: Determine Who To Connect To * * Break up the URL to determine the host to connect to */ /* we break the URL into host, port, uri */ if (APR_SUCCESS != apr_uri_parse_hostinfo(p, url, &uri)) { return ap_proxyerror(r, HTTP_BAD_REQUEST, apr_pstrcat(p, "URI cannot be parsed: ", url, NULL)); } ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01019) "connecting %s to %s:%d", url, uri.hostname, uri.port); /* Determine host/port of next hop; from request URI or of a proxy. */ connectname = proxyname ? proxyname : uri.hostname; connectport = proxyname ? proxyport : uri.port; /* Do a DNS lookup for the next hop */ rv = apr_sockaddr_info_get(&nexthop, connectname, APR_UNSPEC, connectport, 0, p); if (rv != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02327) "failed to resolve hostname '%s'", connectname); return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p, "DNS lookup failure for: ", connectname, NULL)); } /* Check ProxyBlock directive on the hostname/address. */ if (ap_proxy_checkproxyblock2(r, conf, uri.hostname, proxyname ? NULL : nexthop) != OK) { return ap_proxyerror(r, HTTP_FORBIDDEN, "Connect to remote machine blocked"); } ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "connecting to remote proxy %s on port %d", connectname, connectport); /* Check if it is an allowed port */ if(!allowed_port(c_conf, uri.port)) { return ap_proxyerror(r, HTTP_FORBIDDEN, "Connect to remote machine blocked"); } /* * Step Two: Make the Connection * * We have determined who to connect to. Now make the connection. */ /* * At this point we have a list of one or more IP addresses of * the machine to connect to. If configured, reorder this * list so that the "best candidate" is first try. "best * candidate" could mean the least loaded server, the fastest * responding server, whatever. * * For now we do nothing, ie we get DNS round robin. * XXX FIXME */ failed = ap_proxy_connect_to_backend(&sock, "CONNECT", nexthop, connectname, conf, r); /* handle a permanent error from the above loop */ if (failed) { if (proxyname) { return DECLINED; } else { return HTTP_SERVICE_UNAVAILABLE; } } /* setup polling for connection */ ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "setting up poll()"); if ((rv = apr_pollset_create(&pollset, 2, r->pool, 0)) != APR_SUCCESS) { apr_socket_close(sock); ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01020) "error apr_pollset_create()"); return HTTP_INTERNAL_SERVER_ERROR; } /* Add client side to the poll */ pollfd.p = r->pool; pollfd.desc_type = APR_POLL_SOCKET; pollfd.reqevents = APR_POLLIN; pollfd.desc.s = client_socket; pollfd.client_data = NULL; apr_pollset_add(pollset, &pollfd); /* Add the server side to the poll */ pollfd.desc.s = sock; apr_pollset_add(pollset, &pollfd); /* * Step Three: Send the Request * * Send the HTTP/1.1 CONNECT request to the remote server */ backconn = ap_run_create_connection(c->pool, r->server, sock, c->id, c->sbh, c->bucket_alloc); if (!backconn) { /* peer reset */ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01021) "an error occurred creating a new connection " "to %pI (%s)", nexthop, connectname); apr_socket_close(sock); return HTTP_INTERNAL_SERVER_ERROR; } ap_proxy_ssl_disable(backconn); rc = ap_run_pre_connection(backconn, sock); if (rc != OK && rc != DONE) { backconn->aborted = 1; ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01022) "pre_connection setup failed (%d)", rc); return HTTP_INTERNAL_SERVER_ERROR; } ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "connection complete to %pI (%s)", nexthop, connectname); apr_table_setn(r->notes, "proxy-source-port", apr_psprintf(r->pool, "%hu", backconn->local_addr->port)); /* If we are connecting through a remote proxy, we need to pass * the CONNECT request on to it. */ if (proxyport) { /* FIXME: Error checking ignored. */ ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "sending the CONNECT request to the remote proxy"); ap_fprintf(backconn->output_filters, bb, "CONNECT %s HTTP/1.0" CRLF, r->uri); ap_fprintf(backconn->output_filters, bb, "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner()); ap_fflush(backconn->output_filters, bb); } else { ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "Returning 200 OK"); nbytes = apr_snprintf(buffer, sizeof(buffer), "HTTP/1.0 200 Connection Established" CRLF); ap_xlate_proto_to_ascii(buffer, nbytes); ap_fwrite(c->output_filters, bb, buffer, nbytes); nbytes = apr_snprintf(buffer, sizeof(buffer), "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner()); ap_xlate_proto_to_ascii(buffer, nbytes); ap_fwrite(c->output_filters, bb, buffer, nbytes); ap_fflush(c->output_filters, bb); #if 0 /* This is safer code, but it doesn't work yet. I'm leaving it * here so that I can fix it later. */ r->status = HTTP_OK; r->header_only = 1; apr_table_set(r->headers_out, "Proxy-agent: %s", ap_get_server_banner()); ap_rflush(r); #endif } ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "setting up poll()"); /* * Step Four: Handle Data Transfer * * Handle two way transfer of data over the socket (this is a tunnel). */ /* we are now acting as a tunnel - the input/output filter stacks should * not contain any non-connection filters. */ r->output_filters = c->output_filters; r->proto_output_filters = c->output_filters; r->input_filters = c->input_filters; r->proto_input_filters = c->input_filters; /* r->sent_bodyct = 1;*/ while (1) { /* Infinite loop until error (one side closes the connection) */ if ((rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled)) != APR_SUCCESS) { if (APR_STATUS_IS_EINTR(rv)) { continue; } apr_socket_close(sock); ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01023) "error apr_poll()"); return HTTP_INTERNAL_SERVER_ERROR; } #ifdef DEBUGGING ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01024) "woke from poll(), i=%d", pollcnt); #endif for (pi = 0; pi < pollcnt; pi++) { const apr_pollfd_t *cur = &signalled[pi]; if (cur->desc.s == sock) { pollevent = cur->rtnevents; if (pollevent & APR_POLLIN) { #ifdef DEBUGGING ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01025) "sock was readable"); #endif rv = proxy_connect_transfer(r, backconn, c, bb, "sock"); } else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) { rv = APR_EPIPE; ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(01026) "err/hup on backconn"); } if (rv != APR_SUCCESS) client_error = 1; } else if (cur->desc.s == client_socket) { pollevent = cur->rtnevents; if (pollevent & APR_POLLIN) { #ifdef DEBUGGING ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01027) "client was readable"); #endif rv = proxy_connect_transfer(r, c, backconn, bb, "client"); } } else { rv = APR_EBADF; ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01028) "unknown socket in pollset"); } } if (rv != APR_SUCCESS) { break; } } ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "finished with poll() - cleaning up"); /* * Step Five: Clean Up * * Close the socket and clean up */ if (client_error) apr_socket_close(sock); else ap_lingering_close(backconn); c->aborted = 1; c->keepalive = AP_CONN_CLOSE; return OK; }
/** * Copy data from the JVM to the browser. */ static int send_data(stream_t *s, request_rec *r, int ack, int *keepalive) { int code = HMUX_QUIT; char buf[8193]; char key[8193]; char value[8193]; int channel; int i; /* ap_reset_timeout(r); */ if (cse_fill_buffer(s) < 0) return -1; /* code = cse_read_byte(s); if (code != HMUX_CHANNEL) { r->status = 500; r->status_line = "Protocol error"; cse_close(s, "bad protocol"); return -1; } channel = hmux_read_len(s); */ do { int len; /* ap_reset_timeout(r); */ code = cse_read_byte(s); if (s->socket < 0) return -1; switch (code) { case HMUX_CHANNEL: channel = hmux_read_len(s); LOG(("channel %d\n", channel)); break; case HMUX_ACK: channel = hmux_read_len(s); LOG(("ack %d\n", channel)); break; case HMUX_STATUS: len = hmux_read_len(s); cse_read_limit(s, buf, sizeof(buf), len); for (i = 0; buf[i] && buf[i] != ' '; i++) { } buf[i] = 0; r->status = atoi(buf); buf[i] = ' '; i++; r->status_line = ap_pstrdup(r->pool, buf); break; case HMUX_HEADER: len = hmux_read_len(s); cse_read_limit(s, key, sizeof(key), len); cse_read_string(s, value, sizeof(value)); if (! strcasecmp(key, "content-type")) r->content_type = ap_pstrdup(r->pool, value); else ap_table_add(r->headers_out, key, value); break; case HMUX_META_HEADER: len = hmux_read_len(s); cse_read_limit(s, key, sizeof(key), len); cse_read_string(s, value, sizeof(value)); break; case HMUX_DATA: len = hmux_read_len(s); if (cse_write_response(s, len, r) < 0) return -1; break; case HMUX_FLUSH: len = hmux_read_len(s); ap_rflush(r); break; case CSE_KEEPALIVE: len = hmux_read_len(s); *keepalive = 1; break; case CSE_SEND_HEADER: len = hmux_read_len(s); ap_send_http_header(r); break; case -1: break; case HMUX_QUIT: case HMUX_EXIT: break; default: len = hmux_read_len(s); cse_skip(s, len); break; } } while (code > 0 && code != HMUX_QUIT && code != HMUX_EXIT && code != ack); return code; }
// dbuf is the request text static int femto_do_request(request_rec* r, char* dbuf) { int i; int rc; femto_request_t *femto_request = NULL; int zero; struct timespec start; struct timespec now; r->content_type = "text/plain"; if (!r->header_only) { char* index_path = NULL; int index_path_len = 0; index_path = apr_pstrdup(r->pool, r->filename); index_path_len = strlen(index_path); // Make a new version of the filename without the /r. while( index_path_len >= 0 && index_path[index_path_len-1] != '/' && index_path[index_path_len-1] == 'r' ) { index_path[index_path_len-1] = '\0'; index_path_len--; } //printf("FEMTO got request for %s: %s\n", index_path, dbuf); // Look to break out of. for( zero = 0; zero < 1; zero++ ) { // Start going! rc = femto_create_generic_request(&femto_request, &femto_server, index_path, dbuf); if( rc ) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, "FEMTO could not create request"); return HTTP_INTERNAL_SERVER_ERROR; } rc = femto_begin_request(&femto_server, femto_request); if( rc ) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, "FEMTO could not begin request"); return HTTP_INTERNAL_SERVER_ERROR; } start.tv_sec = 0; start.tv_nsec = 0; now.tv_sec = 0; now.tv_nsec = 0; for( i = 0; ! r->connection->aborted; i++ ) { int completed = 0; struct timeval tv; struct timespec ts; rc = gettimeofday(&tv, NULL); ts.tv_sec = tv.tv_sec; ts.tv_nsec = 1000 * tv.tv_usec; //rc = clock_gettime(CLOCK_REALTIME, &ts); if( rc ) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, "FEMTO could not gettime"); return HTTP_INTERNAL_SERVER_ERROR; } ts.tv_sec += 2; rc = femto_timedwait_request(&femto_server, femto_request, &ts, &completed); if( rc ) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, "FEMTO could not wait for request"); return HTTP_INTERNAL_SERVER_ERROR; } if( completed ) break; rc = gettimeofday(&tv, NULL); now.tv_sec = tv.tv_sec; now.tv_nsec = 1000 * tv.tv_usec; //rc = clock_gettime(CLOCK_REALTIME, &now); if( rc ) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, "FEMTO clock_gettime failed"); return HTTP_INTERNAL_SERVER_ERROR; } if( now.tv_sec > start.tv_sec ) { // This is dopey.. but also the best way to check for // an aborted connection... just send a byte every second. ap_rputc(' ', r); ap_rflush(r); start = now; } } } if( ! r->connection->aborted ) { char* response; rc = femto_response_for_generic_request(femto_request, &femto_server, &response); if( rc ) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, "FEMTO response_for_generic_request failed"); return HTTP_INTERNAL_SERVER_ERROR; } //printf("FEMTO sending response %s\n", response); ap_rputc('\n', r); ap_rputs(response, r); free(response); } else { rc = femto_cancel_request(&femto_server, femto_request); if( rc ) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, "FEMTO could not cancel request"); return HTTP_INTERNAL_SERVER_ERROR; } } femto_destroy_request(femto_request); } return OK; }
static int ipp_handler(request_rec *r) { papi_attribute_t **request = NULL, **response = NULL; IPPListenerConfig *config; papi_status_t status; int ret; /* Really, IPP is all POST requests */ if (r->method_number != M_POST) return (DECLINED); #ifndef APACHE2 /* * An IPP request must have a MIME type of "application/ipp" * (RFC-2910, Section 4, page 19). If it doesn't match this * MIME type, we should decline the request and let someone else * try and handle it. */ if (r->headers_in != NULL) { char *mime_type = (char *)ap_table_get(r->headers_in, "Content-Type"); if ((mime_type == NULL) || (strcasecmp(mime_type, "application/ipp") != 0)) return (DECLINED); } #endif /* CHUNKED_DECHUNK might not work right for IPP? */ if ((ret = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != OK) return (ret); if (!ap_should_client_block(r)) return (HTTP_INTERNAL_SERVER_ERROR); #ifndef APACHE2 ap_soft_timeout("ipp_module: read/reply request ", r); #endif /* read the IPP request off the network */ status = ipp_read_message(read_data, r, &request, IPP_TYPE_REQUEST); if (status != PAPI_OK) _log_rerror(APLOG_MARK, APLOG_ERR, r, "read failed: %s\n", papiStatusString(status)); #ifdef DEBUG papiAttributeListPrint(stderr, request, "request (%d) ", getpid()); #endif (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "originating-host", (char *) #ifdef APACHE2 ap_get_remote_host (r->connection, r->per_dir_config, REMOTE_NAME, NULL)); #else ap_get_remote_host (r->connection, r->per_dir_config, REMOTE_NAME)); #endif (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, "uri-port", ap_get_server_port(r)); if (r->headers_in != NULL) { char *host = (char *)ap_table_get(r->headers_in, "Host"); if ((host == NULL) || (host[0] == '\0')) host = (char *)ap_get_server_name(r); (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "uri-host", host); } (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "uri-path", r->uri); config = ap_get_module_config(r->per_dir_config, &ipp_module); if (config != NULL) { (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, "conformance", config->conformance); (void) papiAttributeListAddCollection(&request, PAPI_ATTR_EXCL, "operations", config->operations); if (config->default_user != NULL) (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "default-user", config->default_user); if (config->default_svc != NULL) (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "default-service", config->default_svc); } /* * For Trusted Solaris, pass the fd number of the socket connection * to the backend so the it can be forwarded to the backend print * service to retrieve the sensativity label off of a multi-level * port. */ (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, "peer-socket", ap_bfileno(r->connection->client, B_RD)); /* process the request */ status = ipp_process_request(request, &response, read_data, r); if (status != PAPI_OK) { errno = 0; _log_rerror(APLOG_MARK, APLOG_ERR, r, "request failed: %s\n", papiStatusString(status)); discard_data(r); } #ifdef DEBUG fprintf(stderr, "processing result: %s\n", papiStatusString(status)); papiAttributeListPrint(stderr, response, "response (%d) ", getpid()); #endif /* * If the client is using chunking and we have not yet received the * final "0" sized chunk, we need to discard any data that may * remain in the post request. */ if ((r->read_chunked != 0) && (ap_table_get(r->headers_in, "Content-Length") == NULL)) discard_data(r); /* write an IPP response back to the network */ r->content_type = "application/ipp"; #ifndef APACHE2 ap_send_http_header(r); #endif status = ipp_write_message(write_data, r, response); if (status != PAPI_OK) _log_rerror(APLOG_MARK, APLOG_ERR, r, "write failed: %s\n", papiStatusString(status)); #ifdef DEBUG fprintf(stderr, "write result: %s\n", papiStatusString(status)); fflush(stderr); #endif papiAttributeListFree(request); papiAttributeListFree(response); #ifndef APACHE2 ap_kill_timeout(r); if (ap_rflush(r) < 0) _log_rerror(APLOG_MARK, APLOG_ERR, r, "flush failed, response may not have been sent"); #endif return (OK); }
/** * Copy data from the JVM to the browser. */ static int send_data(stream_t *s, request_rec *r) { int code = -1; char buf[8193]; char key[8193]; char value[8193]; int i; int channel; if (cse_fill_buffer(s) < 0) { return -1; } while (1) { int len; code = cse_read_byte(s); LOG(("%s:%d:send_data(): r-code %c\n", __FILE__, __LINE__, code)); switch (code) { case HMUX_CHANNEL: channel = hmux_read_len(s); LOG(("%s:%d:send_data(): r-channel %d\n", __FILE__, __LINE__, channel)); break; case HMUX_ACK: channel = hmux_read_len(s); LOG(("%s:%d:send_data(): r-ack %d\n", __FILE__, __LINE__, channel)); return code; case HMUX_STATUS: len = hmux_read_len(s); cse_read_limit(s, buf, sizeof(buf), len); for (i = 0; buf[i] && buf[i] != ' '; i++) { } i++; r->status = atoi(buf); r->status_line = apr_pstrdup(r->pool, buf); break; case HMUX_HEADER: len = hmux_read_len(s); cse_read_limit(s, key, sizeof(key), len); cse_read_string(s, value, sizeof(value)); if (! strcasecmp(key, "content-type")) { r->content_type = apr_pstrdup(r->pool, value); apr_table_set(r->headers_out, key, value); } else apr_table_add(r->headers_out, key, value); break; case HMUX_META_HEADER: len = hmux_read_len(s); cse_read_limit(s, key, sizeof(key), len); cse_read_string(s, value, sizeof(value)); break; case HMUX_DATA: len = hmux_read_len(s); if (cse_write_response(s, len, r) < 0) return HMUX_EXIT; break; case HMUX_FLUSH: len = hmux_read_len(s); ap_rflush(r); break; case CSE_SEND_HEADER: len = hmux_read_len(s); break; case HMUX_QUIT: case HMUX_EXIT: return code; default: if (code < 0) { return code; } len = hmux_read_len(s); cse_skip(s, len); break; } } }