# Add size of empty gif

**URL:** <https://www.ruby-forum.com/t/add-size-of-empty-gif/196919>\
**Category:** NGINX\
**Created:** [March 17, 2009, 8:28pm UTC](https://www.ruby-forum.com/t/add-size-of-empty-gif/196919 "2009-03-17T20:28:37Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kirill\_ASKorinskiy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/e274bd/32.png) [@Kirill\_ASKorinskiy](https://www.ruby-forum.com/u/Kirill_ASKorinskiy)\
**Post date:** [March 17, 2009, 8:28pm UTC](https://www.ruby-forum.com/t/add-size-of-empty-gif/196919/1 "2009-03-17T20:28:37Z")

</div>

From: Kirill A. Korinskiy [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

## `ngx_http_empty_gif_module' is a simplpe module for send 1x1 transparent gif. Since the gif can contain any number of garbages data after the header, I added a directive `empty\_gif\_size’ that sets the size of “size” for gif 1x1 transparent gif.

src/http/modules/ngx\_http\_empty\_gif\_module.c | 162  
+++++++++++++++++++++±—  
1 files changed, 137 insertions(+), 25 deletions(-)

diff --git a/src/http/modules/ngx\_http\_empty\_gif\_module.c  
b/src/http/modules/ngx\_http\_empty\_gif\_module.c  
index  
20e4413c086bc9cce0c54b591edc3b5324cf591b…2abbc19ceb9991be85ebd2236d106c4800ae6508  
100644  
— a/src/http/modules/ngx\_http\_empty\_gif\_module.c  
+++ b/src/http/modules/ngx\_http\_empty\_gif\_module.c  
@@ -8,9 +8,22 @@  
#include \<ngx\_http.h\>

+typedef struct {

- ngx\_str\_t fake;  
+} ngx\_http\_empty\_gif\_loc\_conf\_t;
- 
- 

static char \*ngx\_http\_empty\_gif(ngx\_conf\_t \*cf, ngx\_command\_t \*cmd,  
void \*conf);

+static void \*ngx\_http\_empty\_gif\_create\_local\_conf(ngx\_conf\_t \*cf);  
+static char \*ngx\_http\_empty\_gif\_merge\_local\_conf(ngx\_conf\_t \*cf,

- void \*parent, void \*child);
- 

+static char \*ngx\_http\_empty\_gif\_size(ngx\_conf\_t \*cf,

- ngx\_command\_t \*cmd, void \*conf);
- 
- 

static ngx\_command\_t ngx\_http\_empty\_gif\_commands[] = {

```
 { ngx_string("empty_gif"),

```

@@ -20,6 +33,13 @@ static ngx\_command\_t ngx\_http\_empty\_gif\_commands[] =  
{  
0,  
NULL },

- { ngx\_string(“empty\_gif\_size”),
- 

```
 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,

```

- 

```
 ngx_http_empty_gif_size,

```

- 

```
 NGX_HTTP_LOC_CONF_OFFSET,

```

- 

```
 offsetof(ngx_http_empty_gif_loc_conf_t, fake),

```

- 

```
 NULL },

```

- 

```
 ngx_null_command

```

};

@@ -75,32 +95,32 @@ static u\_char ngx\_empty\_gif[] = {

static ngx\_http\_module\_t ngx\_http\_empty\_gif\_module\_ctx = {

- NULL, /\* preconfiguration \*/
- NULL, /\* postconfiguration \*/

- NULL, /\* preconfiguration \*/
- NULL, /\* postconfiguration \*/

- NULL, /\* create main configuration \*/
- NULL, /\* init main configuration \*/

- NULL, /\* create main configuration  
\*/
- NULL, /\* init main configuration  
\*/

- NULL, /\* create server configuration \*/
- NULL, /\* merge server configuration \*/

- NULL, /\* create server  
configuration \*/
- NULL, /\* merge server  
configuration \*/

- NULL, /\* create location configuration \*/
- NULL /\* merge location configuration \*/

- ngx\_http\_empty\_gif\_create\_local\_conf, /\* create location  
configuration \*/
- ngx\_http\_empty\_gif\_merge\_local\_conf /\* merge location  
configuration \*/  
};

ngx\_module\_t ngx\_http\_empty\_gif\_module = {  
NGX\_MODULE\_V1,

- &ngx\_http\_empty\_gif\_module\_ctx, /\* module context \*/
- ngx\_http\_empty\_gif\_commands, /\* module directives \*/
- NGX\_HTTP\_MODULE, /\* module type \*/
- NULL, /\* init master \*/
- NULL, /\* init module \*/
- NULL, /\* init process \*/
- NULL, /\* init thread \*/
- NULL, /\* exit thread \*/
- NULL, /\* exit process \*/
- NULL, /\* exit master \*/

- &ngx\_http\_empty\_gif\_module\_ctx, /\* module context \*/
- ngx\_http\_empty\_gif\_commands, /\* module directives \*/
- NGX\_HTTP\_MODULE, /\* module type \*/
- NULL, /\* init master \*/
- NULL, /\* init module \*/
- NULL, /\* init process \*/
- NULL, /\* init thread \*/
- NULL, /\* exit thread \*/
- NULL, /\* exit process \*/
- NULL, /\* exit master \*/  
NGX\_MODULE\_V1\_PADDING  
};

@@ -108,9 +128,12 @@ ngx\_module\_t ngx\_http\_empty\_gif\_module = {  
static ngx\_int\_t  
ngx\_http\_empty\_gif\_handler(ngx\_http\_request\_t \*r)  
{

- ngx\_int\_t rc;
- ngx\_buf\_t \*b;
- ngx\_chain\_t out;

- ngx\_int\_t rc;

- ngx\_buf\_t \*b;

- ngx\_chain\_t out[2];

- ngx\_http\_empty\_gif\_loc\_conf\_t \*conf;

- 
- conf = ngx\_http\_get\_module\_loc\_conf(r, ngx\_http\_empty\_gif\_module);

- 

```
   if (conf->fake.len) {

```

- 

```
       r->headers_out.content_length_n += conf->fake.len;

```

- 

```
   }
   r->headers_out.last_modified_time = 23349600;

   r->headers_out.etag_size = 40;

```

@@ -144,18 +170,36 @@ ngx\_http\_empty\_gif\_handler(ngx\_http\_request\_t \*r)  
return NGX\_HTTP\_INTERNAL\_SERVER\_ERROR;  
}

- out.buf = b;
- out.next = NULL;

- out[0].buf = b;

- out[0].next = NULL;

- b-\>last\_buf = 1;

- if (conf-\>fake.len) {
- 

```
   out[0].next = &out[1];

```

- 

```
   r->headers_out.content_length_n += conf->fake.len;

```

- 
- 

```
   b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));

```

- 

```
   if (b == NULL) {

```

- 

```
       return NGX_HTTP_INTERNAL_SERVER_ERROR;

```

- 

```
   }

```

- 
- 

```
   out[1].next = NULL;

```

- 

```
   out[1].buf = b;

```

- 
- 

```
   b->pos = conf->fake.data;

```

- 

```
   b->last = conf->fake.data + conf->fake.len;

```

- 

```
   b->memory = 1;

```

- }
- 
- b-\>last\_buf = 1;
- r-\>headers\_out.etag\_size = 40;  
r-\>headers\_out.etag\_time = 5;  
r-\>headers\_out.etag\_uniq = 6535;  
@@ -166,7 +210,7 @@ ngx\_http\_empty\_gif\_handler(ngx\_http\_request\_t \*r)  
return rc;  
}

- return ngx\_http\_output\_filter(r, &out);

- return ngx\_http\_output\_filter(r, &out[0]);  
}

@@ -180,3 +224,71 @@ ngx\_http\_empty\_gif(ngx\_conf\_t \*cf, ngx\_command\_t  
\*cmd, void \*conf)

```
 return NGX_CONF_OK;

```

}  
+  
+  
+static void \*  
+ngx\_http\_empty\_gif\_create\_local\_conf(ngx\_conf\_t \*cf)  
+{

- ngx\_http\_empty\_gif\_loc\_conf\_t \*conf;
- 
- conf = ngx\_pcalloc(cf-\>pool,  
sizeof(ngx\_http\_empty\_gif\_loc\_conf\_t));
- if (conf == NULL) {
- 

```
   return NGX_CONF_ERROR;

```

- }
- 
- return conf;  
+}
- 

+static char \*  
+ngx\_http\_empty\_gif\_merge\_local\_conf(ngx\_conf\_t \*cf, void \*parent, void  
\*child)  
+{

- ngx\_http\_empty\_gif\_loc\_conf\_t \*prev = parent;
- ngx\_http\_empty\_gif\_loc\_conf\_t \*conf = child;
- 
- if (prev-\>fake.len) {
- 

```
   conf->fake = prev->fake;

```

- }
- 
- return NGX\_CONF\_OK;  
+}
- 

+static char \*  
+ngx\_http\_empty\_gif\_size(ngx\_conf\_t \*cf, ngx\_command\_t \*cmd, void \*conf)  
+{

- char \*p = conf;
- 
- ngx\_str\_t \*field, \*value;
- ngx\_conf\_post\_t \*post;
- 
- field = (ngx\_str\_t \*) (p + cmd-\>offset);
- 
- if (field-\>data) {
- 

```
   return "is duplicate";

```

- }
- 
- value = cf-\>args-\>elts;
- 
- field-\>len = ngx\_parse\_size(&value[1]);
- 
- if (field-\>len == (size\_t) NGX\_ERROR) {
- 

```
   return "invalid value";

```

- }
- 
- if (field-\>len \< sizeof(ngx\_empty\_gif)) {
- 

```
   return "is shortly";

```

- }
- 
- field-\>len -= sizeof(ngx\_empty\_gif);
- 
- field-\>data = ngx\_pcalloc(cf-\>pool, field-\>len);
- if (field-\>data == NULL) {
- 

```
   return NGX_CONF_ERROR;

```

- }
- 
- if (cmd-\>post) {
- 

```
   post = cmd->post;

```

- 

```
   return post->post_handler(cf, post, field);

```

- }
- 
- return NGX\_CONF\_OK;  
+}

---

<div class="post-metadata">

**Author:** ![Kirill\_ASKorinskiy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/e274bd/32.png) [@Kirill\_ASKorinskiy](https://www.ruby-forum.com/u/Kirill_ASKorinskiy)\
**Post date:** [March 18, 2009, 12:49am UTC](https://www.ruby-forum.com/t/add-size-of-empty-gif/196919/2 "2009-03-18T00:49:27Z")

</div>

From: Kirill A. Korinskiy [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

## Now for send of very large empty gif did not allocated a lot of memory, because I allocated buffer and used it multiple times. Size of buffer is a first optional argument of `empty\_gif\_size’ directive.

src/http/modules/ngx\_http\_empty\_gif\_module.c | 109  
++++++++++++++++±--------  
1 files changed, 71 insertions(+), 38 deletions(-)

diff --git a/src/http/modules/ngx\_http\_empty\_gif\_module.c  
b/src/http/modules/ngx\_http\_empty\_gif\_module.c  
index  
2abbc19ceb9991be85ebd2236d106c4800ae6508..17b46ac0efb06673232e808ca1d0b44d5994a1a2  
100644  
— a/src/http/modules/ngx\_http\_empty\_gif\_module.c  
+++ b/src/http/modules/ngx\_http\_empty\_gif\_module.c  
@@ -9,7 +9,12 @@

typedef struct {

- ngx\_str\_t fake;

- size\_t size;
- ngx\_str\_t str;  
+} ngx\_http\_empty\_gif\_fake\_t;
- 

+typedef struct {

- ngx\_http\_empty\_gif\_fake\_t fake;  
} ngx\_http\_empty\_gif\_loc\_conf\_t;

@@ -34,7 +39,7 @@ static ngx\_command\_t ngx\_http\_empty\_gif\_commands =  
{  
NULL },

```
 { ngx_string("empty_gif_size"),

```

- 

```
 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,

```

- 

```
 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1|NGX_CONF_TAKE2,
 ngx_http_empty_gif_size,
 NGX_HTTP_LOC_CONF_OFFSET,
 offsetof(ngx_http_empty_gif_loc_conf_t, fake),

```

@@ -129,8 +134,9 @@ static ngx\_int\_t  
ngx\_http\_empty\_gif\_handler(ngx\_http\_request\_t \*r)  
{  
ngx\_int\_t rc;

- ngx\_buf\_t \*b;
- ngx\_chain\_t out[2];

- ngx\_buf\_t \*b = NULL;

- ngx\_uint\_t i, out\_count;

- ngx\_chain\_t \*out;  
ngx\_http\_empty\_gif\_loc\_conf\_t \*conf;

- 

```
   if (conf->fake.len) {

```

- 

```
       r->headers_out.content_length_n += conf->fake.len;

```

- 

```
   if (conf->fake.size) {

```

- 

```
       r->headers_out.content_length_n += conf->fake.size;
   }
   r->headers_out.last_modified_time = 23349600;

```

@@ -165,39 +171,50 @@ ngx\_http\_empty\_gif\_handler(ngx\_http\_request\_t \*r)  
return ngx\_http\_send\_header(r);  
}

- b = ngx\_pcalloc(r-\>pool, sizeof(ngx\_buf\_t));
- if (b == NULL) {
- 

```
   return NGX_HTTP_INTERNAL_SERVER_ERROR;

```

- out\_count = 1;
- if (conf-\>fake.size) {
- 

```
   out_count += conf->fake.size / conf->fake.str.len;

```

- 

```
   if (conf->fake.size % conf->fake.str.len) {

```

- 

```
       out_count++;

```

- 

```
   }

```

}

- out[0].buf = b;
- out[0].next = NULL;
- 
- b-\>pos = ngx\_empty\_gif;
- b-\>last = ngx\_empty\_gif + sizeof(ngx\_empty\_gif);
- b-\>memory = 1;
- 
- r-\>headers\_out.status = NGX\_HTTP\_OK;
- r-\>headers\_out.content\_length\_n = sizeof(ngx\_empty\_gif);
- r-\>headers\_out.last\_modified\_time = 23349600;
- 
- if (conf-\>fake.len) {
- 

```
   out[0].next = &out[1];

```

- 

```
   r->headers_out.content_length_n += conf->fake.len;

```

- out = ngx\_palloc(r-\>pool, sizeof(ngx\_chain\_t) \* out\_count);

- if (out == NULL) {

- 

```
   return NGX_HTTP_INTERNAL_SERVER_ERROR;

```

- }

- for (i = 0; i \< out\_count; i++) {  
b = ngx\_pcalloc(r-\>pool, sizeof(ngx\_buf\_t));  
if (b == NULL) {  
return NGX\_HTTP\_INTERNAL\_SERVER\_ERROR;  
}

- 

```
   out[1].next = NULL;

```

- 

```
   out[1].buf = b;

```

- 

```
   out[i].buf = b;

```

- 
- 

```
   if (0 == i) {

```

- 

```
       out[i].next = NULL;

```

- 

```
       b->pos = b->start = ngx_empty_gif;

```

- 

```
       b->last = b->end = ngx_empty_gif + sizeof(ngx_empty_gif);

```

- 

```
   } else if ((conf->fake.size / conf->fake.str.len) + 1 == i) {

```

- 

```
       out[i-1].next = &out[i];

```

- 

```
       out[i].next = NULL;

```

- 

```
       b->pos = b->start = conf->fake.str.data;

```

- 

```
       b->last = b->end = conf->fake.str.data + conf->fake.size % 

```

conf-\>fake.str.len;

- 

```
   } else {

```

- 

```
       out[i-1].next = &out[i];

```

- 

```
       out[i].next = NULL;

```

- 

```
       b->pos = b->start = conf->fake.str.data;

```

- 

```
       b->last = b->end = conf->fake.str.data + 

```

conf-\>fake.str.len;

- 

```
   }

```

- 

```
   b->pos = conf->fake.data;

```

- 

```
   b->last = conf->fake.data + conf->fake.len;
   b->memory = 1;

```

}

- r-\>headers\_out.status = NGX\_HTTP\_OK;

- r-\>headers\_out.content\_length\_n = sizeof(ngx\_empty\_gif) +  
conf-\>fake.size;

- r-\>headers\_out.last\_modified\_time = 23349600;

- b-\>last\_buf = 1;

- return ngx\_http\_output\_filter(r, &out[0]);

- return ngx\_http\_output\_filter(r, out);  
}

@@ -245,7 +262,7 @@ ngx\_http\_empty\_gif\_merge\_local\_conf(ngx\_conf\_t \*cf,  
void \*parent, void \*child)  
ngx\_http\_empty\_gif\_loc\_conf\_t \*prev = parent;  
ngx\_http\_empty\_gif\_loc\_conf\_t \*conf = child;

- if (prev-\>fake.len) {

- if (prev-\>fake.size) {  
conf-\>fake = prev-\>fake;  
}

@@ -257,31 +274,47 @@ ngx\_http\_empty\_gif\_size(ngx\_conf\_t \*cf,  
ngx\_command\_t \*cmd, void \*conf)  
{  
char \*p = conf;

- ngx\_str\_t \*field, \*value;

- ngx\_str\_t \*value;
- ngx\_int\_t i = 1;  
ngx\_conf\_post\_t \*post;
- ngx\_http\_empty\_gif\_fake\_t \*field;

- field = (ngx\_str\_t \*) (p + cmd-\>offset);

- field = (ngx\_http\_empty\_gif\_fake\_t \*) (p + cmd-\>offset);

- if (field-\>data) {

- if (field-\>str.data) {  
return “is duplicate”;  
}

- field-\>len = ngx\_parse\_size(&value[1]);

- if (cf-\>args-\>nelts == 3) {
- 

```
   field->str.len = ngx_parse_size(&value[i]);

```

- 

```
   if (field->str.len == (size_t) NGX_ERROR) {

```

- 

```
       return "invalid value";

```

- 

```
   }

```

- 

```
   i++;

```

- } else {
- 

```
   field->str.len = 1024;

```

- }
- 
- field-\>size = ngx\_parse\_size(&value[i]);

- if (field-\>len == (size\_t) NGX\_ERROR) {

- if (field-\>size == (size\_t) NGX\_ERROR) {  
return “invalid value”;  
}

- if (field-\>len \< sizeof(ngx\_empty\_gif)) {

- if (field-\>size \< sizeof(ngx\_empty\_gif)) {  
return “is shortly”;  
}

- field-\>len -= sizeof(ngx\_empty\_gif);

- field-\>size -= sizeof(ngx\_empty\_gif);
- 
- if (field-\>str.len \> field-\>size) {
- 

```
   field->str.len = field->size;

```

- }

- field-\>data = ngx\_pcalloc(cf-\>pool, field-\>len);
- if (field-\>data == NULL) {

- field-\>str.data = ngx\_pcalloc(cf-\>pool, field-\>str.len);
- if (field-\>str.data == NULL) {  
return NGX\_CONF\_ERROR;  
}

---

<div class="post-metadata">

**Author:** ![Kirill\_ASKorinskiy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/e274bd/32.png) [@Kirill\_ASKorinskiy](https://www.ruby-forum.com/u/Kirill_ASKorinskiy)\
**Post date:** [March 18, 2009, 12:49am UTC](https://www.ruby-forum.com/t/add-size-of-empty-gif/196919/3 "2009-03-18T00:49:27Z")

</div>

From: Kirill A. Korinskiy [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

* * *

src/http/modules/ngx\_http\_empty\_gif\_module.c | 3 +±  
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/src/http/modules/ngx\_http\_empty\_gif\_module.c  
b/src/http/modules/ngx\_http\_empty\_gif\_module.c  
index  
17b46ac0efb06673232e808ca1d0b44d5994a1a2…e1a5749f44369b092913720ab89f565f8deb3130  
100644  
— a/src/http/modules/ngx\_http\_empty\_gif\_module.c  
+++ b/src/http/modules/ngx\_http\_empty\_gif\_module.c  
@@ -39,7 +39,8 @@ static ngx\_command\_t ngx\_http\_empty\_gif\_commands[] =  
{  
NULL },

```
 { ngx_string("empty_gif_size"),

```

- 

```
 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1|NGX_CONF_TAKE2,

```

- 

NGX\_HTTP\_MAIN\_CONF|NGX\_HTTP\_SRV\_CONF|NGX\_HTTP\_LOC\_CONF|NGX\_HTTP\_LIF\_CONF

- 

```
                   |NGX_CONF_TAKE12,
 ngx_http_empty_gif_size,
 NGX_HTTP_LOC_CONF_OFFSET,
 offsetof(ngx_http_empty_gif_loc_conf_t, fake),

```
