Because having only an ICAP server is boring because it is doing nothing. So you should write your first Service.
So lets start with a little template:
# load the icap server require 'icaprb/server' # create a class that inherits the base of (all) ICAP services in ICAPrb class SampleService < ::ICAPrb::Server::Services::ServiceBase # initialize the service: our module does only RESPMOD # (which means it has no support to edit responses which are # called REQMOD in the protocol and request_mod in ICAPrb) def initialize # the first parameter here is the service name used in the icap headers (not the URL) super('name',[:response_mod]) end # you need to override this method to do the work of your module def process_request(icap_server,ip,socket,data) # get the logger from the server to use it for sending data to the log # use it for errors in your module # logger = icap_server.logger # this creates a new ICAP response to be sent to the ICAP client response = ::ICAPrb::Server::Response.new # if you change the data, you should use 200. # If the data is unchanged and the client accepts 204, use it here # as it is shorter (less network traffic, better performance). response.icap_status_code = 200 http_resp_header = data[:http_response_header] http_resp_body = data[:http_response_body] # do your modification here # modified is a variable you must set if modified # this will update the HTTP Content-Length header because the length may have changed # (for example if you removed ad tags, the content is shorter now) http_resp_header['Content-Length'] = http_resp_body.length.to_s # this is required by the interface of ICAPrb::Server # it detects that this string is an ICAP response body by checking the type (class) http_resp_body = ::ICAPrb::Server::ResponseBody.new(http_resp_body) # add the components to your response - order does not matter because it will find it by the type - other types are ignored. # If you have an error here, your response may be malformed and your ICAP service is broken - make sure you are not using a wrong type like string. response.components << http_resp_header response.components << http_resp_body # this method sends only the headers to the socket, not the content itself - if your response.write_headers_to_socket socket # send everything in one chunk - you could use multiple but you are not required to - on large downloads, this may make sense socket.write(http_resp_body.to_chunk) # this methods sends the last chunk of your connection - after that, the connection may be terminated ::ICAPrb::Server::Response.send_last_chunk(socket,false) else # Just send a 204 message (we do not check if it is supported here because this is only a short sample). response.icap_status_code = 204 response.write_headers_to_socket socket end end end
The next step is using it in your ICAPrb server. It is really simple. If
s contains the instance of your server, you only need to attach it.
# this makes your service available as service. # For example, your URL may look like icap://[::1]:1344/service s.services['service'] = SampleService.new