RFC 3050

Common Gateway Interface for SIP

๐Ÿ“… published January 2001, from ietf

RFC 3050: Common Gateway Interface for SIP ๐ŸŽ€

Part 1 of 7 ๐Ÿ’–

okay bestie, this is RFC 3050, and it's called Common Gateway Interface for SIP ๐Ÿ“žโœจ It came from the Network Working Group in January 2001. The authors are J. Lennox (Columbia U.), H. Schulzrinne (Columbia U.), and J. Rosenberg (dynamicsoft). It's Informational, so it's sharing info, not setting a standard. It doesn't say it obsoletes or updates any other RFC, so it isn't replacing or tweaking anything. ๐Ÿฆ‹

Status of This Memo โœจ

this memo gives info to the Internet community ๐ŸŒธ it does not specify an Internet standard of any kind, and distribution of it is unlimited, so share away ๐Ÿ’…

Copyright (C) The Internet Society (2001). All Rights Reserved.

Abstract ๐Ÿงš

okay so in internet telephony, there has to be a way to make new services super fast โšก on the World Wide Web, the Common Gateway Interface (CGI) has been the popular way to program web services, and since SIP and HTTP are so alike, CGI is a really good fit for making services in a SIP environment ๐Ÿ™ˆ this doc defines a SIP CGI interface for offering SIP services on a SIP server. iconic ๐Ÿ‘‘

IESG Note ๐Ÿ’œ

the IESG notes that the mechanism here depends on the Common Gateway Interface. if that interface changes or gets upgraded, this spec might need changes too, and that's just how it goes ๐Ÿซถ according to the W3C, CGI is currently maintained by the NCSA Software Development Group. for more on where CGI stands right now, check out:

http://www.w3c.org/cgi

Table of Contents ๐Ÿ—‚๏ธ

1          Introduction .......................................   3
2          Motivations ........................................   4
3          Differences from HTTP CGI ..........................   5
3.1        Basic Model ........................................   6
3.2        Persistence Model ..................................   8
3.3        SIP CGI Triggers ...................................   9
3.4        Naming .............................................   9
3.5        Environment Variables ..............................   9
3.6        Timers .............................................  10
4          Overview of SIP CGI ................................  10
5          SIP CGI Specification ..............................  12
5.1        Introduction .......................................  12
5.1.1      Relationship with HTTP CGI .........................  12
5.1.2      Conventions of This Document .......................  12
5.1.3      Specifications .....................................  12
5.1.4      Terminology ........................................  13
5.2        Notational Conventions and Generic Grammar .........  13
5.3        Invoking the Script ................................  14
5.4        The SIP CGI Script Command Line ....................  14
5.5        Data Input to the SIP CGI Script ...................  14
5.5.1      Message Metadata (Metavariables) ...................  14
5.5.1.1    AUTH_TYPE ..........................................  16
5.5.1.2    CONTENT_LENGTH .....................................  16
5.5.1.3    CONTENT_TYPE .......................................  17
5.5.1.4    GATEWAY_INTERFACE ..................................  17
5.5.1.5    Protocol-Specific Metavariables ....................  18
5.5.1.6    REGISTRATIONS ......................................  18
5.5.1.7    REMOTE_ADDR ........................................  19
5.5.1.8    REMOTE_HOST ........................................  19
5.5.1.9    REMOTE_IDENT .......................................  19
5.5.1.10   REMOTE_USER ........................................  20
5.5.1.11   REQUEST_METHOD .....................................  20
5.5.1.12   REQUEST_TOKEN ......................................  21
5.5.1.13   REQUEST_URI ........................................  21
5.5.1.14   RESPONSE_STATUS ....................................  21
5.5.1.15   RESPONSE_REASON ....................................  21
5.5.1.16   RESPONSE_TOKEN .....................................  21
5.5.1.17   SCRIPT_COOKIE ......................................  22
5.5.1.18   SERVER_NAME ........................................  22
5.5.1.19   SERVER_PORT ........................................  22
5.5.1.20   SERVER_PROTOCOL ....................................  22
5.5.1.21   SERVER_SOFTWARE ....................................  23
5.5.2      Message Bodies .....................................  23
5.6        Data Output from the SIP CGI Script ................  23
5.6.1      CGI Action Lines ...................................  25
5.6.1.1    Status .............................................  25
5.6.1.2    Proxy Request ......................................  25
5.6.1.3    Forward Response ...................................  26
5.6.1.4    Script Cookie ......................................  26
5.6.1.5    CGI Again ..........................................  27
5.6.1.6    Default Action .....................................  27
5.6.2      CGI Header Fields ..................................  28
5.6.2.1    Request-Token ......................................  28
5.6.2.2    Remove .............................................  28
5.7        Local Expiration Handling ..........................  28
5.8        Locally-Generated Responses ........................  29
5.9        SIP CGI and REGISTER ...............................  29
5.10       SIP CGI and CANCEL .................................  29
5.11       SIP CGI and ACK ....................................  30
5.11.1     Receiving ACK's ....................................  30
5.11.2     Sending ACK's ......................................  30
6          System Specifications ..............................  30
6.1        Unix ...............................................  30
6.2        Microsoft Windows ..................................  31
7          Security Considerations ............................  31
7.1        Request Initiation .................................  31
7.2        Authenticated and Encrypted Messages ...............  31
7.3        SIP Header Fields Containing Sensitive Information..  32
7.4        Script Interference with the Server ................  32
7.5        Data Length and Buffering Considerations ...........  32
8          Acknowledgements ...................................  33
9          Authors' Addresses .................................  33
10         Bibliography .......................................  34
11         Full Copyright Statement ...........................  35

1. Introduction ๐ŸŒˆ

okay so in internet telephony, there has to be a way to make new services and roll them out really fast ๐Ÿš€ back in traditional telephony networks, that happened through IN service creation environments, which gave you an interface for building new services, often with GUI-based tools ๐Ÿ–ฑ๏ธ

the WWW has its own toolkit for service creation too ๐Ÿงฐ at first, web servers just turned URLs into filenames on a local system and sent back the file contents. then servers got dynamic content, and forms let people send in input. basically, that became a way to create services on the web ๐Ÿ’… now there are tons of ways to make dynamic web content, like server side JavaScript, servlets, and the common gateway interface (CGI) [1] ๐Ÿ“

multimedia communications, Internet telephony included, are gonna need a way to create services too ๐Ÿ“ฑ that mechanism is super tied to the features of the signaling protocols. the Session Initiation Protocol (SIP) [2] was built to start and end multimedia sessions ๐Ÿ“ž SIP borrows a lot from HTTP, inheriting its client-server interaction and much of its syntax and semantics ๐Ÿซถ so that's why web service creation environments, and CGI especially, look like a great starting point for SIP-based service creation environments ๐Ÿฆ‹

2. Motivations ๐Ÿ’–

