handlers.html 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. {
  2. title: 'Creating Handlers',
  3. crumbs: [
  4. { "Developer's Guide": '../developers/' },
  5. ],
  6. }
  7. <h1>Creating GoAhead Handlers</h1>
  8. <p>GoAhead responds to client requests by routing the request to a request handler. The
  9. request handler is responsible for generating the response content or redirecting to another
  10. more suitable handler.</p>
  11. <p>GoAhead provides a suite of handlers for standard content types and web frameworks. But you can also create your own custom handler to process Http requests and perform any processing you desire. Once created handlers are configured via routes in the route table. See <a href="../users/routing.html">Request Routing</a> for more details about Routing.</p>
  12. <a id="processing"></a>
  13. <h2>Request Processing</h2>
  14. <p>When a request is received from the client, GoAhead parses the HTTP request headers and then determines the best GoAhead <a href="../users/routing.html">route</a> for the request. A route contains the full details for how to process a request including the required handler and required authentication. GoAhead matches each route in the route table in-order and selects the first matching route. The route specifies the desired handler for requests matching that route.</p>
  15. <h3>Matching a Handler</h3>
  16. <p>The last step of selecting a route is calling the candidate handler's optional match() callback. If the match callback returns true, the handler will be selected. If it returns false, the handler and route will be skipped and the route selection process continues.</p>
  17. <h3>Running a Handler</h3>
  18. <p>Once the route has been selected, GoAhead invokes the handler service callback to process the request and generate a response. At this point, request body data will be received and buffered. The handler may choose to not handler the request by returning a zero status code. In that case, the router continues matching routes to find a more suitable route and handler combination.</p>
  19. <a id="responses"></a>
  20. <h2>Generating Responses</h2>
  21. <p>An HTTP response consists of a status code, a set of HTTP headers and optionally a response body. If a
  22. status is not set, the successful status of 200 will be used. If not custom headers are defined, then a
  23. minimal standard set will be generated.</p>
  24. <h3>Setting Status and Headers</h3>
  25. <p>The response status may be set via:
  26. <a href="../ref/api/goahead.html#group___webs_1gaef03eccfb6f0d42b34f1a7a90bac62b6">websSetStatus</a>.
  27. The response headers may be set via:
  28. <a href="../ref/api/goahead.html#group___webs_1ga506c041a3eb2dfeaab1e9d1f322eea0b">websWriteHeaders</a>.
  29. For example:</p>
  30. <pre class="ui code segment">
  31. websSetStatus(wp, 200);
  32. websWriteHeaders(wp, contentLength, 0);
  33. websWriteHeader(wp, "X-MyCustomHeader", "1234");
  34. websWriteEndHeaders(wp);
  35. websWriteBlock(wp, buf, len);
  36. websDone(wp);
  37. </pre>
  38. <p>The websWriteBlock function will buffer written data that will be written to the client in the
  39. background.</p>
  40. <a id="errors"></a>
  41. <h3>Generating an Error Response</h3>
  42. <p>If the request has an error, the status and a response message may be set in one step via:
  43. <a href="../ref/api/goahead.html#group___webs_1ga3a9158494088fc25249543e69481e00e">websError</a>.
  44. When websError is called to indicate a request error, the supplied response text is used instead of
  45. any partially generated response body and the the connection field <em>conn-&gt;error</em> is set. Once
  46. set, pipeline processing is abbreviated and handler callbacks will not be called anymore. Consequently, if
  47. you need to continue handler processing, but want to set a non-zero status return code, do <i>not</i>
  48. use websError. Rather, use websSetStatus.</p>
  49. <pre class="ui code segment">
  50. websError(conn, 404, "Can't find %s", path);
  51. </pre>
  52. <h4>Aborting Requests</h4>
  53. <p>The status argument to websError can also accept flags to control how the socket connection is
  54. managed. If WEBS_CLOSE is supplied, the connection will be closed when the request is completed.
  55. Normally the connection is kept-open for subsequent requests on the same socket.</p>
  56. <pre class="ui code segment">
  57. websError(conn, 404 | WEBS_CLOSE, "Protocol error");
  58. </pre>
  59. <a id="redirecting"></a>
  60. <h3>Redirecting</h3>
  61. <p>Sometimes a handler will want to generate a response that will redirect the client to a new URI.
  62. Use the
  63. <a href="../ref/api/goahead.html#group___webs_1ga2a3e594ef28c12f3be0d7b54461af36e">websRedirect</a> call
  64. to redirect the client. For example:
  65. <pre class="ui code segment">websRedirect(wp, WEBS_CODE_MOVED_PERMANENTLY, uri);</pre>
  66. <h3>Generating Response Body</h3>
  67. <p>The simplest way to generate a response is to use
  68. <a href="../ref/api/goahead.html#group___webs_1ga8d5489a7fa2a2126bc0b6c703da4b964">websWrite</a>.
  69. The websWrite routine will automatically flush data as required. This routine may block while data drains
  70. to the client if the data cannot be buffered. See the <i>main.bit</i> configuration limit:
  71. <a href="../start/source.html#main">LimitBuffer</a> for how to control the internal buffer size.
  72. When all the data has been written, call:
  73. <a href="../ref/api/goahead.html#group___webs_1gac2af58b7a686cb33e44eb010cf755ce1">websDone</a>. This
  74. finalizes the request.</p>
  75. <pre class="ui code segment">
  76. websWrite(p, "Hello World\n");
  77. websDone(wp);
  78. </pre>
  79. <a id="defining"></a>
  80. <h2>Defining a Handler</h2>
  81. <p>To define an GoAhead handler, you need to call <a href=
  82. "../ref/api/goahead.html#group___webs_1gaac26a36fb28e1486fd54443ad59674a5">websDefineHandler</a>. For example:
  83. <pre class="ui code segment">
  84. static bool matchFoo(Webs *wp)
  85. {
  86. /* Handle request */
  87. return 1;
  88. }
  89. static bool serviceFoo(Webs *wp)
  90. {
  91. /* Do work here */
  92. return 1;
  93. }
  94. static void closeFoo() {
  95. /* Cleanup when goahead is exiting */
  96. }
  97. ...
  98. websDefineHandler("foo", matchFoo, serviceFoo, closeFoo, 0);
  99. </pre>