patx/mrhttp-asgi

Speed up the mime type setting

Commit cda4a3f · MarkReedZ · 2024-03-07T07:33:53Z

Changeset
cda4a3f37cd340a1d0fa96b326d27a6e81db47dc
Parents
e1f1e646664a3672e4265489b3dad350b1cb1f6d

View source at this commit

Comments

No comments yet.

Log in to comment

Diff

diff --git a/src/mrhttp/internals/protocol.c b/src/mrhttp/internals/protocol.c
index a1c77b7..dc77c28 100644
--- a/src/mrhttp/internals/protocol.c
+++ b/src/mrhttp/internals/protocol.c
@@ -618,6 +618,8 @@ Protocol* Protocol_handle_request(Protocol* self, Request* request, Route* r) {
 
 
   if ( r->iscoro ) {
+    response_setMimeType(r->mtype); // TODO this doesn't work if we pipeline different types
+
     DBG printf("protocol - Request is a coroutine\n");
     PyObject *task;
     if(!(task = PyObject_CallFunctionObjArgs(self->create_task, result, NULL))) return NULL;
@@ -651,7 +653,7 @@ Protocol* Protocol_handle_request(Protocol* self, Request* request, Route* r) {
     return NULL;
   }
 
-  request->response->mtype = r->mtype;
+  response_setMimeType(r->mtype);
 
   if(!protocol_write_response(self, request, result)) goto error;
 
@@ -728,9 +730,6 @@ static inline Protocol* protocol_write_response(Protocol* self, Request *req, Py
   Py_DECREF(o);
   Py_DECREF(bytes);
 
-  // If we modified the header in the response buffer return it to default TODO
-  if ( req->response->mtype ) response_setHtmlHeader();
-
   if ( req != self->request ) MrhttpApp_release_request( self->app, req );
   else                        Request_reset(req);
   return self;
@@ -858,6 +857,7 @@ static void* protocol_pipeline_ready(Protocol* self, PipelineRequest r)
     return NULL;
   }
 
+
   if(!self->closed) {
     if(!protocol_write_response(self, request, response)) goto error;
   } else {
diff --git a/src/mrhttp/internals/response.c b/src/mrhttp/internals/response.c
index 5d90379..5413ecb 100644
--- a/src/mrhttp/internals/response.c
+++ b/src/mrhttp/internals/response.c
@@ -13,6 +13,8 @@ static char *resp_mrp   = "application/mrpacker\r\n\r\n";
 static char *rbuf   = NULL;
 static char *errbuf = NULL;
 static int rbuf_sz = 0;
+static int mime_type = 0;
+static int mime_type_end = 144;
 
 PyObject* Response_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
@@ -63,7 +65,6 @@ char *getResponseBuffer(int sz) {
 
 int Response_init(Response* self, PyObject *args, PyObject* kw)
 {
-  self->mtype = 0;
   self->headers = NULL;
   self->cookies = NULL;
   return 0;
@@ -79,21 +80,19 @@ PyObject *response_updateDate(PyObject *date) {
   Py_RETURN_NONE;
 }
 
-void response_setHtmlHeader() {
-  memcpy( rbuf+116, resp_html, 28 );
+void response_setMimeType(int mt) {
+  if ( mt != mime_type ) {
+    mime_type = mt;
+    if      ( mime_type == 1 ) { memcpy( rbuf+116, resp_plain, 14 ); mime_type_end = 130;  }
+    else if ( mime_type == 2 ) { memcpy( rbuf+116, resp_json,  20 ); mime_type_end = 136; }
+    else if ( mime_type == 3 ) { memcpy( rbuf+116, resp_mrp,   24 ); mime_type_end = 140; }
+    else                       { memcpy( rbuf+116, resp_html,  28 ); mime_type_end = 144; }
+  }
 }
 
 // Returns the header length
 int response_updateHeaders(Response *self) {
-  int ret = 144;
-
-  // Set Content-Type:  1 plain, 2 json, default is html
-  if ( self->mtype ) {
-    char *p = rbuf;
-    if      ( self->mtype == 1 ) { memcpy( p+116, resp_plain, 14 ); ret = 130; }
-    else if ( self->mtype == 2 ) { memcpy( p+116, resp_json,  20 ); ret = 136; }
-    else if ( self->mtype == 3 ) { memcpy( p+116, resp_mrp,   24 ); ret = 140; }
-  } 
+  int ret = mime_type_end; // Mime type is the last header in the response
 
   if ( self->headers != NULL ) {
     int hlen = response_add_headers( self, rbuf+ret-2 );
diff --git a/src/mrhttp/internals/response.h b/src/mrhttp/internals/response.h
index de65a5f..7d51a2e 100644
--- a/src/mrhttp/internals/response.h
+++ b/src/mrhttp/internals/response.h
@@ -26,6 +26,7 @@ typedef struct {
   PyObject* cookies;
 
   int mtype; // mime type 0 html 1 plain 2 json
+  int mtype_end;
 
   char* buffer;
   size_t buffer_len;
@@ -40,6 +41,7 @@ void Response_reset(Response *self);
 
 PyObject *response_updateDate(PyObject *date);
 int       response_updateHeaders(Response *self);
+void      response_setMimeType(int mt);
 void      response_setHtmlHeader(void);
 
 PyObject* Response_get_headers(Response* self, void* closure);
diff --git a/tst.py b/tst.py
index 2dbdaf5..b260293 100755
--- a/tst.py
+++ b/tst.py
@@ -1,7 +1,8 @@
 
 import traceback
 from mrhttp import app
-#import asyncmrq, mrpacker
+import mrpacker
+
 
 app.config["memcache"] = [ ("127.0.0.1", 11211) ]
 
@@ -11,8 +12,8 @@ app.config["memcache"] = [ ("127.0.0.1", 11211) ]
   #await app.c.connect(servers=[("127.0.0.1",7100)])
 
 #@app.route('/',options=['session'])
[email protected]('/')
-async def index(r):
[email protected]('/',_type="html")
+def index(r):
   print( r.headers )
   #print( r.ip )
   return "yay"  
@@ -25,13 +26,13 @@ async def index(r):
 def json(r):
   return r.json["name"]
 
[email protected]('/mrpacker')
-def mrpacker(r):
-  return r.mrpack["name"]
[email protected]('/mrp',_type="mrp")
+def mrp(r):
+  return mrpacker.pack("hello")
 
 
 try:
-  app.run(cores=4)
+  app.run(cores=1)
 except Exception as e:
   print("YAY",e)