CGI has a bunch of strengths that make it a total slay for creating SIP services ๐Ÿ‘‘

  • Language independence: CGI works with perl, C, VisualBasic, tcl, and many other languages, as long as they can access environment variables ๐ŸŒธ
  • Exposes all headers: CGI exposes the content of all the headers in an HTTP request to the CGI application ๐Ÿ‘€ the app can use whichever ones it wants and ignore the rest, so every part of an HTTP request can be considered when making content ๐Ÿ’… in a SIP environment, headers matter even more than in HTTP ๐Ÿ˜ญ they carry critical info about the transaction, like caller and callee, subject, contact addresses, organizations, extension names, registration parameters and expirations, call status, and call routes, to name a few ๐Ÿ“‹ so it's critical for SIP services to get as much access to these headers as possible, and that's why CGI is so attractive ๐Ÿ”ฅ
  • Creation of responses: CGI can create all parts of a response, including headers, status codes and reason phrases, plus message bodies ๐ŸŽ€ other mechanisms, like Java servlets, mostly focus on the body, so they don't do this ๐Ÿ™… in a SIP environment it's critical to be able to generate every aspect of a response (and every aspect of new or proxied requests too), since the body usually isn't the main event in SIP service creation ๐Ÿ’€
  • Component reuse: lots of CGI utilities make it easy to read environment variables, parse form data, and often parse and generate header fields ๐Ÿงš since SIP reuses the basic RFC822 [3] syntax of HTTP, a lot of these tools work for SIP CGI too โœจ
  • Familiar environment: lots of web programmers already know CGI ๐Ÿ™Œ
  • Ease of extensibility: since CGI is an interface and not a language, it's easy to extend it and reapply it to other protocols, like SIP ๐Ÿฆ‹

so yeah, the generality, extensibility, and detailed control and access to information that CGI gives you, plus the whole range of tools that already exist for it that can be used right away with SIP, make it a seriously good mechanism for SIP service creation ๐Ÿ†๐Ÿ’œ

3. Differences from HTTP CGI โœจ

okay so SIP and HTTP are basically twins ๐Ÿ‘ฏโ€โ™€๏ธ: same basic syntax and same request-response model. but they're not identical, and the differences are juicy. ๐Ÿ”ฅ Proxies matter a LOT for SIP services, while they're kinda background characters in HTTP. SIP servers can fork requests (one request comes in, several go out), which is a capability HTTP just doesn't have ๐Ÿ’…. SIP also has features like registrations that HTTP doesn't have at all. All of this shows up in the gap between SIP CGI and HTTP CGI. SIP CGI runs mostly on proxy, redirect, and registrar servers, not on user agent servers (those are the SIP version of origin servers in HTTP). SIP CGI lets the script do messaging stuff HTTP CGI can't, like proxying requests, and it adds a persistence model so a script can stay in control across multiple message exchanges. HTTP CGI has no persistence for scripts. none. zero. ๐Ÿ˜ญ

3.1. Basic Model

The basic model for HTTP CGI is depicted in figure 1.

                -----    ------------
     ~~~~~~~~  |req  |  |  --------  |
    |        |----------| |  http  | |
    | client | |resp |  | | server | |
    |        |----------| |        | |w
     ~~~~~~~~  |     |  |  --------  |e
                -----   |  s|  /\s   |b
               net      |  t|   |t   |
                        |e d| C |d   |s
                        |n i| G |o   |e
                        |v n| I |u   |r
                        |   |   |t   |v
                        |  \/   |    |e
                        |  -------   |r
                        | |       |  |
                        | |  CGI  |  |
                        | | prog. |  |
                        | |       |  |
                        |  -------   |
                         ------------

Figure 1: HTTP CGI Model

A client sends an HTTP request, which goes either straight to the origin server (like in the picture) or gets forwarded through a proxy server ๐Ÿš€. The origin server runs a CGI script, and the script sends back a response, which goes back to the client. The main job of the script is to generate the body for the response. Only origin servers run CGI scripts, not proxy servers. proxies are not doing the script life ๐Ÿ™…โ€โ™€๏ธ.

In a SIP server, the model is different, and it's shown in Figure 2.

     ~~~~~~~~   req  -------   req   -------     req   ~~~~~~~~
    |        |------|       |-------|       |---------|        |
    | client | resp | server| resp  | server| resp    | client |
    |        |------|       |-------|       |---------|        |
     ~~~~~~~~        -------         -------           --------
                      |   | CGI
                      |   |
                     -------
                    |       |
                    |  CGI  |
                    | prog. |
                    |       |
                     -------

Figure 2: SIP CGI Model

The client generates a request, which gets forwarded to a server. The server may generate a response (like an error or a redirect response) ๐Ÿ™ƒ. Or, if the server is a proxy server, the request gets proxied to another server, and eventually to a user agent. The response then travels back upstream through the server and back towards the client. A SIP proxy server may also fork requests, generating multiple requests in response to one received request. Generally, a proxy server won't generate the content in responses. Those contain session descriptions created by user agents. Services like call forward and mobility services are based on the decisions the server makes about (1) when, to where, and how many requests to proxy downstream, and (2) when to send a response back upstream. Creating services like ad-hoc bridging (where the server acts as a media mixer in a multiparty call, without being asked to do so by the end users) will require the server to generate new requests of its own, and to modify and generate the body in responses. that's a whole plot twist ๐ŸŽญ.

An HTTP server is mainly concerned with generating responses. A SIP server is generally concerned with four basic operations:

  • Proxying of Requests: Receiving a request, adding or modifying any of the headers, deciding on a set of servers to forward the request to, and forwarding it to them.
  • Returning Responses: Receiving a response, adding or modifying any of the headers, and passing the response towards the client.
  • Generating Requests: Creating a new request that originates at the server, placing headers and a body into the message, and sending it to a server.
  • Generation of Responses: Receiving a request, generating a response to it, and sending it back to the client.

When a request comes in, one or more of the above operations may happen at once ๐ŸŒ€. For example, a SIP server may generate a provisional response, generate a new request, and proxy the original request to two servers. This means SIP CGI has to cover a bigger set of functions than HTTP CGI. These functions are a super-set of the simple end-server request/response model ๐Ÿ‘‘.

3.2. Persistence Model

In HTTP CGI, a script runs once for each request. It generates the response, and then it terminates ๐Ÿ’€. As a general rule, no state is kept across requests from the same user (although this can be done, and it is, for more complex services like database accesses, which basically encapsulate state in client-side cookies or dynamically-generated URLs ๐Ÿช). A transaction is just a single request and a response.

In SIP CGI, since one request can generate many new and proxied requests, those requests will generate responses too. A service will often need these responses processed, and additional requests or responses generated. So while an HTTP CGI script runs once per transaction, a SIP CGI script has to somehow keep control over numerous events ๐Ÿคนโ€โ™€๏ธ.

To make this work, and to stay true to the original CGI model, we mandate that a SIP CGI script runs when a message arrives, and then terminates after generating output (in the form of additional messages). State is maintained by letting the CGI return an opaque token to the server. When the CGI script is called again for the same transaction, this token is passed back to it. When it's called for a new transaction, no token is passed ๐ŸŽŸ๏ธ.

For example, say a request arrives at a SIP server. The server calls a CGI script, which generates a provisional response and a proxied request. It also returns a token to the server, and then terminates. The response goes back upstream towards the client, and the request is proxied. When the response to the proxied request arrives, the script runs again. The environment variables are set based on the content of the new response. The script is also passed the token. Using the token as its state, the script decides to proxy the request to a different location. So it returns a proxied request, and another token. The server forwards this new request, and when the response comes back, it calls the CGI script once more and passes back the token. This time, the script generates a final response and passes it back to the server. The server sends the response to the client, destroys the token, and the transaction is complete ๐ŸŽ‰.

3.3. SIP CGI Triggers

In lots of cases, calling the CGI script on every single message is inefficient ๐Ÿ™„. CGI scripts come with a lot of overhead, since they generally require creating a new process. So it's important in SIP CGI for a script to say, after it's called the first time, under what conditions it will be called for the rest of the transaction. If the script isn't called, the server takes the "default" action, as specified in this document. This lets an application designer trade off flexibility for computational resources โš–๏ธ. Making an analogy to the Intelligent Network (IN): a script gets to define the triggers for its future execution. ooh, control ๐ŸŽฎ.

