---
title: "STM Lesson 91. LAN. W5500. HTTP Server. Part 3"
url: "https://maker.wiznet.io/teddy/projects/stm-lesson-91-lan-w5500-http-server-part-3/"
markdown_url: "https://maker.wiznet.io/teddy/projects/stm-lesson-91-lan-w5500-http-server-part-3/md"
type: "UCC: User Created Content"
author: "Narod stream"
author_url: "https://narodstream.ru/stm-urok-91-lan-w5500-http-server-chast-3/"
editor: "WIZnet"
editor_url: "https://maker.wiznet.io/"
original_author: "Narod stream"
original_url: "https://narodstream.ru/stm-urok-91-lan-w5500-http-server-chast-3/"
published: "2023-08-02"
language: "en"
likes: 0
views: 457
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# STM Lesson 91. LAN. W5500. HTTP Server. Part 3

> STM Lesson 91. LAN. W5500. HTTP Server. Part 3

Original author: Narod stream (source: https://narodstream.ru/stm-urok-91-lan-w5500-http-server-chast-3/)

## Article

**Part 3**

## **LAN. W5500. HTTP server**

B [**previous part**](https://narodstream.ru/stm-urok-91-lan-w5500-http-server-chast-2/) lesson we wrote the function of initializing the chip, and also began to write the function of receiving and processing network packages.

Since we are writing an HTTP server, let's put all the work with this protocol into a separate module for which we will create files **httpd.h** and **httpd.c** as follows

**httpd.h**

`**#ifndef**``** HTTPD_H_**`

`**#define**``** HTTPD_H_**`

`**//--------------------------------------------------**`

`**#include**````**"stm32f4xx_hal.h"**`

`**#include**````**<string.h>**`

`**#include**````**<stdlib.h>**`

`**#include**````**<stdint.h>**`

`**#include**````**"fatfs.h"**`

`**#include**````**"w5500.h"**`

`**//--------------------------------------------------**`

`**#endif**````**/* HTTPD_H_ */**`

**httpd.c**

`**#include**````**"httpd.h"**`

`**//-----------------------------------------------**`

`**extern**````**UART_HandleTypeDef**``** huart2;**`

`**//-----------------------------------------------**`

`**extern**````**char**``** str1[60];**`

`**//-----------------------------------------------**`

Also connect this library in the file **w5500.h** in **bottom itself** file

`**void**``** w5500_packetReceive(**``**void**``**);**`

`**//--------------------------------------------------**`

`**#include**````**"httpd.h"**`

`**//--------------------------------------------------**`

In file **httpd.h** add a structure for the properties of the HTTP package, as well as macros for document types

`#include``"w5500.h"`

`**//--------------------------------------------------**`

`**typedef**````**struct**````**http_sock_prop**``** {**`

`**volatile**````**uint8_t**````**data_stat**``**;**``**//статус передачи данных**`

`**volatile**````**uint32_t**````**data_size**``**;**``**//размер данных для передачи**`

`**volatile**````**uint16_t**````**last_data_part_size**``**;**``**//размер последней части данных для передачи**`

`**volatile**````**uint16_t**````**cnt_data_part**``**;**``**//общее количество частей данных для передачи**`

`**volatile**````**uint16_t**````**cnt_rem_data_part**``**;**``**//количество оставшихся частей данных для передачи**`

`**volatile**````**uint32_t**````**total_count_bytes**``**;**``**//количество переданных байтов документа**`

`**volatile**````**uint8_t**````**http_doc**``**;**``**//вариант документа для передачи**`

`**volatile**````**uint8_t**````**prt_tp**``**;**``**//вариант документа для передачи**`

`**char**````**fname**``**[20];**``**//имя файла (документа)**`

`**} **``**http_sock_prop_ptr**``**;**`

`**//--------------------------------------------------**`

`**//Варианты документов HTTP**`

`**#define**``** EXISTING_HTML 0**`

`**#define**``** E404_HTML 1**`

`**#define**``** EXISTING_JPG 2**`

`**#define**``** EXISTING_ICO 3**`

`**//--------------------------------------------------**`

In file **httpd.c** add a variable of our structure, as well as connect the structure of the properties of TCP

`extern``char``str1[60];`

`**//-----------------------------------------------**`

`**http_sock_prop_ptr httpsockprop[2];**`

`**extern**````**tcp_prop_ptr**``** tcpprop;**`

In the w5500.c file, also connect the HTTP property structure variable

`tcp_prop_ptr``tcpprop;`

`**extern**``** http_sock_prop_ptr httpsockprop[2];**`

In file **w5500.h** add macro substitutions for data transfer states

`} tcp_prop_ptr;`

`**//--------------------------------------------------**`

`**//Статусы передачи данных**`

`**#define**``** DATA_COMPLETED 0 **``**//передача данных закончена**`

`**#define**``** DATA_ONE 1 **``**//передаём единственный пакет**`

`**#define**``** DATA_FIRST 2 **``**//передаём первый пакет**`

`**#define**``** DATA_MIDDLE 3 **``**//передаём средний пакет**`

`**#define**``** DATA_LAST 4 **``**//передаём последний пакет**`

`**#define**``** DATA_END 5 **``**//закрываем соединение после передачи данных**`

`**//--------------------------------------------------**`

In file **w5500.c** in the function of receiving a package in the body of our condition of the socket, add another condition of the state of data transfer

`if``(GetSocketStatus(tcpprop.cur_sock)==SOCK_ESTABLISHED)`

`{`

`** if**``**(httpsockprop[tcpprop.cur_sock].data_stat == DATA_COMPLETED)**`

`** {**`

`** }**`

`}`

In the body of this condition, we will accept the HTTP request, provided that the data from us is all transferred. And, since the macro of this state matters to us **0**, then we do not need to initialize the state at the start of the program and we will immediately enter the body of this condition.

Above the initialization function, add a new function for determining the size of the accepted data in the TCP package, using a special socket register for this

`**//-----------------------------------------------**`

`**uint16_t**``** GetSizeRX(**``**uint8_t**``** sock_num)**`

`**{**`

`** uint16_t**``** len;**`

`** uint8_t**``** opcode=0;**`

`** opcode = (((sock_num<<2)|BSB_S0)<<3)|OM_FDM1;**`

`** len = (w5500_readReg(opcode,Sn_RX_RSR0)<<8|w5500_readReg(opcode,Sn_RX_RSR1));**`

`** return**``** len;**`

`**}**`

`**//-----------------------------------------------**`

Further in the body of an already new condition, we will find out the size of the accepted data, display it in the terminal program, and if it is zero, then there is no data in the TCP package, then we exit the function

`if``(httpsockprop[tcpprop.cur_sock].data_stat == DATA_COMPLETED)`

`{`

`** //Отобразим размер принятых данных**`

`** len = GetSizeRX(0);**`

`** sprintf(str1,**``**"len_rx_buf:0x%04Xrn"**``**,len);**`

`** HAL_UART_Transmit(&huart2,(uint8_t*)str1,strlen(str1),0x1000);**`

`** //Если пришел пустой пакет, то уходим из функции**`

`** if**``**(!len) **``**return**``**;**`

`}`

We collect the code, send the controller and try to request any page. Although, of course, our server will not answer in any way, but at least we will see that a package of a certain length has arrived

![image30](https://narodstream.ru/wp-content/uploads/2017/09/image30.png)

In the terminal program, we see endlessly incoming data with the size of the data length, that is, until we process the data, we will fall into this condition. and this is independent, whether or not our connection will close

![image31](https://narodstream.ru/wp-content/uploads/2017/09/image31.png)

We also see in WareShark that there was only one request from the client

![image32](https://narodstream.ru/wp-content/uploads/2017/09/image32.png)

And to stop this "endless cycle" is only possible by restarting the controller.

But at least we see that the request has come to us.

Also above the initialization function we write a function that will return the data address in the receiving buffer, also using the corresponding register of socket

`**//-----------------------------------------------**`

`**uint16_t**``** GetReadPointer(**``**uint8_t**``** sock_num)**`

`**{**`

`** uint16_t**``** point;**`

`** uint8_t**``** opcode;**`

`** opcode = (((sock_num<<2)|BSB_S0)<<3)|OM_FDM1;**`

`** point = (w5500_readReg(opcode,Sn_RX_RD0)<<8|w5500_readReg(opcode,Sn_RX_RD1));**`

`** return**``** point;**`

`**}**`

`**//-----------------------------------------------**`

Add a prototype for this function. It will come in handy for us in another module.

Let's also find out the data address in the buffer of their reception in the body of the same conditions as the reading and processing of network packages, also displaying it in the terminal program

`if``(!len) ``return``;`

`**//здесь обмениваемся информацией: на запрос документа от клиента отправляем ему запрошенный документ**`

`**//указатель на начало чтения приёмного буфера**`

`**point = GetReadPointer(tcpprop.**``**cur_sock**``**);**`

`**sprintf(str1,**``**"Sn_RX_RD:0x%04Xrn"**``**,point);**`

`**HAL_UART_Transmit(&huart2,(uint8_t*)str1,strlen(str1),0x1000);**`

We collect the code, send the controller and once again request the document in the browser. And here is the result

![image33](https://narodstream.ru/wp-content/uploads/2017/09/image33.png)

Our address is still zero. Well, it is understandable. This is the very first request and it has not been processed. Therefore, the address will not change until it is.

Add global array for temporary buffer

`extern``char``str1[60];`

`**char**``** tmpbuf[30];**`

In file **w5500.h** add a structure for the transfer buffer

`} tcp_prop_ptr;`

`**//--------------------------------------------------**`

`**typedef**````**struct**````**data_sect**``** {**`

`** volatile**````**uint16_t**````**addr**``**;**`

`** volatile**````**uint8_t**````**opcode**``**;**`

`** uint8_t**````**data**``**[];**`

`**} **``**data_sect_ptr**``**;**`

`**//--------------------------------------------------**`

We will also add macros for TCP protocol options. So far there will be only two — unknown and HTTP

`#define``DATA_END 5 ``//закрываем соединение после передачи данных`

`**//--------------------------------------------------**`

`**//Варианты протоколов TCP**`

`**#define**``** PRT_TCP_UNCNOWN 0**`

`**#define**``** PRT_TCP_HTTP 1**`

`**//--------------------------------------------------**`

Let's go back to the file **w5500.c** and after the register reading function, add a few more read functions

`**//-----------------------------------------------**`

`**void**``** w5500_readBuf(data_sect_ptr *datasect, **``**uint16_t**``** len)**`

`**{**`

`** SS_SELECT();**`

`** HAL_SPI_Transmit(&hspi1, (**``**uint8_t**``***) datasect, 3, 0xFFFFFFFF);**`

`** HAL_SPI_Receive(&hspi1, (**``**uint8_t**``***) datasect, len, 0xFFFFFFFF);**`

`** SS_DESELECT();**`

`**}**`

`**//-----------------------------------------------**`

`**uint8_t**``** w5500_readSockBufByte(**``**uint8_t**``** sock_num, **``**uint16_t**``** point)**`

`**{**`

`** uint8_t**``** opcode, bt;**`

`** opcode = (((sock_num<<2)|BSB_S0_RX)<<3)|OM_FDM1;**`

`** bt = w5500_readReg(opcode, point);**`

`** return**``** bt;**`

`**}**`

`**//-----------------------------------------------**`

`**void**``** w5500_readSockBuf(**``**uint8_t**``** sock_num, **``**uint16_t**``** point, **``**uint8_t**``** *buf, **``**uint16_t**``** len)**`

`**{**`

`** data_sect_ptr *datasect = (**``**void**``***)buf;**`

`** datasect->opcode = (((sock_num<<2)|BSB_S0_RX)<<3)|OM_FDM0;**`

`** datasect->addr = be16toword(point);**`

`** w5500_readBuf(datasect,len);**`

`**}**`

`**//-----------------------------------------------**`

The first of these functions reads from the buffer using the variable length data reading method, the second — reads one byte from a buffer of a particular socket, and the third — several bytes from a particular socket.

On the second function — **w5500_readSockBufByte** — add the prototype in the title file.

Now, in the function of reading and processing network packages, add more code to our condition, which will determine what this is the HTTP request

`HAL_UART_Transmit(&huart2,(uint8_t*)str1,strlen(str1),0x1000);`

`**w5500_readSockBuf(tcpprop.cur_sock, point, (uint8_t*)tmpbuf, 5);**`

`**if**``** (strncmp(tmpbuf,**``**"GET /"**``**, 5) == 0)**`

`**{**`

`** HAL_UART_Transmit(&huart2,(uint8_t*)**``**"HTTPrn"**``**,6,0x1000);**`

`** httpsockprop[tcpprop.cur_sock].prt_tp = PRT_TCP_HTTP;**`

`**}**`

If the lines match, we will display the abbreviation "HTTP" in the terminal program, and also initialize the structure field with a specific protocol.

In file **httpd.c** add the response function to the HTTP request, in which we find the address of the occurrence of the character "**/**"

`extern``tcp_prop_ptr``tcpprop;`

`**//-----------------------------------------------**`

`**void**``** http_request(**``**void**``**)**`

`**{**`

`** uint16_t**``** point;**`

`** uint8_t**``** RXbyte;**`

`** uint16_t**``** i=0;**`

`** char**``** *ss1;**`

`** int**``** ch1=**``**'.'**``**;**`

`** // ищем первый "/" в HTTP заголовке**`

`** point = GetReadPointer(tcpprop.**``**cur_sock**``**);**`

`** i = 0;**`

`** while**``** (RXbyte != (**``**uint8_t**``**)**``**'/'**``**)**`

`** {**`

`** RXbyte = w5500_readSockBufByte(tcpprop.**``**cur_sock**``**,point+i);**`

`** i++;**`

`** }**`

`**}**`

`**//-----------------------------------------------**`

We create a prototype for this function and call it the function of reading the package in our condition in the file **w5500.c**

`httpsockprop[tcpprop.cur_sock].prt_tp = PRT_TCP_HTTP;`

`**http_request();**`

In order not to get confused in the places where the conditions are added, let's leave the bodies of two conditions at once and add two more conditions in advance

`http_request();`

`}`

`}`

`** else**````**if**``**(httpsockprop[tcpprop.cur_sock].data_stat==DATA_MIDDLE)**`

`** {**`

`** if**``**(httpsockprop[tcpprop.cur_sock].prt_tp == PRT_TCP_HTTP)**`

`** {**`

`** }**`

`** }**`

`** else**````**if**``**(httpsockprop[tcpprop.cur_sock].data_stat==DATA_LAST)**`

`** {**`

`** if**``**(httpsockprop[tcpprop.cur_sock].prt_tp == PRT_TCP_HTTP)**`

`** {**`

`** }**`

`** }**`

`}`

`}`

These conditions will be triggered if one of the — transfer statuses is set to transfer the average package and or transfer the last data package. Similarly, we worked with packages in lessons using the HTTP protocol with the enc28j60 module.

In file **httpd.c** connect temporary buffer

`extern``char``str1[60];`

`**extern**````**char**``** tmpbuf[30];**`

We continue to write the response function to the HTTP request.

We consider the following character after a slash and, if there is a space — then this is a query of the main page. Set the corresponding type of document in the structure field

`i++;`

`}`

`**point+=i;**`

`**RXbyte = w5500_readSockBufByte(tcpprop.**``**cur_sock**``**,point);**`

`**if**``**(RXbyte==(uint8_t)**``**' '**``**)**`

`**{**`

`** strcpy(httpsockprop[tcpprop.cur_sock].fname,**``**"index.htm"**``**);**`

`** httpsockprop[tcpprop.cur_sock].http_doc = EXISTING_HTML;**`

`**}**`

`**else**`

`**{**`

`**}**`

We will write a body of conditions working otherwise

`else`

`{`

`** // ищем следующий пробел (" ") в HTTP заголовке, таким образом считывая имя документа из запроса**`

`** i=0;**`

`** while**``** (1)**`

`** {**`

`** tmpbuf[i] = w5500_readSockBufByte(tcpprop.cur_sock, point+i);**`

`** if**``**(tmpbuf[i] == (uint8_t)**``**' '**``**) **``**break**``**;**`

`** i++;**`

`** }**`

`** tmpbuf[i] = 0; **``**//закончим строку**`

`** strcpy(httpsockprop[tcpprop.cur_sock].fname,tmpbuf);**`

`}`

In this body we will get all the bytes until the next space. This will be the name of the document.

We continue the function further. Display the file name that the client requested in the terminal program

`strcpy(httpsockprop[tcpprop.cur_sock].fname,tmpbuf);`

`}`

`**HAL_UART_Transmit(&huart2,(uint8_t*)httpsockprop[tcpprop.cur_sock].fname,strlen(httpsockprop[tcpprop.cur_sock].fname),0x1000);**`

`**HAL_UART_Transmit(&huart2,(uint8_t*)**``**"rn"**``**,2,0x1000);**`

We collect the code, sew the controller and try to request first the main page, and then some other, then we'll see the result in the terminal

![image34](https://narodstream.ru/wp-content/uploads/2017/09/image34.png) ![image35](https://narodstream.ru/wp-content/uploads/2017/09/image35.png)

Everything is read normally.

Now in the file **main.c** add some global variables to work with the file system, and connect the string array

`/* Private variables ---------------------------------------------------------*/`

`**extern**````**char**``** SDPath[4]; **``**/* logical drive path */**`

`**FATFS**``** SDFatFs;**``**//указатель на объект**`

`**extern**````**char**``** str1[60];**`

`/* USER CODE END PV */`

In function **main ( )** also add a local variable for the result

`/* USER CODE BEGIN 1 */`

`**FRESULT**``** result; **``**//результат выполнения**`

`/* USER CODE END 1 */`

In the same function, mount our media on the SD map and display the result in the terminal program

`/* USER CODE BEGIN 2 */`

`**result=f_mount(&SDFatFs,(**``**TCHAR**````**const**``***)SDPath,0);**`

`**sprintf(str1,**``**"f_mount: %drn"**``**,result);**`

`**HAL_UART_Transmit(&huart2,(uint8_t*)str1,strlen(str1),0x1000);**`

`net_ini();`

We collect the code, sew the controller and see the result in the terminal

![image36](https://narodstream.ru/wp-content/uploads/2017/09/image36.png)

Everything was finely mounted.

Let's go back to the file **httpd.c** and add the necessary global variables for working with the file system

`extern``tcp_prop_ptr``tcpprop;`

`**FIL**``** MyFile;**`

`**FRESULT**``** result; **``**//результат выполнения**`

`**uint32_t**``** bytesread;**`

`//-----------------------------------------------`

Continue our HTTP request response feature.

We open the required file from the card and find out its size. We will also show this in the terminal program

`HAL_UART_Transmit(&huart2,(uint8_t*)``"rn"``,2,0x1000);`

`**f_close(&MyFile);**`

`**result=f_open(&MyFile,httpsockprop[tcpprop.**``**cur_sock**``**].fname,FA_READ); **``**//Попытка открыть файл**`

`**sprintf(str1,**``**"f_open: %drn"**``**,result);**`

`**HAL_UART_Transmit(&huart2,(uint8_t*)str1,strlen(str1),0x1000);**`

`**sprintf(str1,**``**"f_size: %lurn"**``**,MyFile.fsize);**`

`**HAL_UART_Transmit(&huart2,(uint8_t*)str1,strlen(str1),0x1000);**`

Before opening the file, we close the previous one. You can do this in other places, but it works best for me.

We’ll collect the project again, we’ll send a controller and try to request some existing document

![image37](https://narodstream.ru/wp-content/uploads/2017/09/image37.png)

The size is determined normally.

I created several html pages of various sizes to test our project with the request of documents consisting of different numbers of packages.

Add a few types of HTTP headers for response in the form of global arrays, as well as an array with a page transmitted in case of absence of the requested document

`uint32_t``bytesread;`

`//-----------------------------------------------`

`**const**````**char**``** http_header[] = { **``**"HTTP/1.1 200 OKrnContent-Type: text/htmlrnrn"**``**};**`

`**const**````**char**``** jpg_header[] = {**``**"HTTP/1.0 200 OKrnServer: nginxrnContent-Type: image/jpegrnConnection: closernrn"**``**};**`

`**const**````**char**``** icon_header[] = { **``**"HTTP/1.1 200 OKrnContent-Type: image/x-iconrnrn"**``**};**`

`**const**````**char**``** error_header[] = {**``**"HTTP/1.0 404 File not foundrnServer: nginxrnContent-Type: text/htmlrnConnection: closernrn"**``**};**`

`**char**``** *header;**`

`**//-----------------------------------------------**`

`**const**````**uint8_t**``** e404_htm[] = {**`

`**0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0a,0x20,0x20,0x3c,0x68,0x65,0x61,0x64,0x3e,0x0a,**`

`**0x20,0x20,0x20,0x20,0x3c,0x74,0x69,0x74,0x6c,0x65,0x3e,0x34,0x30,0x34,0x20,0x4e,**`

`**0x6f,0x74,0x20,0x46,0x6f,0x75,0x6e,0x64,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,**`

`**0x0a,0x20,0x20,0x3c,0x2f,0x68,0x65,0x61,0x64,0x3e,0x0a,0x3c,0x62,0x6f,0x64,0x79,**`

`**0x3e,0x0a,0x3c,0x68,0x31,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x74,0x65,0x78,**`

`**0x74,0x2d,0x61,0x6c,0x69,0x67,0x6e,0x3a,0x20,0x63,0x65,0x6e,0x74,0x65,0x72,0x3b,**`

`**0x22,0x3e,0x34,0x30,0x34,0x20,0x45,0x72,0x72,0x6f,0x72,0x20,0x46,0x69,0x6c,0x65,**`

`**0x20,0x4e,0x6f,0x74,0x20,0x46,0x6f,0x75,0x6e,0x64,0x3c,0x2f,0x68,0x31,0x3e,0x0a,**`

`**0x3c,0x68,0x32,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x74,0x65,0x78,0x74,0x2d,**`

`**0x61,0x6c,0x69,0x67,0x6e,0x3a,0x20,0x63,0x65,0x6e,0x74,0x65,0x72,0x3b,0x22,0x3e,**`

`**0x20,0x54,0x68,0x65,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,0x20,0x61,0x72,**`

`**0x65,0x20,0x6c,0x6f,0x6f,0x6b,0x69,0x6e,0x67,0x20,0x66,0x6f,0x72,0x20,0x6d,0x69,**`

`**0x67,0x68,0x74,0x20,0x68,0x61,0x76,0x65,0x20,0x62,0x65,0x65,0x6e,0x20,0x72,0x65,**`

`**0x6d,0x6f,0x76,0x65,0x64,0x2c,0x20,0x3c,0x62,0x72,0x20,0x2f,0x3e,0x68,0x61,0x64,**`

`**0x20,0x69,0x74,0x73,0x20,0x6e,0x61,0x6d,0x65,0x20,0x63,0x68,0x61,0x6e,0x67,0x65,**`

`**0x64,0x2c,0x20,0x6f,0x72,0x20,0x69,0x73,0x20,0x74,0x65,0x6d,0x70,0x6f,0x72,0x61,**`

`**0x72,0x69,0x6c,0x79,0x20,0x75,0x6e,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,**`

`**0x2e,0x3c,0x2f,0x68,0x32,0x3e,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x3c,0x2f,**`

`**0x68,0x74,0x6d,0x6c,0x3e};**`

`**//-----------------------------------------------**`

We continue to write our response function to the HTTP request. If the document has opened, then we will study its extension and set the necessary status, and if not, we will establish the status of the error of the existence of the document on the server. We also calculate in advance the length of the HTTP response in order to determine later what many packages and windows it will fit

`HAL_UART_Transmit(&huart2,(uint8_t*)str1,strlen(str1),0x1000);`

`**if**``** (result==FR_OK)**`

`**{**`

`** //изучим расширение файла**`

`** ss1 = strchr(httpsockprop[tcpprop.cur_sock].fname,ch1);**`

`** ss1++;**`

`** if**``** (strncmp(ss1,**``**"jpg"**``**, 3) == 0)**`

`** {**`

`** httpsockprop[tcpprop.cur_sock].http_doc = EXISTING_JPG;**`

`** //сначала включаем в размер размер заголовка**`

`** httpsockprop[tcpprop.cur_sock].data_size = strlen(jpg_header);**`

`** }**`

`** if**``** (strncmp(ss1,**``**"ico"**``**, 3) == 0)**`

`** {**`

`** httpsockprop[tcpprop.cur_sock].http_doc = EXISTING_ICO;**`

`** //сначала включаем в размер размер заголовка**`

`** httpsockprop[tcpprop.cur_sock].data_size = strlen(icon_header);**`

`** }**`

`** else**`

`** {**`

`** httpsockprop[tcpprop.cur_sock].http_doc = EXISTING_HTML;**`

`** //сначала включаем в размер размер заголовка**`

`** httpsockprop[tcpprop.cur_sock].data_size = strlen(http_header);**`

`** }**`

`** //затем размер самого документа**`

`** httpsockprop[tcpprop.cur_sock].data_size += MyFile.fsize;**`

`**}**`

`**else**`

`**{**`

`** httpsockprop[tcpprop.cur_sock].http_doc = E404_HTML;**`

`** //сначала включаем в размер размер заголовка**`

`** httpsockprop[tcpprop.cur_sock].data_size = strlen(error_header);**`

`** //затем размер самого документа**`

`** httpsockprop[tcpprop.cur_sock].data_size += **``**sizeof**``**(e404_htm);**`

`**}**`

B [**next part**](https://narodstream.ru/stm-urok-91-lan-w5500-http-server-chast-4/) lesson we will continue the response function to the HTTP request, as well as write the function of transferring to the client a document that fits with the heading in one window.

[Embedded media](https://www.youtube.com/embed/EOCH3_CcVN8)

---

Source: https://maker.wiznet.io/teddy/projects/stm-lesson-91-lan-w5500-http-server-part-3/
