Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

support IO::Handle like object for response body

  • Loading branch information...
commit e37543bc0be9b1351373e702ca711b6a55ba010c 1 parent d175487
Masayoshi Sekimura authored October 16, 2009

Showing 1 changed file with 64 additions and 6 deletions. Show diff stats Hide diff stats

  1. 70  evpsgi.c
70  evpsgi.c
@@ -286,17 +286,73 @@ void add_headers(struct evhttp_request *req,  SV *headers )
286 286
     }
287 287
 }
288 288
 
289  
-void add_body(struct evbuffer *buf, struct evhttp_request *req,  SV *body )
  289
+int add_body(struct evbuffer *buf, struct evhttp_request *req,  SV *body )
290 290
 {
291  
-    SV *b;
292  
-    AV *body_av;
293  
-    I32 i, lastidx;
  291
+    int ret, type;
  292
+
  293
+    switch (type = SvTYPE(SvRV(body))) {
  294
+        case SVt_PVAV:
  295
+            ret = add_body_av(buf, req, (AV *) SvRV(body));
  296
+            break;
  297
+        case SVt_PVHV: /* IO::Handle::Iterator */
  298
+        case SVt_PVGV:
  299
+            if (!sv_derived_from(body, "IO::Handle")) {
  300
+                err(1, "response body must be devived from IO::Handle");
  301
+            }
  302
+            ret = add_body_iterator(buf, req, body);
  303
+            break;
  304
+        default:
  305
+            err(1, "response body must be an array reference or IO::Handle like object");
  306
+            ret = 0;
  307
+            break;
  308
+    }
  309
+
  310
+    return ret;
  311
+}
  312
+
  313
+int add_body_iterator(struct evbuffer *buf, struct evhttp_request *req,  SV *io )
  314
+{
  315
+    dTHX;
  316
+    SV *buf_sv;
294 317
     STRLEN len;
  318
+    dSP;
295 319
     char *line;
  320
+    int count;
  321
+
  322
+    ENTER;
  323
+    SAVETMPS;
296 324
 
297  
-    /*TODO: support IO::Handle-like object or a built-in filehandle */
  325
+    while (1) {
  326
+        PUSHMARK(SP);
  327
+        XPUSHs(io);
  328
+        PUTBACK;
  329
+        count = call_method("getline", G_SCALAR);
  330
+        SPAGAIN;
  331
+        buf_sv = POPs;
  332
+        if (!SvOK(buf_sv))
  333
+            break;
  334
+        line = SvPV(buf_sv, len);
  335
+        evbuffer_add(buf, line, len);
  336
+        count += len;
  337
+    }
  338
+    PUSHMARK(SP);
  339
+    XPUSHs(io);
  340
+    PUTBACK;
  341
+    call_method("close", G_DISCARD);
  342
+    SPAGAIN;
  343
+    PUTBACK;
  344
+    FREETMPS;
  345
+    LEAVE;
  346
+    return count;
  347
+}
298 348
 
299  
-    body_av = (AV *) SvRV(body);
  349
+int add_body_av(struct evbuffer *buf, struct evhttp_request *req,  AV *body_av )
  350
+{
  351
+    SV *b;
  352
+    I32 i, lastidx;
  353
+    STRLEN len;
  354
+    char *line;
  355
+    int ret;
300 356
 
301 357
     lastidx = av_len(body_av);
302 358
     for (i = 0; i <= lastidx; i++) {
@@ -304,8 +360,10 @@ void add_body(struct evbuffer *buf, struct evhttp_request *req,  SV *body )
304 360
         if (SvOK(b)) {
305 361
             line = SvPV(b, len);
306 362
             evbuffer_add(buf, line, len);
  363
+            ret += len;
307 364
         }
308 365
     }
  366
+    return ret;
309 367
 }
310 368
 
311 369
 void psgi_handler(struct evhttp_request *req, void *arg)

0 notes on commit e37543b

Please sign in to comment.
Something went wrong with that request. Please try again.