So, in summary: while an HTTP CGI script runs once during a transaction, a single SIP CGI script may run many times during a transaction, and it can specify at which points it wants control for the rest of the transaction ๐Ÿฆ‹.

3.4. Naming

In HTTP CGI, the CGI script itself is usually the resource named in the request URI. This is not so in SIP ๐Ÿ™…โ€โ™€๏ธ. In general, the request URI names a user to be called. The mapping to the script that gets executed may depend on other SIP headers, including To and From fields, the SIP method, status codes, and reason phrases. So the mapping of a message to a CGI script is purely a matter of local policy administration at a server ๐Ÿ“‹. A server may have a single script that always runs, or it may have multiple scripts, with the target picked by some parts of the header.

3.5. Environment Variables

In HTTP CGI, environment variables get set with the values of the paths and other aspects of the request ๐Ÿ›ฃ๏ธ. But there's no notion of a path in SIP, so some of these environment variables just don't make sense. bestie, that's a vibe check ๐Ÿซ .

3.6. Timers

In SIP, certain services need the script to get called not only when a message arrives, but also when some timer expires โฐ. The classic example of this is "call forward no answer." To be implemented with SIP CGI, the first time the script runs, it must generate a proxied request, and also indicate a time at which it should be called again if no response comes. This kind of feature isn't present in HTTP CGI, so some rudimentary support for it is needed in SIP CGI ๐Ÿงš.

4. Overview of SIP CGI โœจ

okay so bestie, when a request shows up at a SIP server and starts a brand new transaction, the server sets a bunch of environment variables and then calls a CGI script ๐Ÿ’…. The script gets the body of the request through stdin ๐Ÿซถ.

The script answers on stdout with a set of SIP action lines ๐ŸŽ€. Each action line can be modified by CGI and/or SIP headers. The whole set is delimited by two carriage returns ๐Ÿฆ‹. The action lines let the script pick any of the four operations we covered above, plus the default operation ๐Ÿ‘‘. To generate a response, you copy the status line of the response into an action line of the CGI output ๐Ÿ’–. For example, this creates a 200 OK to the original request:

SIP/2.0 200 OK

Proxying is handled by the CGI-PROXY-REQUEST action, which takes the URL to proxy to as an argument ๐Ÿงš. For example, to proxy a request to dante@inferno.com:

CGI-PROXY-REQUEST sip:dante@inferno.com SIP/2.0
Contact: sip:server1@company.com

In this example, the server takes the original request and tweaks any header fields that normally get changed during a proxy, like decrementing Max-Forwards and adding a Via field โœจ. Then the message gets "merged" with the CGI output. SIP headers written underneath the action line in the CGI output get added to the outbound request ๐ŸŒธ. In the example above, the Contact header gets added. Also, the action line looks like the request line of a SIP request message, and that's on purpose, because it makes parsing easier ๐Ÿ™ˆ.

To delete headers from the outgoing request, the merge process also supports the CGI header CGI-Remove ๐Ÿ—‘๏ธ. Like SIP headers, CGI headers are written underneath the action line. The SIP server pulls them out and uses them to get additional guidance. CGI headers always begin with CGI so they can be told apart from SIP headers. In this case, the supported values for the CGI-Remove header are the names of headers in the original message.

Returning responses is a little more complex ๐ŸŒˆ. A server may receive multiple responses because it forked a request. The script should be able to ask the server to return any of the responses it got earlier. To make that work, the server passes an opaque token to the script through environment variables, unique for each response received. To return a response, the CGI script has to say which response it wants back. For example, to return a response named with the token abcdefghij, this output gets generated:

CGI-FORWARD-RESPONSE abcdefghij SIP/2.0

Finally, if the script doesn't output any of the above actions, the server does whatever it would normally do when it receives the message that triggered the script ๐Ÿ’œ.

A SIP CGI script usually only runs when the original request arrives. But if the script also wants to be called for later messages in a transaction (because of responses to proxied requests, or, in certain circumstances, ACK and CANCEL requests), it can perform the CGI-AGAIN action ๐Ÿ”:

CGI-AGAIN yes SIP/2.0

This action only applies to the next invocation of the script. It means "invoke the script one more time." Outputting "no" is identical to outputting "yes" on this invocation, and then outputting nothing the next time the script is called ๐Ÿ™ƒ.

When the script runs again, it might need some state to keep going ๐Ÿง . A script can generate one piece of state, called a cookie, for any new request or proxied request. It gets passed to the server through the CGI-SET-COOKIE action. The action contains a token, which is the cookie itself. The server doesn't examine or parse the cookie. It just stores it. When the script is re-executed, the cookie gets passed back to the script through an environment variable ๐Ÿ“.

CGI-SET-COOKIE khsihppii8asdl SIP/2.0

