Permalink
Browse files

Move constants to top of Feersum.xs and POD them.

  • Loading branch information...
1 parent 9e1961e commit dcde0d60eac1cd8b2eb518e306c519e5f2a299b3 @stash committed Sep 8, 2011
Showing with 147 additions and 63 deletions.
  1. +46 −32 Feersum.xs
  2. +1 −13 Makefile.PL
  3. +100 −18 lib/Feersum.pm
View
@@ -11,6 +11,35 @@
#include "ppport.h"
+
+///////////////////////////////////////////////////////////////
+// "Compile Time Options" - See Feersum.pm POD for information
+
+#define MAX_HEADERS 64
+#define MAX_HEADER_NAME_LEN 128
+#define MAX_BODY_LEN 2147483647
+
+#define READ_BUFSZ 4096
+#define READ_INIT_FACTOR 2
+#define READ_GROW_FACTOR 8
+
+#define AUTOCORK_WRITES 1
+
+#define FLASH_SOCKET_POLICY_SUPPORT
+#define FLASH_SOCKET_POLICY "<?xml version=\"1.0\"?>\n<!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">\n<cross-domain-policy>\n<site-control permitted-cross-domain-policies=\"master-only\"/>\n<allow-access-from domain=\"*\" to-ports=\"*\" secure=\"false\"/>\n</cross-domain-policy>\n"
+
+// may be lower for your platform (e.g. Solaris is 16). See POD.
+#define FEERSUM_IOMATRIX_SIZE 64
+
+// auto-detected in Makefile.PL by perl versions and ithread usage; override
+// that here. See POD for details.
+#if 0
+# undef FEERSUM_STEAL
+#endif
+
+///////////////////////////////////////////////////////////////
+
+
#ifdef __GNUC__
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
@@ -50,26 +79,6 @@
#define Sz unsigned Sz_t
#define Ssz Sz_t
-// if you change these, also edit the LIMITS section in the POD
-#define MAX_HEADERS 64
-#define MAX_HEADER_NAME_LEN 128
-#define MAX_BODY_LENGTH 2147483647
-
-// Read buffers start out at READ_INIT_FACTOR * READ_BUFSZ bytes.
-// If another read is needed and the buffer is under READ_BUFSZ bytes
-// then the buffer gets an additional READ_GROW_FACTOR * READ_BUFSZ bytes.
-// The trade-off with the grow factor is memory usage vs. system calls.
-#define READ_BUFSZ 4096
-#define READ_INIT_FACTOR 2
-#define READ_GROW_FACTOR 8
-
-// Setting this to true will wait for writability before calling write() (will
-// try to immediately write otherwise)
-#define AUTOCORK_WRITES 1
-
-// Setting this to true will enable Flash Socket Policy support
-#define FLASH_SOCKET_POLICY_SUPPORT 1
-
#define WARN_PREFIX "Feersum: "
#ifndef DEBUG
@@ -105,10 +114,13 @@
#include "rinq.c"
// Check FEERSUM_IOMATRIX_SIZE against what's actually usable on this
-// platform. See $iomatrix_size in Makefile.PL for the default.
-#if FEERSUM_IOMATRIX_SIZE > IOV_MAX
+// platform. See Feersum.pm for an explanation
+#if defined(IOV_MAX) && FEERSUM_IOMATRIX_SIZE > IOV_MAX
# undef FEERSUM_IOMATRIX_SIZE
# define FEERSUM_IOMATRIX_SIZE IOV_MAX
+#elif defined(UIO_MAXIOV) && FEERSUM_IOMATRIX_SIZE > UIO_MAXIOV
+# undef FEERSUM_IOMATRIX_SIZE
+# define FEERSUM_IOMATRIX_SIZE UIO_MAXIOV
#endif
struct iomatrix {
@@ -328,12 +340,10 @@ add_sv_to_wbuf(struct feer_conn *c, SV *sv)
else if (unlikely(SvPADTMP(sv))) {
// PADTMPs have their PVs re-used, so we can't simply keep a
// reference. TEMPs maybe behave in a similar way and are potentially
- // stealable.
+ // stealable. If not stealing, we must make a copy.
#ifdef FEERSUM_STEAL
if (SvFLAGS(sv) == SVs_PADTMP|SVf_POK|SVp_POK) {
trace3("STEALING\n");
- // XXX: EGREGIOUS HACK THAT MAKES THINGS A LOT FASTER
- // steal the PV from a PADTMP PV
SV *theif = newSV(0);
sv_upgrade(theif, SVt_PV);
@@ -352,11 +362,9 @@ add_sv_to_wbuf(struct feer_conn *c, SV *sv)
sv = theif;
}
else {
- // be safe and just make a copy
sv = newSVsv(sv);
}
#else
- // Make a simple copy (which duplicates the PV almost all of the time)
sv = newSVsv(sv);
#endif
}
@@ -994,20 +1002,26 @@ try_conn_read(EV_P_ ev_io *w, int revents)
SvCUR(c->rbuf) += got_n;
// likely = optimize for small requests
if (likely(c->receiving == RECEIVE_HEADERS)) {
+
#ifdef FLASH_SOCKET_POLICY_SUPPORT
if (unlikely(*SvPVX(c->rbuf) == '<')) {
- if (likely(SvCUR(c->rbuf) >= 22)) {
- if (strnEQ(SvPVX(c->rbuf), "<policy-file-request/>", 22)) {
- add_const_to_wbuf(c, "<?xml version=\"1.0\"?>\n<!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">\n<cross-domain-policy>\n<site-control permitted-cross-domain-policies=\"master-only\"/>\n<allow-access-from domain=\"*\" to-ports=\"*\" secure=\"false\"/>\n</cross-domain-policy>\n", 263);
+ if (likely(SvCUR(c->rbuf) >= 22)) { // length of vvv
+ if (str_eq(SvPVX(c->rbuf), 22, "<policy-file-request/>", 22)) {
+ add_const_to_wbuf(c, STR_WITH_LEN(FLASH_SOCKET_POLICY));
conn_write_ready(c);
stop_read_watcher(c);
stop_read_timer(c);
+ // TODO: keep-alives: be sure to remove the 22 bytes
+ // out of the rbuf
change_receiving_state(c, RECEIVE_SHUTDOWN);
change_responding_state(c, RESPOND_SHUTDOWN);
goto dont_read_again;
}
}
- else if (likely(strnEQ(SvPVX(c->rbuf), "<policy-file-request/>", SvCUR(c->rbuf)))) {
+ // "if prefixed with"
+ else if (likely(str_eq(SvPVX(c->rbuf), SvCUR(c->rbuf),
+ "<policy-file-request/>", SvCUR(c->rbuf))))
+ {
goto try_read_again;
}
}
@@ -1245,7 +1259,7 @@ process_request_headers (struct feer_conn *c, int body_offset)
{
int g = grok_number(hdr->value, hdr->value_len, &expected);
if (likely(g == IS_NUMBER_IN_UV)) {
- if (unlikely(expected > MAX_BODY_LENGTH)) {
+ if (unlikely(expected > MAX_BODY_LEN)) {
err_code = 413;
err = "Content length exceeds maximum\n";
goto got_bad_request;
View
@@ -68,17 +68,6 @@ if ($convert_deps) {
use Config;
my $steal = ($] >= 5.012 && !defined($Config{useithreads}));
-# Control the size of the main write-buffer structure in feersum. Making this
-# value lower will use slightly less memory per connection at the cost of
-# speed and vice-versa. It's most noticeable when you're app is buffering a
-# lot of sparce writes. The default of 64 generally keeps usage under 4k per
-# connection on full 64-bit when you take into account the other connection
-# and request structures.
-# NOTE: If your OS defines IOV_MAX or UIO_MAXIOV then this value will be
-# forced to be at most that size with a #define. Solaris defines IOV_MAX to
-# be 16. Linux and OSX generally have IOV_MAX as 1024.
-my $iomatrix_size = 64;
-
WriteMakefile(ev_args(
NAME => 'Feersum',
VERSION_FROM => 'lib/Feersum.pm',
@@ -113,8 +102,7 @@ WriteMakefile(ev_args(
},
LIBS => [''],
EXE_FILES => ['bin/feersum'],
- DEFINE => "-DFEERSUM_IOMATRIX_SIZE=$iomatrix_size ".
- ($steal ? '-DFEERSUM_STEAL' : ''),
+ DEFINE => ($steal ? '-DFEERSUM_STEAL' : ''),
INC => '-I.',
dynamic_lib => {OTHERLDFLAGS => $otherldflags},
));
View
@@ -461,33 +461,111 @@ Override Feersum's notion of what SERVER_HOST and SERVER_PORT should be.
=cut
-=head1 LIMITS
+=head1 GRITTY DETAILS
+
+=head2 Compile Time Options
+
+There are a number of constants at the top of Feersum.xs. If you change any
+of these, be sure to note that in any bug reports.
=over 4
-=item HTTP methods
+=item MAX_HEADERS
+
+Defaults to 64. Controls how many headers can be present in an HTTP request.
+
+If a request exceeds this limit, a 400 response is given and the app handler does not run.
+
+=item MAX_HEADER_NAME_LEN
+
+Defaults to 128. Controls how long the name of each header can be.
+
+If a request exceeds this limit, a 400 response is given and the app handler does not run.
+
+=item MAX_BODY_LEN
+
+Defaults to ~2GB. Controls how large the body of a POST/PUT/etc. can be when
+that request has a C<Content-Length> header.
+
+If a request exceeds this limit, a 413 response is given and the app handler does not run.
+
+See also BUGS
+
+=item READ_BUFSZ
+
+=item READ_INIT_FACTOR
-Only GET POST PUT DELETE HEAD - others are not supported.
+=item READ_GROW_FACTOR
-=item listening sockets
+READ_BUFSZ defaults to 4096, READ_INIT_FACTOR 2 and READ_GROW_FACTOR 8.
-1 - this may be considered a bug
+Together, these tune how data is read for a request.
-=item body length
+Read buffers start out at READ_INIT_FACTOR * READ_BUFSZ bytes.
+If another read is needed and the buffer is under READ_BUFSZ bytes
+then the buffer gets an additional READ_GROW_FACTOR * READ_BUFSZ bytes.
+The trade-off with the grow factor is memory usage vs. system calls.
-2147483647 - about 2GiB.
+=item AUTOCORK_WRITES
-=item request headers
+Controls how response data is written to sockets. If enabled (the default)
+the event loop is used to wait until the socket is writable, otherwise a write
+is performed immediately. In either case, non-blocking writes are used.
+Using the event loop is "nicer" but perhaps introduces latency, hence this
+option.
-64
+=item FLASH_SOCKET_POLICY_SUPPORT
-=item request header name length
+=item FLASH_SOCKET_POLICY
-128 bytes
+FLASH_SOCKET_POLICY_SUPPORT defaults to enabled.
-=item bytes read per read() system call
+When it's enabled, Feersum will detect a Flash C<< <policy-file-request/> >>
+packet and respond with the FLASH_SOCKET_POLICY string.
-4096 bytes
+The default FLASH_SOCKET_POLICY string looks like this:
+
+ <?xml version="1.0"?>
+ <!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd">
+ <cross-domain-policy>
+ <site-control permitted-cross-domain-policies="master-only"/>
+ <allow-access-from domain="*" to-ports="*" secure="false"/>
+ </cross-domain-policy>
+
+Since that's fairly wide-open, you may wish to disable
+FLASH_SOCKET_POLICY_SUPPORT. Note that this feature likely won't work if you
+use a front-end HTTP server like nginx since the request isn't valid HTTP.
+
+=item FEERSUM_IOMATRIX_SIZE
+
+Controls the size of the main write-buffer structure in Feersum. Making this
+value lower will use slightly less memory per connection at the cost of speed
+(and vice-versa for raising the value). The effect is most noticeable when
+you're app is making a lot of sparce writes. The default of 64 generally
+keeps usage under 4k per connection on full 64-bit platforms when you take
+into account the other connection and request structures.
+
+B<NOTE>: FEERSUM_IOMATRIX_SIZE cannot exceed your OS's defined IOV_MAX or
+UIO_MAXIOV constant. Solaris defines IOV_MAX to be 16, making it the default
+on that platform. Linux and OSX seem to set this at 1024.
+
+=item FEERSUM_STEAL
+
+For non-threaded perls >= 5.12.0, this defaults to enabled.
+
+When enabled, Feersum will "steal" the contents of temporary lexical scalars
+used for response bodies. The scalars become C<undef> as a result, but due to
+them being temps they likely aren't used again anyway. Stealing saves the
+time and memory needed to make a copy of that scalar, resulting in a mild to
+moderate performance boost.
+
+This egregious hack only extends to non-magical, string, C<PADTMP> scalars.
+
+If it breaks for your new version of perl, please send stash a note (or a pull
+request!) on github.
+
+Worth noting is that a similar zero-copy effect can be achieved by using the
+C<psgix.body.scalar_refs> feature.
=back
@@ -497,10 +575,10 @@ Please report bugs using http://github.com/stash/Feersum/issues/
Keep-alive is ignored completely.
-Currently there's no way to limit the request entity length of a POST/PUT/etc.
-This could lead to a DoS attack on a Feersum server. Suggested remedy is to
-only run Feersum behind some other web server and to use that to limit the
-entity size.
+Currently there's no way to limit the request entity length of a B<streaming>
+POST/PUT/etc. This could lead to a DoS attack on a Feersum server. Suggested
+remedy is to only run Feersum behind some other web server and to use that to
+limit the entity size.
Although not explicitly a bug, the following may cause undesirable behavior.
Feersum will have set SIGPIPE to be ignored by the time your handler gets
@@ -537,9 +615,13 @@ Hans Dieter Pearcey (confound) for docs and packaging guidance.
For bug reports: Chia-liang Kao (clkao), Lee Aylward (leedo)
+Audrey Tang (au) for flash socket policy support.
+
=head1 COPYRIGHT AND LICENSE
-Copyright (C) 2010 by Jeremy Stashewsky & Socialtext Inc.
+Copyright (C) 2011 by Jeremy Stashewsky
+
+Portions Copyright (C) 2010 Socialtext Inc.
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.7 or,

0 comments on commit dcde0d6

Please sign in to comment.