Last but not least, when the script causes the server to proxy a request, responses to those requests will arrive ๐Ÿ“ฌ. To make matching responses to requests easier, the script can put a request token in the CGI-Request-Token header (it's the CGI CGI-Request-Token header, yes, very iconic ๐Ÿ’€). The server removes this header when the request is proxied. Any responses received for that request will have the token passed in an environment variable ๐Ÿฆ‹.


5. SIP CGI Specification ๐Ÿ‘‘

5.1. Introduction ๐ŸŒธ

5.1.1. Relationship with HTTP CGI

This SIP CGI specification is based on work-in-progress revision 1.1 of the HTTP CGI specification [1]. That document comes from the CGI-WG mailing list, which is not an official IETF working group. The CGI-WG homepage is at http://Web.Golux.Com/coar/cgi/, and the newest versions of the CGI specification are over there. This specification pulls in a great deal of text from the work-in-progress version of that document as of February 23, 2000. A future version of this specification may change to cite parts of that document by reference instead ๐Ÿ“š.

5.1.2. Conventions of This Document

In this document, the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as described in RFC 2119 [4]. They indicate requirement levels for compliant SIP CGI implementations ๐ŸŽฏ.

Some paragraphs are indented, like this. They give motivations for design choices, or questions for future discussion in the development of SIP CGI. They are not normative to the specification of the protocol ๐Ÿฆ‹.

5.1.3. Specifications

Not every function and feature of SIP CGI is defined in the main part of this specification. These phrases describe the features that are not specified ๐Ÿงฉ:

  • System-defined: The feature may differ between systems, but must be the same for different implementations using the same system. A system will usually identify a class of operating systems. Some systems are defined in section 6 of this document. New systems may be defined by new specifications without revision of this document.
  • Implementation-defined: The behavior of the feature may vary from implementation to implementation, but a particular implementation should be consistent in its behavior.

5.1.4. Terminology

This specification uses many terms defined in the SIP/2.0 specification [2]. However, the following terms are used here in a sense that may not match their definitions in that document, or their common meaning ๐Ÿค“:

  • metavariable: A named parameter that carries information from the server to the script. It is not necessarily a variable in the operating system's environment, although that is the most common implementation.
  • script: The software which is invoked by the server via this interface. It need not be a standalone program, but could be a dynamically-loaded or shared library, or even a subroutine in the server. It may be a set of statements interpreted at run-time, as the term script is frequently understood, but that is not a requirement, and within the context of this specification the term has the broader definition stated.
  • server: The application program which invokes the script in order to service messages.
  • message: A SIP request or response, typically either the one that triggered the invocation of the CGI script, or one that the CGI script caused to be sent.

5.2. Notational Conventions and Generic Grammar ๐Ÿ“

In this specification we use the Augmented Backus-Naur Form notation as described in appendix C of the SIP/2.0 specification, RFC 2543 [2].

The following grammatical constructs are taken from other documents. This table lists the appropriate sources ๐Ÿ“‹:

OCTET          SIP/2.0 [2] Appendix C.1
CHAR           SIP/2.0 [2] Appendix C.1
digit          SIP/2.0 [2] Appendix C.1
alphanum       SIP/2.0 [2] Appendix C.1
token          SIP/2.0 [2] Appendix C.1
hostname       SIP/2.0 [2] Section 2
SIP-URL        SIP/2.0 [2] Section 2
SIP-Version    SIP/2.0 [2] Section 4.3.1
Status-Code    SIP/2.0 [2] Section 5.1.1
Reason-Phrase  SIP/2.0 [2] Section 5.1.1
media-type     HTTP/1.1 [5] Section 3.7

               (via SIP/2.0 [2] Section 6.16)
field-name     SIP/2.0 [2] Section 6.6

Other grammatical constructs taken from outside sources are noted in the text ๐Ÿ”.

5.3. Invoking the Script โšก

The script is invoked in a system-defined manner. Unless specified otherwise, the file containing the script will be invoked as an executable program ๐Ÿ’ป.

Only one CGI script at a time may be outstanding for a SIP transaction. If later-arriving responses would cause a CGI script to be invoked, handling them is deferred (except for ACK) until the CGI scripts for previous messages in the transaction terminate. Messages are processed in the order they are received ๐Ÿ“ฌ.

5.4. The SIP CGI Script Command Line ๐Ÿ™…โ€โ™€๏ธ

The server SHOULD NOT provide any command line arguments to the script.

Command line arguments are used for indexed queries in HTTP CGI. HTTP indexed queries don't have an equivalent in SIP, so this is why ๐Ÿ™ˆ.

5.5. Data Input to the SIP CGI Script ๐Ÿซถ

Information about a message comes from two different sources: the message header, and any associated content-body. Servers MUST make portions of this information available to scripts ๐Ÿ’–.

5.5.1. Message Metadata (Metavariables) ๐Ÿต

okay so bestie, this is where the server spills all the tea about the message for the script ๐Ÿ’… Every SIP CGI server MUST come up with some way to pass data about the message from the server to the script. The script reads those metavariables in a system-defined way, and how the characters inside them get represented is up to the system too ๐Ÿซถ

Here's the big one: undefined and null are NOT the same thing ๐Ÿ™ˆ An undefined value just isn't there. A null value is there, but it has zero length. The representation MUST distinguish between the two, and null values are only allowed for metavariables whose grammar permits them.

Historically, HTTP CGI treated null and undefined as the same thing. This spec is like, nope, we're fixing that misfeature, because they are semantically different ๐Ÿ’€

Names are case-insensitive, so you can't have two variables that only differ in capitalization ๐Ÿ˜ญ We write them in capitals with underscores so they're easy to read. The actual name format on your system MAY be defined differently. Metavariable values, though, MUST be treated as case-sensitive unless noted otherwise ๐Ÿ’–

These are the canonical metavariables ๐ŸŽ€

AUTH_TYPE
CONTENT_LENGTH
CONTENT_TYPE
GATEWAY_INTERFACE
REMOTE_ADDR
REMOTE_HOST
REMOTE_IDENT
REMOTE_USER
REGISTRATIONS
REQUEST_METHOD
REQUEST_TOKEN
REQUEST_URI
RESPONSE_STATUS
RESPONSE_REASON
RESPONSE_TOKEN
SCRIPT_COOKIE
SERVER_NAME
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE

Metavariables that start with the protocol name (like SIP_ACCEPT) are canonical too when they describe message header fields. The number and meaning of those fields can change without this spec changing, so see section 5.5.1.5 for the details โœจ

A server MAY also specify extra non-canonical metavariables, if it wants to ๐ŸŒˆ

5.5.1.1. AUTH_TYPE ๐Ÿ”

If the message's target needed access authentication for external access, the server MUST set this variable from the auth-scheme token in the message's Authorization header field. Otherwise it isn't defined ๐Ÿ‘€

AUTH_TYPE    =  "" | auth-scheme
auth-scheme  =  "Basic" | "Digest" | "PGP" | token

The SIP access authentication schemes are described in sections 14 and 15 of the SIP/2.0 specification [2]. The auth-scheme is not case-sensitive ๐Ÿ’…

Servers MUST give this metavariable to scripts if the message's Authorization field was authenticated. For the complex auth schemes, the server SHOULD do the checking itself. If the authentication failed, this metavariable SHOULD NOT be set ๐Ÿ™…โ€โ™€๏ธ

If the message has several credentials with multiple schemes, this variable SHOULD be set to match the authenticated credentials using the strongest scheme the server supports. If credentials are present for several domains, the server SHOULD NOT take any action on credentials from domains outside its own ๐Ÿซถ

If both Authorization and Proxy-Authorization headers are present, the server SHOULD do the authorizations based on whichever header fits the context it's running in. For example, a server that's both a proxy and a registrar would use Authorization headers for REGISTER messages aimed at its local domains, and Proxy-Authorization headers for everything else ๐Ÿ“

5.5.1.2. CONTENT_LENGTH ๐Ÿ“

This metavariable is set to the size of the message-body entity attached to the message, if there is one, in decimal octets. If no data is attached, it isn't defined. The syntax matches the SIP Content-Length header field (section 6.15, SIP/2.0 specification [2]) โœจ

CONTENT_LENGTH  =  "" | 1*digit

Servers MUST give this metavariable to scripts if the message came with a content-body entity, even if the message didn't include a Content-Length header field ๐Ÿงš

5.5.1.3. CONTENT_TYPE ๐ŸŽ€

If the message has a message-body, CONTENT_TYPE is set to the Internet Media Type [6] of the attached entity. That happens if the type came through a Content-type field in the message header, or if the server can work it out even without one. The syntax matches the SIP Content-Type header field ๐Ÿ’–

CONTENT_TYPE  =  "" | media-type

The type, subtype, and parameter attribute names aren't case-sensitive. Parameter values MAY be case-sensitive though ๐ŸŒธ Media types and how SIP uses them are covered in section 6.16 of the SIP/2.0 specification [2], and by reference in section 3.7 of the HTTP/1.1 specification [5].

Since SIP requires the Content-Type header MUST be specified whenever a body is present, servers MUST give this metavariable to scripts if a body was in the original message, unless that "body" is actually an encrypted payload ๐Ÿ”ฅ

5.5.1.4. GATEWAY_INTERFACE ๐Ÿฆ‹

This metavariable is set to the dialect of SIP CGI the server is using to talk to the script. Here's the syntax ๐Ÿ‘‘

GATEWAY_INTERFACE  =  "SIP-CGI" "/" major "." minor
major              =  1*digit
minor              =  1*digit

The major and minor numbers are treated as separate integers, so each one can be more than a single digit. That means SIP-CGI/2.4 is lower than SIP-CGI/2.13, which is lower than SIP-CGI/12.3 ๐Ÿคฏ Leading zeros in either number MUST be ignored by scripts, and servers SHOULD NOT generate them โœจ

This document defines version 1.1 of the SIP CGI interface, which is SIP-CGI/1.1 ๐ŸŒˆ

Servers MUST give this metavariable to scripts ๐Ÿ’œ

For maximum compatibility with existing HTTP CGI libraries, we want this to look as much like CGI 1.1 as possible. We also want it to be obvious that this is SIP CGI, so making HTTP CGI's version identifier a substring of the SIP CGI identifier felt like a reasonable compromise. (The existing CGI libraries we checked don't seem to check the version.)

5.5.1.5. Protocol-Specific Metavariables ๐Ÿ“จ

These metavariables are specific to whichever protocol the method was sent over. How you read them depends on the SERVER_PROTOCOL metavariable (see section 5.5.1.20) ๐ŸŽ€

Metavariables whose names start with SIP_ hold values from the message header when the protocol is SIP. Each SIP header field name gets converted to upper case, has every - swapped for _, and then has SIP_ stuck on the front ๐Ÿ’… Other protocols get similar transformations.

The header data MAY be presented exactly as the client sent it, or MAY be rewritten in ways that don't change its meaning. If several header fields share the same field-name, the server MUST rewrite them as if they had arrived as one header field with the same meaning, before putting them into a metavariable. Likewise, a header field that comes in over more than one line MUST be merged into a single line ๐Ÿซถ If it's needed, the server MUST also change how the data is represented (like the character set) so it fits a CGI metavariable.

Heads up: these metavariable names used to be HTTP_* in early drafts. They got changed to SIP_* because the plan to keep existing CGI libraries working unmodified got outweighed by how confusing the overlap was ๐Ÿ™ˆ

Servers don't have to make metavariables for every header field they get. But headers matter a lot in SIP for what a message means, so servers SHOULD provide every header that doesn't contain sensitive authorization info, like Authorization ๐Ÿ”’ Servers SHOULD also provide protocol-specific metavariables even for stuff that's already available through other SIP CGI metavariables, like CONTENT_LENGTH and CONTENT_TYPE.

This lets a SIP CGI script figure out, if it needs to, whether the info in the other metavariables came from the original message or was made up by the server ๐Ÿ•ต๏ธโ€โ™€๏ธ

5.5.1.6. REGISTRATIONS ๐Ÿ“’

This metavariable holds a list of the current locations the server has registered for the user in the Request-URI of the transaction's initial request. It's syntactically identical to the protocol metavariable SIP_CONTACT, so it's defined by section 5.5.1.5 of this document and section 6.13 of the SIP/2.0 specification [2]. It includes all the URIs, URI parameters, display names, and contact parameters for the addresses registered with the server ๐Ÿ’–

The syntax of REGISTRATIONS matches exactly how SIP_CONTACT would show up in a 302 response from a redirection server, so parsing code can be reused. Efficient and iconic ๐Ÿ‘‘

If a user's registrations change during a transaction, the server SHOULD update this metavariable for any later script invocations in that transaction ๐Ÿฆ‹

5.5.1.7. REMOTE_ADDR ๐ŸŒ

This is the IP address of the client that sent the message to the server. It isn't necessarily the address of the originating user agent client or server ๐Ÿงš

REMOTE_ADDR  =  hostnumber
hostnumber   =  IPv4address | IPv6address

The definitions of IPv4address and IPv6address are in Appendix B of RFC 2373 [7] โœจ

For locally-generated responses (see section 5.8), this SHOULD be the loopback address, meaning 127.0.0.1 for IPv4 or ::1 for IPv6 ๐ŸŒธ

Servers MUST supply this value to scripts ๐Ÿซถ

5.5.1.8. REMOTE_HOST ๐Ÿ 

This is the fully qualified domain name of the host that sent the message to this server, if it's available. Otherwise it isn't defined (see section 5.5.1.7). Domain names aren't case-sensitive ๐Ÿ“

REMOTE_HOST  =  hostname

Servers SHOULD provide this information to scripts ๐Ÿ’œ

5.5.1.9. REMOTE_IDENT ๐Ÿชช

This is the identity information about the connection from an RFC 1413 [8] request, if it's available ๐Ÿ”

REMOTE_IDENT  =  *CHAR

Servers MAY choose not to support this feature ๐Ÿ™ƒ Lots of implementations probably won't bother, since the info isn't all that useful once there are complicated proxy paths.

5.5.1.10. REMOTE_USER ๐Ÿ‘ค

If the message asked for authentication (meaning the AUTH_TYPE metavariable is set), then REMOTE_USER gets set to the user-ID supplied for that authentication. For Basic authentication, that's the content of the (decoded) "userid" grammar element. For Digest, it's the content of "username-value." For PGP authentication, it's the URI in the "signed-by" parameter of the Authorization header if there is one, and otherwise the URI part of the From header ๐Ÿ”

If some other authentication scheme was requested, this metavariable SHOULD be set to an appropriate piece of the authorization info that identifies the user or entity behind the credentials. If authentication wasn't requested, this metavariable isn't defined ๐Ÿ’…

REMOTE_USER  =  *OCTET

Servers SHOULD provide this metavariable to scripts ๐ŸŒˆ

5.5.1.11 REQUEST_METHOD ๐Ÿ’…

okay so if the message that set off the script was a request, REQUEST_METHOD gets set to whatever method that request was made with, as described in section 4.2 of the SIP/2.0 specification [2]. otherwise it's just not defined ๐Ÿ™ˆ

REQUEST_METHOD    =  sip-method
sip-method        =  "INVITE" | "BYE" | "OPTIONS" | "CANCEL"
                     | "REGISTER" | "ACK"
                     | extension-method
extension-method  =  token

ngl ACK is usually not a vibe for the SIP CGI 1.1 environment ๐Ÿ’€ but you can check out section 5.11 if you want the tea. REGISTER's implications in the CGI context are discussed in section 5.9, and CANCEL gets its own moment in section 5.10 โœจ. A SIP CGI 1.1 server MAY choose to process some methods directly rather than passing them to scripts, so it's giving "the server gets a say" energy ๐Ÿ‘‘

Servers MUST provide this metavariable to scripts if the triggering message was a request. no skipping, periodt ๐Ÿซถ

5.5.1.12 REQUEST_TOKEN ๐Ÿฆ‹

REQUEST_TOKEN  =  token

if the script specified a request token in a proxied request, this token gets sent back to the server in responses to that request ๐ŸŒธ the main thing to remember is that the script picks this token, not the server. every response to a proxied request carries the same value for it, so it's super consistent ๐Ÿ’œ

5.5.1.13 REQUEST_URI ๐ŸŒˆ

this metavariable is specific to requests made with SIP ๐Ÿงš

REQUEST_URI  =  absoluteURI  ; defined in RFC 2396 [9]

if the message that triggered the script was a request, this variable shows the URI that was specified with the request method โœจ it's only defined if REQUEST_METHOD is defined, and in that case servers MUST provide it to scripts. no excuses bestie ๐Ÿ’…

This metavariable fills the roles of HTTP CGI's SCRIPT_NAME, PATH_INFO, and QUERY_STRING. it's basically doing three jobs at once, iconic ๐Ÿ™Œ

5.5.1.14 RESPONSE_STATUS ๐ŸŽ€

RESPONSE_STATUS  =  Status-Code

if the message that triggered the script was a response, this variable shows the numeric code in that response. otherwise it's not defined. in the first case, servers MUST provide this metavariable to scripts ๐Ÿ”ฅ

5.5.1.15 RESPONSE_REASON ๐Ÿ“

RESPONSE_REASON  =  Reason-Phrase

if the message that triggered the script was a response, this variable holds the textual string that was in the response ๐Ÿ’–

5.5.1.16 RESPONSE_TOKEN โญ

RESPONSE_TOKEN  =  token

if the message that triggered the script was a response, the server MUST specify a token that later runs of the CGI script can use to identify that response ๐Ÿซถ the server picks this string, and the script can't see inside it, so it's opaque. for the CGI-FORWARD-RESPONSE drama, check out section 5.6.1 below ๐Ÿ‘€

SCRIPT_COOKIE  =  token

this is the value that an earlier run of this script, for this same transaction, passed to the server in the CGI-SET-COOKIE action line ๐Ÿช for what that action actually does, see section 5.6.1.4 below.

5.5.1.18 SERVER_NAME ๐Ÿ 

The SERVER_NAME metavariable is set to the name of the server.

SERVER_NAME  =  hostname | hostnumber

Servers MUST provide this metavariable to scripts. it's a must-have, no cap ๐Ÿ’…

5.5.1.19 SERVER_PORT ๐Ÿšช

The SERVER_PORT metavariable is set to the port the message came in on ๐Ÿฆ‹

SERVER_PORT  =  1*digit

Servers MUST provide this metavariable to scripts. always. forever. ๐Ÿ’–

5.5.1.20 SERVER_PROTOCOL ๐Ÿ“ก

The SERVER_PROTOCOL metavariable is set to the name and revision of the protocol the message arrived with. this is usually going to be "SIP/2.0" ๐Ÿ’œ it's not automatically the same as the protocol version the server uses when it answers the client, so don't mix them up, bestie ๐Ÿ™ˆ

SERVER_PROTOCOL    =  SIP-Version | extension-version
                      | extension-token
extension-version  =  protocol "/" 1*digit "." 1*digit
protocol           =  1*( alphanum | "+" | "-" | "." )
extension-token    =  token

Servers MUST provide this metavariable to scripts. โœจ

5.5.1.21 SERVER_SOFTWARE ๐ŸŒธ

The SERVER_SOFTWARE metavariable is set to the name and version of the information server software that's handling the message (and running the gateway) ๐Ÿงš

SERVER_SOFTWARE  =  1*product
product          =  token [ "/" product-version ]
product-version  =  token

Servers MUST provide this metavariable to scripts. ๐Ÿ‘‘

5.5.2 Message Bodies ๐ŸŽ€

okay so there might be a data entity attached to the message, which means there MUST be a system-defined method for the script to read that data ๐Ÿ“š unless it's defined otherwise, that method is the `standard input' file descriptor ๐Ÿ’…

If the metavariable CONTENT_LENGTH (see section 5.5.1.2) is defined, the server MUST supply at least that many bytes to scripts on the standard input stream ๐ŸŒŠ scripts aren't obligated to read the data. servers MAY signal an EOF condition after CONTENT_LENGTH bytes have been read, but they don't have to ๐Ÿ™ƒ so the big rule is that scripts MUST NOT attempt to read more than CONTENT_LENGTH bytes, even if more data is available. don't be greedy, bestie ๐Ÿซถ

5.6 Data Output from the SIP CGI Script ๐Ÿฆ‹

There MUST be a system-defined method for the script to send data back to the server or client ๐Ÿ“ฎ unless it's defined otherwise, that's the `standard output' file descriptor โœจ

Servers MAY implement a timeout period within which data must be received from scripts, a maximum number of requests or responses that a particular CGI script can initiate, a maximum total number of requests or responses that can be sent by scripts over the lifetime of a transaction, or any other resource limitations they want ๐Ÿ’… if a script goes over one of these limits, the server MAY terminate the script process, and it SHOULD abort the transaction with either a 504 Gateway Timed Out' or a 500 Internal Server Error' response ๐Ÿ˜ญ

A SIP CGI script's output is any number of messages, and each one corresponds to an action the script is asking the server to perform ๐ŸŒˆ each message has an action line, whose syntax depends on the type of action, followed by CGI header fields and SIP header fields. the action lines decide what action happens and are described in section 5.6.1 โœจ CGI header fields pass extra instructions or information to the server and are described in section 5.6.2 ๐Ÿงš

A message MUST contain exactly one action line, MAY also contain any number of CGI header fields and SIP header fields, and MAY contain a SIP body. โœจ

All header fields (both SIP and CGI) in an output message MUST be specified one per line, because SIP CGI 1.1 makes no provision for continuation lines ๐Ÿ™…โ€โ™€๏ธ the generic syntax of CGI header fields is specified in section 5.6.2.

A server MAY choose to honor only some of the requests or responses. in particular, it SHOULD NOT accept any responses that follow a Status message which sends a definitive non-success response ๐Ÿฅฒ

The messages a script sends are delimited like this ๐ŸŽ€

  1. A message begins with an action line.
  2. If the message does not contain a Content-Type header field, or if it contains the header field Content-Length: 0, then it is terminated by a blank line.
  3. If the message contains both Content-Type and Content-Length header fields, the message has a body made up of the Content-Length octets that follow the blank line below the set. the next message begins after the body (and optionally some number of blank lines). if the script closes its output prematurely, the server SHOULD report a 500-class server error ๐Ÿ˜ฑ
  4. If the message contains Content-Type but not Content-Length, the message's body begins with the blank line after the set, and it extends until the script closes its output. in this case, this is necessarily the last message the script can send. the server SHOULD insert a Content-Length header containing the amount of data read before the script closed its output ๐Ÿ’…
  5. If a message contains a non-zero Content-Length but does not contain a Content-Type, it is an error. the server SHOULD report a 500-class server error ๐Ÿ™ˆ

The output of a SIP CGI script is meant to be syntactically identical to a UDP packet in which multiple requests or responses are sent, so the same message parser may be used ๐Ÿงš it's giving efficiency, iykyk ๐ŸŒธ

5.6.1 CGI Action Lines ๐Ÿ’œ

5.6.1.1 Status ๐Ÿฆ‹

Status  =  SIP-Version 3*digit SP reason-phrase NL

this action line makes the server generate a SIP response and relay it upstream toward the client ๐Ÿš€ the server MUST copy the To, From, Call-ID, and CSeq headers from the original request into the response if the script output doesn't specify them. the server SHOULD copy any other headers that would normally be copied into the response from the request, as long as the script output doesn't specify them ๐Ÿซถ

For compatibility with HTTP CGI, a server MAY interpret a message containing a Content-Type header field and no action line as though it contained "SIP/2.0 200 OK". this usage is deprecated, so maybe don't lean on it ๐Ÿฅ€

5.6.1.2 Proxy Request ๐ŸŒˆ

Proxy-Request  =  "CGI-PROXY-REQUEST" SIP-URL SIP-Version

this action line makes the server forward a request to the specified SIP URI ๐Ÿš€ it can be sent either by a script triggered by a request (in which case the triggering request gets forwarded), or by a script triggered by a response on a server that's running statefully (in which case the initial request of the transaction gets sent) ๐Ÿ’–

Any SIP header field MAY be specified below the action line. specified SIP headers replace all of the ones in the original message in their entirety. if a script wants to keep header elements from the original message and also add new ones, it can concatenate them using the usual header concatenation rules and put the result in the script output โœจ new header fields get added to the message after any Via headers but before any other headers ๐Ÿง

Any headers from the original request that the CGI script doesn't generate are copied into the proxied request, after the modifications a proxy server normally makes. in particular, the server MUST append a Via field and decrement Max-Forwards ๐Ÿ”ฅ a server MAY perform additional modifications as it sees fit, such as adding a Record-Route header. a server SHOULD NOT append these headers if they're specified in the script output ๐Ÿ™…โ€โ™€๏ธ

A script MAY specify that a SIP header is to be deleted from the message by using the CGI-Remove CGI header. see section 5.6.2 for that one ๐Ÿ—‘๏ธ

If the message does not specify a body, the body from the initial request is used. a message with Content-Length: 0 is specifying an empty body, which makes the body get deleted from the message ๐Ÿซง

If the original request was authenticated by any means other than `basic,' the script SHOULD NOT add, change, or remove any end-to-end headers, because that would break the authentication ๐Ÿ” this one is serious, bestie ๐Ÿ˜ญ

5.6.1.3 Forward Response ๐ŸŽ€

Forward-Response  =  "CGI-FORWARD-RESPONSE" Response-Name
                      SIP-Version
Response-Name     =  response-token | "this"

this action line makes the server forward a response on to its appropriate final destination ๐Ÿฆ‹ the same rules for accompanying SIP headers and message bodies apply as they do for CGI-PROXY-REQUEST ๐Ÿ’…

The specified response name may either be a response token the server previously submitted in a RESPONSE_TOKEN metavariable, or the string "this." the string "this" may only be sent if the message that triggered this CGI script was a response. it means that this triggering response should be forwarded ๐ŸŒธ

        Script-Cookie  =  "CGI-SET-COOKIE" token SIP-Version

Okay so this action line tells the server to store a script cookie, and the token rides along inside the action line itself ๐ŸŽ€. Every later script run for messages in the same transaction gets that token back in a meta-header ๐Ÿ’–. The script can change the cookie's value with more script cookie actions, and the new value takes effect for all of the script runs after that point โœจ.

5.6.1.5 CGI Again ๐Ÿ”

        CGI-Again  =  "CGI-AGAIN" ("yes" | "no") SIP-Version

This action line decides whether the script gets invoked again for the later requests and responses in this transaction ๐Ÿฆ‹. If the parameter is "yes", the script runs again when the next message shows up. If the parameter is "no", or this action isn't specified at all, the script stops running, and the server does its default action for every message after that ๐Ÿ’….

5.6.1.6 Default Action ๐ŸŒธ

If none of the actions CGI-PROXY-REQUEST or CGI-FORWARD-RESPONSE happen, and no new response gets sent, then the script just outputs CGI-AGAIN, CGI-SET-COOKIE, or nothing at all. That's when the script falls back to its default action. Which default action it is depends on the event that triggered the script:

  • Request received: When the request first comes in, the server's default action is to check whether its own domain matches the domain in the Request-URI. If it doesn't match, the request gets proxied to the request in the Request-URI. If it does match, the server checks its registration database against the request, then either proxies or redirects the request based on the action the user agent asked for in its registration. ๐Ÿ 
  • Proxied response received: When a response comes back for a proxied request, the server forwards it towards the caller if it's a 200 or 600 class response, and sends a CANCEL on all pending branches ๐Ÿš€. If it's a 100 class response, the state machinery for that branch gets updated, and the response is proxied upstream towards the caller, unless it was a 100 response and not some other 1xx. For 300, 400, and 500 class responses, an ACK is sent. The response then gets forwarded upstream towards the caller only if all the other branches have terminated and this response is the best one received so far. If not all branches have terminated, the server does nothing. If all branches have terminated but this response isn't the best, the best one gets forwarded upstream instead. This is the basic algorithm laid out in the SIP specification ๐Ÿ‘‘.

5.6.2 CGI Header Fields ๐ŸŽ€

CGI header fields look a lot like SIP header fields, but their names all start with the string "CGI-" ๐Ÿ’œ. The SIP server MUST strip all CGI header fields from any message before sending it, including the ones it doesn't recognize ๐Ÿ™ˆ.

CGI header fields have the generic syntax from section 6.6 of the SIP/2.0 specification [2] โœจ. The field-name isn't case sensitive, but the field value MUST conform to the grammar of that specific field in the specification where it's defined ๐Ÿ’….

5.6.2.1 Request-Token ๐Ÿงš

        Request-Token  =  "CGI-Request-Token" ":" token

To help match responses back to proxied requests, the script can put a CGI-Request-Token CGI header in a CGI-PROXY-REQUEST or a new request ๐Ÿ”ฅ. This header holds a token that's opaque to the server. When a response to that request shows up, the token gets handed back to the script as a meta-header ๐Ÿซถ.

This lets scripts "fork" a proxy request and figure out which response belongs to which branch of the request. Main character energy ๐Ÿ‘‘.

5.6.2.2 Remove ๐Ÿงน

        Remove  =  "CGI-Remove" ":" 1#field-name

The CGI-Remove header lets the script remove SIP headers from the outgoing request or response ๐Ÿ’–. Its value is a comma-separated list of the SIP headers that should get removed before the message is sent out ๐Ÿ“.

A script MAY specify headers that aren't in the request, and the server SHOULD silently ignore those ๐Ÿฆ‹. A script SHOULD NOT both specify a SIP header in its output and also list that same header in a CGI-Remove header, because the result of doing that is undefined ๐Ÿ’€.

5.7 Local Expiration Handling โฐ

If a CGI script specifies an Expires header field along with CGI-PROXY-REQUEST, the SIP server SHOULD track the expiration timeout locally as well as sending the message to the remote server ๐ŸŒˆ. When the timeout expires, the server SHOULD generate a "408 Request Timeout" response. The timeout response SHOULD be handled as specified in section 5.8. And at the moment the request times out, the server SHOULD also transmit CANCEL messages for the request โœจ.

This is what lets a SIP CGI script in a proxy server run services like "Call Forward No Answer," which triggers after a user-determined time, even if the remote user-agent server isn't responding or doesn't properly handle the Expires header field ๐Ÿ“ž.

5.8 Locally-Generated Responses ๐Ÿ›Ž๏ธ

In a proxy environment, locally-generated responses such as "408 Request Timeout" SHOULD be sent to the CGI script the same way received messages are ๐ŸŒธ. However, messages that just report a problem with a message, such as "400 Bad Request", SHOULD NOT be sent to the script ๐Ÿ™…โ€โ™€๏ธ.

This is the other half of the requirements for the "Call Forward No Answer" service, along with the local handling of the Expires header ๐Ÿซถ.

5.9 SIP CGI and REGISTER ๐Ÿ“

The specific semantics of a SIP CGI script triggered by a REGISTER request are a bit different from those triggered by call-related requests ๐Ÿค”. Still, letting users control their registration can be useful in some cases ๐Ÿ’œ. The two specific actions for REGISTER that need discussing are the "200" response and the default action ๐Ÿ‘‘. In the first case, the server SHOULD assume the CGI script is handling the registration internally, and SHOULD NOT add the registration to its internal registration database. In the second case, the server SHOULD add the registration to its own database. The server also SHOULD NOT add the registration if a 3xx, 4xx, 5xx, or 6xx status was returned, or if the registration request was proxied to another location ๐Ÿ™…โ€โ™€๏ธ.

5.10 SIP CGI and CANCEL ๐Ÿ›‘

SIP CGI servers SHOULD execute scripts when a CANCEL message is received ๐Ÿ””. The script SHOULD clean up any state it has for the transaction as quickly as possible ๐Ÿงผ.

When a CANCEL arrives at a server for an existing transaction, the server SHOULD send a 200 OK response to the cancel and cancel all currently outstanding branches ๐Ÿงฏ. Running the script on a CANCEL message is purely advisory, though, so the script SHOULD NOT perform any actions in response to it ๐Ÿ™ˆ.

5.11 SIP CGI and ACK ๐Ÿค

5.11.1 Receiving ACK's ๐Ÿ“ฌ

Under normal circumstances, if the server receives an ACK, the script doesn't get re-executed ๐Ÿ’…. If the ACK is destined for the proxy (acknowledging a 300, 400, 500, or 600 response), the ACK makes the response retransmissions stop โœ‹. If the ACK is for a 200 response forwarded from a downstream server, the ACK gets proxied downstream โžก๏ธ.

However, if the script generated its own 200 response to an INVITE request, the script SHOULD be re-executed with the ACK message ๐Ÿ”. This is necessary when the script is making the proxy act as a UAS ๐Ÿ–ฅ๏ธ. ACK messages can contain bodies, so they'd be useful to the script ๐Ÿ“ฆ.

5.11.2 Sending ACK's ๐Ÿ“ค

When the server receives a non-200 final response to an INVITE request, it SHOULD generate an ACK on its own, and not depend on the script to do it ๐Ÿค–. There's no way in SIP CGI 1.1 to override this behavior ๐Ÿšซ. However, since the server won't generate an ACK for 200 responses to INVITE, a script that makes the server act as a UAC MUST generate ACK's for them ๐Ÿซถ.

6 System Specifications ๐Ÿ’ป

6.1 Unix ๐Ÿง

The implementation of SIP CGI on a Unix operating system platform SHOULD use environment variables as the mechanism for providing request metadata to CGI scripts ๐ŸŒฟ.

For Unix compatible operating systems, the following are defined:

  • Environment variables: These are accessed by the C library routine getenv. ๐Ÿ”‘
  • The current working directory: The current working directory for the script SHOULD be set to the directory containing the script. ๐Ÿ“
  • Character set: The US-ASCII character set is used for the definition of environment variable names and header field names. The newline (NL) sequence is LF, and servers SHOULD also accept CR LF as a newline. ๐Ÿ”ค

6.2 Microsoft Windows ๐ŸชŸ

The implementation of SIP CGI on 32-bit Microsoft Windows system platforms (Windows 95, 98, NT, and 2000) SHOULD use environment variables as the mechanism for providing request metadata to CGI scripts ๐Ÿ’พ.

For Microsoft Windows, the following are defined:

  • Environment variables: These are accessed by the C library routine getenv. ๐Ÿ”‘
  • The current working directory: The current working directory for the script SHOULD be set to the directory containing the script. ๐Ÿ“
  • Character set: The US-ASCII character set is used for the definition of environment variable names and header field names. The newline (NL) sequence is CR LF, and servers SHOULD also accept LF as a newline. ๐Ÿ”ค

7 Security Considerations ๐Ÿ”

7.1 Request Initiation ๐Ÿšจ

CGI scripts are able to initiate arbitrary SIP transactions, or to produce spoofed responses of any sort ๐Ÿ˜ฑ. This protocol doesn't try to restrict the actions CGI scripts can take. Server administrators MUST consider CGI scripts to be as security-sensitive as their SIP server itself, and perform equivalent levels of security review before installing them ๐Ÿ›ก๏ธ.

7.2 Authenticated and Encrypted Messages ๐Ÿ”

CGI scripts must be careful not to interfere with authentication ๐Ÿ™…โ€โ™€๏ธ. In particular, adding or removing header fields that are below the Authorization header will cause the message to fail authentication at the user agent ๐Ÿ’€.

When a SIP request is encrypted, the headers that are in the clear are passed to the server according to this specification. The encrypted portion of the request is passed to the script as a body ๐Ÿ“ฆ. Any SIP headers output by the script will be added to the message. However, scripts should be aware that these may be discarded if they also exist within the encrypted portion ๐Ÿ‘€.

7.3 SIP Header Fields Containing Sensitive Information ๐Ÿ•ต๏ธโ€โ™€๏ธ

Some SIP header fields may carry sensitive information, and the server SHOULD NOT pass that on to the script unless it's explicitly configured to do so ๐Ÿ”’. For example, if the server protects the script using the Basic authentication scheme, the client will send an Authorization header field containing a username and password. If the server, rather than the script, validates this information, then the password SHOULD NOT be passed on to the script via the HTTP_AUTHORIZATION metavariable ๐Ÿ™ˆ.

7.4 Script Interference with the Server โœจ

okay so the most common way CGI runs a script is as a child process, using the same user and group as the server ๐Ÿ‘€ which means the script SHOULD be locked down so it can't interfere with the server process, its configuration, or the documents ๐Ÿ›ก๏ธ bestie, this one is serious.

If the script runs by calling a function that's linked into the server software (at compile-time or run-time), precautions SHOULD be taken to protect the server's core memory, or to make sure untrusted code can't be executed ๐Ÿ’€ that's the whole vibe here.

7.5 Data Length and Buffering Considerations ๐ŸŽ€

no limits are placed on how long the entity bodies handed to a script can be ๐Ÿ™ˆ so scripts SHOULD NOT assume that statically allocated buffers of any size can hold the entire submission at one time. using a fixed-length buffer without careful overflow checking can let an attacker exploit stack-smashing' or stack-overflow' vulnerabilities in the operating system ๐Ÿ˜ญ scary, but fixable!

scripts are allowed to spool big submissions to disk or other buffering media, but a rapid succession of large submissions can lead to denial of service conditions ๐ŸŒง๏ธ and if the CONTENT_LENGTH of an entity-body is bigger than resource considerations allow, scripts SHOULD respond with `413 Request Entity Too Large.' ๐Ÿซถ

8 Acknowledgements ๐ŸŒธ

this work leans super heavily on the HTTP CGI specification [1] ๐Ÿ’… like, about half the text in the specification section is taken straight from that document. iconic borrowing, honestly.

9 Authors' Addresses ๐Ÿงš

the authors' contact details, exactly as written:

Jonathan Lennox
Dept. of Computer Science
Columbia University
1214 Amsterdam Avenue, MC 0401
New York, NY 10027
USA

EMail: lennox@cs.columbia.edu


Jonathan Rosenberg
dynamicsoft
72 Eagle Rock Ave.
First Floor
East Hanover, NJ 07936

EMail: jdrosen@dynamicsoft.com


Henning Schulzrinne
Dept. of Computer Science
Columbia University
1214 Amsterdam Avenue, MC 0401
New York, NY 10027
USA

EMail: schulzrinne@cs.columbia.edu

10 Bibliography ๐Ÿ“š

  • [1] http://hoohoo.ncsa.uiuc.edu/cgi/interface.html
  • [2] Handley, M, Schulzrinne, H., Schooler, E. and J. Rosenberg, "SIP: Session Initiation Protocol", RFC 2543, March 1999.
  • [3] Crocker, D., "Standard for the Format of ARPA Internet Text Messages", STD 10, RFC 822, August 1982.
  • [4] Bradner, S., "Key words for use in RFCs to indicate requirement levels", BCP 14, RFC 2119, March 1997.
  • [5] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P. and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999.
  • [6] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types", RFC 2046, November 1996.
  • [7] Hinden, R. and S. Deering, "IP Version 6 Addressing Architecture", RFC 2373, July 1998.
  • [8] St. Johns, M., "Identification Protocol", RFC 1413, January 1993.
  • [9] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform Resource Identifiers (URI): Generic Syntax", RFC 2396, August 1998.

the legal bit, kept word for word so nothing gets lost:

Copyright (C) The Internet Society (2001).  All Rights Reserved.

This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works.  However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.

The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.

This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Acknowledgement ๐Ÿ’–

funding for the RFC Editor function is currently provided by the Internet Society ๐ŸŒˆ and that's a wrap, bestie! ๐Ÿ‘‘

๐Ÿ“ฆ where this page comes from